From 4da8aac36e66e5d13655ddaa276b8cfb83b38b9a Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Mon, 2 Nov 2015 23:17:51 -0500 Subject: [PATCH] Add vendored files --- .gitignore | 2 +- composer.json | 8 +- vendor/autoload.php | 7 + vendor/bin/phpunit | 1 + vendor/composer/ClassLoader.php | 413 + vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 454 + vendor/composer/autoload_files.php | 15 + vendor/composer/autoload_namespaces.php | 17 + vendor/composer/autoload_psr4.php | 53 + vendor/composer/autoload_real.php | 55 + vendor/composer/installed.json | 3530 ++++ vendor/danielstjules/stringy/.gitignore | 3 + vendor/danielstjules/stringy/.travis.yml | 7 + vendor/danielstjules/stringy/CHANGELOG.md | 119 + vendor/danielstjules/stringy/LICENSE.txt | 19 + vendor/danielstjules/stringy/README.md | 1190 ++ vendor/danielstjules/stringy/composer.json | 35 + vendor/danielstjules/stringy/phpunit.xml.dist | 14 + vendor/danielstjules/stringy/src/Create.php | 19 + .../stringy/src/StaticStringy.php | 979 + vendor/danielstjules/stringy/src/Stringy.php | 1558 ++ .../stringy/tests/CommonTest.php | 1130 ++ .../stringy/tests/CreateTest.php | 16 + .../stringy/tests/StaticStringyTest.php | 710 + .../stringy/tests/StringyTest.php | 994 + vendor/doctrine/inflector/.gitignore | 4 + vendor/doctrine/inflector/.travis.yml | 11 + vendor/doctrine/inflector/LICENSE | 19 + vendor/doctrine/inflector/README.md | 6 + vendor/doctrine/inflector/composer.json | 29 + .../Doctrine/Common/Inflector/Inflector.php | 415 + vendor/doctrine/inflector/phpunit.xml.dist | 31 + .../Tests/Common/Inflector/InflectorTest.php | 210 + .../tests/Doctrine/Tests/DoctrineTestCase.php | 10 + .../tests/Doctrine/Tests/TestInit.php | 27 + vendor/doctrine/instantiator/.gitignore | 5 + vendor/doctrine/instantiator/.scrutinizer.yml | 46 + .../doctrine/instantiator/.travis.install.sh | 14 + vendor/doctrine/instantiator/.travis.yml | 22 + vendor/doctrine/instantiator/CONTRIBUTING.md | 35 + vendor/doctrine/instantiator/LICENSE | 19 + vendor/doctrine/instantiator/README.md | 40 + vendor/doctrine/instantiator/composer.json | 45 + vendor/doctrine/instantiator/phpmd.xml.dist | 27 + vendor/doctrine/instantiator/phpunit.xml.dist | 22 + .../Exception/ExceptionInterface.php | 29 + .../Exception/InvalidArgumentException.php | 62 + .../Exception/UnexpectedValueException.php | 79 + .../Doctrine/Instantiator/Instantiator.php | 273 + .../Instantiator/InstantiatorInterface.php | 37 + .../InstantiatorPerformanceEvent.php | 96 + .../InvalidArgumentExceptionTest.php | 83 + .../UnexpectedValueExceptionTest.php | 69 + .../InstantiatorTest/InstantiatorTest.php | 219 + .../AbstractClassAsset.php | 29 + .../ArrayObjectAsset.php | 41 + .../InstantiatorTestAsset/ExceptionAsset.php | 41 + .../FinalExceptionAsset.php | 41 + .../InstantiatorTestAsset/PharAsset.php | 41 + .../PharExceptionAsset.php | 44 + .../SerializableArrayObjectAsset.php | 62 + .../SimpleSerializableAsset.php | 61 + .../SimpleTraitAsset.php | 29 + .../UnCloneableAsset.php | 50 + .../UnserializeExceptionArrayObjectAsset.php | 39 + .../WakeUpNoticesAsset.php | 38 + .../InstantiatorTestAsset/XMLReaderAsset.php | 41 + vendor/fzaninotto/faker/.gitignore | 2 + vendor/fzaninotto/faker/.travis.yml | 17 + vendor/fzaninotto/faker/CHANGELOG.md | 295 + vendor/fzaninotto/faker/CONTRIBUTING.md | 21 + vendor/fzaninotto/faker/LICENSE | 22 + vendor/fzaninotto/faker/Makefile | 10 + vendor/fzaninotto/faker/composer.json | 37 + vendor/fzaninotto/faker/phpunit.xml.dist | 9 + vendor/fzaninotto/faker/readme.md | 1048 ++ .../faker/src/Faker/Calculator/Luhn.php | 55 + .../faker/src/Faker/DefaultGenerator.php | 27 + .../fzaninotto/faker/src/Faker/Documentor.php | 60 + vendor/fzaninotto/faker/src/Faker/Factory.php | 46 + .../fzaninotto/faker/src/Faker/Generator.php | 239 + .../faker/src/Faker/Guesser/Name.php | 92 + .../Faker/ORM/CakePHP/ColumnTypeGuesser.php | 64 + .../src/Faker/ORM/CakePHP/EntityPopulator.php | 149 + .../faker/src/Faker/ORM/CakePHP/Populator.php | 84 + .../Faker/ORM/Doctrine/ColumnTypeGuesser.php | 68 + .../Faker/ORM/Doctrine/EntityPopulator.php | 193 + .../src/Faker/ORM/Doctrine/Populator.php | 78 + .../Faker/ORM/Mandango/ColumnTypeGuesser.php | 43 + .../Faker/ORM/Mandango/EntityPopulator.php | 110 + .../src/Faker/ORM/Mandango/Populator.php | 61 + .../Faker/ORM/Propel/ColumnTypeGuesser.php | 99 + .../src/Faker/ORM/Propel/EntityPopulator.php | 170 + .../faker/src/Faker/ORM/Propel/Populator.php | 86 + .../faker/src/Faker/Provider/Address.php | 123 + .../faker/src/Faker/Provider/Barcode.php | 110 + .../faker/src/Faker/Provider/Base.php | 509 + .../faker/src/Faker/Provider/Biased.php | 64 + .../faker/src/Faker/Provider/Color.php | 108 + .../faker/src/Faker/Provider/Company.php | 30 + .../faker/src/Faker/Provider/DateTime.php | 240 + .../faker/src/Faker/Provider/File.php | 606 + .../faker/src/Faker/Provider/Image.php | 88 + .../faker/src/Faker/Provider/Internet.php | 335 + .../faker/src/Faker/Provider/Lorem.php | 215 + .../src/Faker/Provider/Miscellaneous.php | 258 + .../faker/src/Faker/Provider/Payment.php | 298 + .../faker/src/Faker/Provider/Person.php | 126 + .../faker/src/Faker/Provider/PhoneNumber.php | 16 + .../faker/src/Faker/Provider/Text.php | 137 + .../faker/src/Faker/Provider/UserAgent.php | 162 + .../faker/src/Faker/Provider/Uuid.php | 57 + .../src/Faker/Provider/ar_JO/Address.php | 152 + .../src/Faker/Provider/ar_JO/Company.php | 63 + .../src/Faker/Provider/ar_JO/Internet.php | 55 + .../faker/src/Faker/Provider/ar_JO/Person.php | 108 + .../faker/src/Faker/Provider/ar_JO/Text.php | 323 + .../src/Faker/Provider/at_AT/Payment.php | 31 + .../src/Faker/Provider/be_BE/Payment.php | 31 + .../src/Faker/Provider/bg_BG/Internet.php | 9 + .../src/Faker/Provider/bg_BG/Payment.php | 43 + .../faker/src/Faker/Provider/bg_BG/Person.php | 114 + .../src/Faker/Provider/bg_BG/PhoneNumber.php | 20 + .../src/Faker/Provider/bn_BD/Address.php | 58 + .../src/Faker/Provider/bn_BD/Company.php | 28 + .../faker/src/Faker/Provider/bn_BD/Person.php | 36 + .../src/Faker/Provider/bn_BD/PhoneNumber.php | 14 + .../faker/src/Faker/Provider/bn_BD/Utils.php | 14 + .../src/Faker/Provider/cs_CZ/Address.php | 149 + .../src/Faker/Provider/cs_CZ/Company.php | 120 + .../src/Faker/Provider/cs_CZ/DateTime.php | 61 + .../src/Faker/Provider/cs_CZ/Internet.php | 9 + .../src/Faker/Provider/cs_CZ/Payment.php | 19 + .../faker/src/Faker/Provider/cs_CZ/Person.php | 473 + .../src/Faker/Provider/cs_CZ/PhoneNumber.php | 14 + .../faker/src/Faker/Provider/cs_CZ/Text.php | 7185 +++++++ .../src/Faker/Provider/da_DK/Address.php | 287 + .../src/Faker/Provider/da_DK/Company.php | 70 + .../src/Faker/Provider/da_DK/Internet.php | 30 + .../src/Faker/Provider/da_DK/Payment.php | 19 + .../faker/src/Faker/Provider/da_DK/Person.php | 195 + .../src/Faker/Provider/da_DK/PhoneNumber.php | 21 + .../src/Faker/Provider/de_AT/Address.php | 99 + .../src/Faker/Provider/de_AT/Company.php | 13 + .../src/Faker/Provider/de_AT/Internet.php | 9 + .../src/Faker/Provider/de_AT/Payment.php | 19 + .../faker/src/Faker/Provider/de_AT/Person.php | 116 + .../src/Faker/Provider/de_AT/PhoneNumber.php | 19 + .../src/Faker/Provider/de_DE/Address.php | 90 + .../src/Faker/Provider/de_DE/Company.php | 15 + .../src/Faker/Provider/de_DE/Internet.php | 9 + .../src/Faker/Provider/de_DE/Payment.php | 19 + .../faker/src/Faker/Provider/de_DE/Person.php | 124 + .../src/Faker/Provider/de_DE/PhoneNumber.php | 20 + .../faker/src/Faker/Provider/de_DE/Text.php | 2036 ++ .../src/Faker/Provider/el_GR/Address.php | 61 + .../src/Faker/Provider/el_GR/Payment.php | 19 + .../faker/src/Faker/Provider/el_GR/Person.php | 178 + .../src/Faker/Provider/el_GR/PhoneNumber.php | 19 + .../src/Faker/Provider/en_AU/Address.php | 57 + .../src/Faker/Provider/en_AU/Internet.php | 9 + .../src/Faker/Provider/en_AU/PhoneNumber.php | 63 + .../src/Faker/Provider/en_CA/Address.php | 64 + .../src/Faker/Provider/en_CA/PhoneNumber.php | 18 + .../src/Faker/Provider/en_GB/Address.php | 89 + .../src/Faker/Provider/en_GB/Internet.php | 9 + .../src/Faker/Provider/en_GB/Payment.php | 19 + .../faker/src/Faker/Provider/en_GB/Person.php | 93 + .../src/Faker/Provider/en_GB/PhoneNumber.php | 39 + .../src/Faker/Provider/en_NZ/Address.php | 84 + .../src/Faker/Provider/en_NZ/Internet.php | 14 + .../src/Faker/Provider/en_NZ/PhoneNumber.php | 106 + .../src/Faker/Provider/en_PH/Address.php | 421 + .../src/Faker/Provider/en_UG/Address.php | 129 + .../src/Faker/Provider/en_UG/Internet.php | 9 + .../faker/src/Faker/Provider/en_UG/Person.php | 132 + .../src/Faker/Provider/en_UG/PhoneNumber.php | 17 + .../src/Faker/Provider/en_US/Address.php | 97 + .../src/Faker/Provider/en_US/Company.php | 64 + .../faker/src/Faker/Provider/en_US/Person.php | 119 + .../src/Faker/Provider/en_US/PhoneNumber.php | 33 + .../faker/src/Faker/Provider/en_US/Text.php | 3720 ++++ .../src/Faker/Provider/en_ZA/Address.php | 97 + .../src/Faker/Provider/en_ZA/Internet.php | 9 + .../faker/src/Faker/Provider/en_ZA/Person.php | 126 + .../src/Faker/Provider/en_ZA/PhoneNumber.php | 17 + .../src/Faker/Provider/es_AR/Address.php | 95 + .../src/Faker/Provider/es_AR/Company.php | 66 + .../faker/src/Faker/Provider/es_AR/Person.php | 90 + .../src/Faker/Provider/es_AR/PhoneNumber.php | 42 + .../src/Faker/Provider/es_ES/Address.php | 101 + .../src/Faker/Provider/es_ES/Company.php | 80 + .../src/Faker/Provider/es_ES/Internet.php | 9 + .../src/Faker/Provider/es_ES/Payment.php | 19 + .../faker/src/Faker/Provider/es_ES/Person.php | 71 + .../src/Faker/Provider/es_ES/PhoneNumber.php | 29 + .../src/Faker/Provider/es_PE/Address.php | 91 + .../src/Faker/Provider/es_PE/Company.php | 66 + .../faker/src/Faker/Provider/es_PE/Person.php | 90 + .../src/Faker/Provider/es_PE/PhoneNumber.php | 17 + .../src/Faker/Provider/es_VE/Address.php | 97 + .../src/Faker/Provider/es_VE/Company.php | 30 + .../src/Faker/Provider/es_VE/Internet.php | 9 + .../faker/src/Faker/Provider/es_VE/Person.php | 157 + .../src/Faker/Provider/es_VE/PhoneNumber.php | 29 + .../src/Faker/Provider/fa_IR/Internet.php | 99 + .../faker/src/Faker/Provider/fa_IR/Person.php | 137 + .../faker/src/Faker/Provider/fa_IR/Text.php | 546 + .../src/Faker/Provider/fi_FI/Address.php | 85 + .../src/Faker/Provider/fi_FI/Company.php | 64 + .../src/Faker/Provider/fi_FI/Internet.php | 9 + .../faker/src/Faker/Provider/fi_FI/Person.php | 88 + .../src/Faker/Provider/fi_FI/PhoneNumber.php | 20 + .../src/Faker/Provider/fr_BE/Address.php | 91 + .../src/Faker/Provider/fr_BE/Company.php | 13 + .../src/Faker/Provider/fr_BE/Internet.php | 9 + .../src/Faker/Provider/fr_BE/Payment.php | 19 + .../faker/src/Faker/Provider/fr_BE/Person.php | 49 + .../src/Faker/Provider/fr_BE/PhoneNumber.php | 20 + .../src/Faker/Provider/fr_CA/Address.php | 156 + .../faker/src/Faker/Provider/fr_CA/Person.php | 82 + .../src/Faker/Provider/fr_FR/Address.php | 137 + .../src/Faker/Provider/fr_FR/Company.php | 169 + .../src/Faker/Provider/fr_FR/Internet.php | 9 + .../src/Faker/Provider/fr_FR/Payment.php | 19 + .../faker/src/Faker/Provider/fr_FR/Person.php | 70 + .../src/Faker/Provider/fr_FR/PhoneNumber.php | 70 + .../faker/src/Faker/Provider/fr_FR/Text.php | 15531 ++++++++++++++++ .../src/Faker/Provider/hu_HU/Address.php | 50 + .../src/Faker/Provider/hu_HU/Company.php | 13 + .../faker/src/Faker/Provider/hu_HU/Person.php | 73 + .../src/Faker/Provider/hu_HU/PhoneNumber.php | 14 + .../faker/src/Faker/Provider/hu_HU/Text.php | 3407 ++++ .../src/Faker/Provider/hy_AM/Address.php | 132 + .../src/Faker/Provider/hy_AM/Company.php | 54 + .../src/Faker/Provider/hy_AM/Internet.php | 8 + .../faker/src/Faker/Provider/hy_AM/Person.php | 112 + .../src/Faker/Provider/hy_AM/PhoneNumber.php | 37 + .../src/Faker/Provider/id_ID/Address.php | 316 + .../src/Faker/Provider/id_ID/Company.php | 43 + .../src/Faker/Provider/id_ID/Internet.php | 25 + .../faker/src/Faker/Provider/id_ID/Person.php | 256 + .../src/Faker/Provider/id_ID/PhoneNumber.php | 55 + .../src/Faker/Provider/is_IS/Address.php | 178 + .../src/Faker/Provider/is_IS/Company.php | 53 + .../src/Faker/Provider/is_IS/Internet.php | 23 + .../src/Faker/Provider/is_IS/Payment.php | 19 + .../faker/src/Faker/Provider/is_IS/Person.php | 140 + .../src/Faker/Provider/is_IS/PhoneNumber.php | 20 + .../src/Faker/Provider/it_IT/Address.php | 97 + .../src/Faker/Provider/it_IT/Company.php | 64 + .../src/Faker/Provider/it_IT/Internet.php | 9 + .../src/Faker/Provider/it_IT/Payment.php | 19 + .../faker/src/Faker/Provider/it_IT/Person.php | 88 + .../src/Faker/Provider/it_IT/PhoneNumber.php | 21 + .../faker/src/Faker/Provider/it_IT/Text.php | 1994 ++ .../src/Faker/Provider/ja_JP/Address.php | 137 + .../src/Faker/Provider/ja_JP/Company.php | 17 + .../src/Faker/Provider/ja_JP/Internet.php | 57 + .../faker/src/Faker/Provider/ja_JP/Person.php | 100 + .../src/Faker/Provider/ja_JP/PhoneNumber.php | 12 + .../faker/src/Faker/Provider/ka_GE/Person.php | 59 + .../faker/src/Faker/Provider/ka_GE/Text.php | 997 + .../src/Faker/Provider/kk_KZ/Address.php | 131 + .../faker/src/Faker/Provider/kk_KZ/Color.php | 12 + .../src/Faker/Provider/kk_KZ/Company.php | 72 + .../src/Faker/Provider/kk_KZ/Internet.php | 9 + .../src/Faker/Provider/kk_KZ/Payment.php | 20 + .../faker/src/Faker/Provider/kk_KZ/Person.php | 155 + .../src/Faker/Provider/kk_KZ/PhoneNumber.php | 16 + .../faker/src/Faker/Provider/kk_KZ/Text.php | 490 + .../src/Faker/Provider/ko_KR/Address.php | 96 + .../src/Faker/Provider/ko_KR/Company.php | 31 + .../src/Faker/Provider/ko_KR/Internet.php | 9 + .../faker/src/Faker/Provider/ko_KR/Person.php | 52 + .../src/Faker/Provider/ko_KR/PhoneNumber.php | 17 + .../src/Faker/Provider/lv_LV/Address.php | 114 + .../src/Faker/Provider/lv_LV/Internet.php | 9 + .../src/Faker/Provider/lv_LV/Payment.php | 19 + .../faker/src/Faker/Provider/lv_LV/Person.php | 83 + .../src/Faker/Provider/lv_LV/PhoneNumber.php | 13 + .../src/Faker/Provider/me_ME/Address.php | 127 + .../src/Faker/Provider/me_ME/Company.php | 49 + .../src/Faker/Provider/me_ME/Payment.php | 19 + .../faker/src/Faker/Provider/me_ME/Person.php | 102 + .../src/Faker/Provider/me_ME/PhoneNumber.php | 15 + .../src/Faker/Provider/ne_NP/Address.php | 129 + .../src/Faker/Provider/ne_NP/Internet.php | 32 + .../faker/src/Faker/Provider/ne_NP/Person.php | 121 + .../src/Faker/Provider/ne_NP/PhoneNumber.php | 19 + .../src/Faker/Provider/nl_BE/Address.php | 106 + .../src/Faker/Provider/nl_BE/Company.php | 13 + .../src/Faker/Provider/nl_BE/Internet.php | 9 + .../src/Faker/Provider/nl_BE/Payment.php | 19 + .../faker/src/Faker/Provider/nl_BE/Person.php | 72 + .../src/Faker/Provider/nl_BE/PhoneNumber.php | 20 + .../src/Faker/Provider/nl_NL/Address.php | 112 + .../faker/src/Faker/Provider/nl_NL/Color.php | 36 + .../src/Faker/Provider/nl_NL/Company.php | 15 + .../src/Faker/Provider/nl_NL/Internet.php | 9 + .../src/Faker/Provider/nl_NL/Payment.php | 19 + .../faker/src/Faker/Provider/nl_NL/Person.php | 293 + .../src/Faker/Provider/nl_NL/PhoneNumber.php | 39 + .../src/Faker/Provider/no_NO/Address.php | 195 + .../src/Faker/Provider/no_NO/Company.php | 19 + .../faker/src/Faker/Provider/no_NO/Person.php | 326 + .../src/Faker/Provider/no_NO/PhoneNumber.php | 22 + .../src/Faker/Provider/pl_PL/Address.php | 108 + .../src/Faker/Provider/pl_PL/Company.php | 80 + .../src/Faker/Provider/pl_PL/Internet.php | 9 + .../src/Faker/Provider/pl_PL/Payment.php | 120 + .../faker/src/Faker/Provider/pl_PL/Person.php | 226 + .../src/Faker/Provider/pl_PL/PhoneNumber.php | 18 + .../faker/src/Faker/Provider/pl_PL/Text.php | 2866 +++ .../src/Faker/Provider/pt_BR/Address.php | 132 + .../src/Faker/Provider/pt_BR/Company.php | 33 + .../src/Faker/Provider/pt_BR/Internet.php | 9 + .../src/Faker/Provider/pt_BR/Payment.php | 19 + .../faker/src/Faker/Provider/pt_BR/Person.php | 133 + .../src/Faker/Provider/pt_BR/PhoneNumber.php | 142 + .../src/Faker/Provider/pt_BR/check_digit.php | 35 + .../src/Faker/Provider/pt_PT/Address.php | 124 + .../src/Faker/Provider/pt_PT/Payment.php | 19 + .../faker/src/Faker/Provider/pt_PT/Person.php | 146 + .../src/Faker/Provider/pt_PT/PhoneNumber.php | 50 + .../src/Faker/Provider/ro_MD/Address.php | 148 + .../faker/src/Faker/Provider/ro_MD/Person.php | 90 + .../src/Faker/Provider/ro_MD/PhoneNumber.php | 33 + .../src/Faker/Provider/ro_RO/Address.php | 176 + .../faker/src/Faker/Provider/ro_RO/Person.php | 202 + .../src/Faker/Provider/ro_RO/PhoneNumber.php | 67 + .../src/Faker/Provider/ru_RU/Address.php | 156 + .../faker/src/Faker/Provider/ru_RU/Color.php | 23 + .../src/Faker/Provider/ru_RU/Company.php | 52 + .../src/Faker/Provider/ru_RU/Internet.php | 9 + .../src/Faker/Provider/ru_RU/Payment.php | 811 + .../faker/src/Faker/Provider/ru_RU/Person.php | 135 + .../src/Faker/Provider/ru_RU/PhoneNumber.php | 14 + .../faker/src/Faker/Provider/ru_RU/Text.php | 4544 +++++ .../src/Faker/Provider/sk_SK/Address.php | 344 + .../src/Faker/Provider/sk_SK/Company.php | 64 + .../src/Faker/Provider/sk_SK/Internet.php | 9 + .../src/Faker/Provider/sk_SK/Payment.php | 19 + .../faker/src/Faker/Provider/sk_SK/Person.php | 168 + .../src/Faker/Provider/sk_SK/PhoneNumber.php | 15 + .../src/Faker/Provider/sl_SI/Address.php | 107 + .../src/Faker/Provider/sl_SI/Internet.php | 11 + .../src/Faker/Provider/sl_SI/Payment.php | 19 + .../faker/src/Faker/Provider/sl_SI/Person.php | 149 + .../src/Faker/Provider/sl_SI/PhoneNumber.php | 18 + .../src/Faker/Provider/sr_Cyrl_RS/Address.php | 58 + .../src/Faker/Provider/sr_Cyrl_RS/Payment.php | 19 + .../src/Faker/Provider/sr_Cyrl_RS/Person.php | 242 + .../src/Faker/Provider/sr_Latn_RS/Address.php | 58 + .../src/Faker/Provider/sr_Latn_RS/Payment.php | 19 + .../src/Faker/Provider/sr_Latn_RS/Person.php | 213 + .../src/Faker/Provider/sr_RS/Address.php | 58 + .../src/Faker/Provider/sr_RS/Payment.php | 19 + .../faker/src/Faker/Provider/sr_RS/Person.php | 247 + .../src/Faker/Provider/sv_SE/Address.php | 150 + .../src/Faker/Provider/sv_SE/Company.php | 19 + .../faker/src/Faker/Provider/sv_SE/Person.php | 143 + .../src/Faker/Provider/sv_SE/PhoneNumber.php | 37 + .../src/Faker/Provider/tr_TR/Address.php | 92 + .../faker/src/Faker/Provider/tr_TR/Color.php | 58 + .../src/Faker/Provider/tr_TR/DateTime.php | 46 + .../src/Faker/Provider/tr_TR/Internet.php | 9 + .../src/Faker/Provider/tr_TR/Payment.php | 19 + .../faker/src/Faker/Provider/tr_TR/Person.php | 97 + .../src/Faker/Provider/tr_TR/PhoneNumber.php | 33 + .../src/Faker/Provider/uk_UA/Address.php | 345 + .../faker/src/Faker/Provider/uk_UA/Color.php | 23 + .../src/Faker/Provider/uk_UA/Company.php | 44 + .../src/Faker/Provider/uk_UA/Internet.php | 9 + .../faker/src/Faker/Provider/uk_UA/Person.php | 57 + .../src/Faker/Provider/uk_UA/PhoneNumber.php | 29 + .../faker/src/Faker/Provider/uk_UA/Text.php | 4512 +++++ .../src/Faker/Provider/vi_VN/Address.php | 170 + .../faker/src/Faker/Provider/vi_VN/Color.php | 36 + .../src/Faker/Provider/vi_VN/Internet.php | 8 + .../faker/src/Faker/Provider/vi_VN/Person.php | 184 + .../src/Faker/Provider/vi_VN/PhoneNumber.php | 61 + .../src/Faker/Provider/zh_CN/Address.php | 43 + .../src/Faker/Provider/zh_CN/Company.php | 26 + .../src/Faker/Provider/zh_CN/Internet.php | 19 + .../faker/src/Faker/Provider/zh_CN/Person.php | 49 + .../src/Faker/Provider/zh_CN/PhoneNumber.php | 21 + .../src/Faker/Provider/zh_TW/Address.php | 419 + .../faker/src/Faker/Provider/zh_TW/Color.php | 66 + .../src/Faker/Provider/zh_TW/Company.php | 253 + .../src/Faker/Provider/zh_TW/DateTime.php | 46 + .../src/Faker/Provider/zh_TW/Internet.php | 16 + .../src/Faker/Provider/zh_TW/Payment.php | 11 + .../faker/src/Faker/Provider/zh_TW/Person.php | 132 + .../src/Faker/Provider/zh_TW/PhoneNumber.php | 19 + .../faker/src/Faker/Provider/zh_TW/Text.php | 124 + .../faker/src/Faker/UniqueGenerator.php | 49 + vendor/fzaninotto/faker/src/autoload.php | 27 + .../faker/test/Faker/Calculator/LuhnTest.php | 62 + .../faker/test/Faker/DefaultGeneratorTest.php | 27 + .../faker/test/Faker/GeneratorTest.php | 144 + .../faker/test/Faker/Provider/AddressTest.php | 34 + .../faker/test/Faker/Provider/BarcodeTest.php | 45 + .../faker/test/Faker/Provider/BaseTest.php | 446 + .../faker/test/Faker/Provider/BiasedTest.php | 73 + .../faker/test/Faker/Provider/ColorTest.php | 46 + .../test/Faker/Provider/DateTimeTest.php | 122 + .../faker/test/Faker/Provider/ImageTest.php | 62 + .../test/Faker/Provider/InternetTest.php | 120 + .../test/Faker/Provider/LocalizationTest.php | 26 + .../faker/test/Faker/Provider/LoremTest.php | 108 + .../test/Faker/Provider/MiscellaneousTest.php | 54 + .../faker/test/Faker/Provider/PaymentTest.php | 68 + .../faker/test/Faker/Provider/PersonTest.php | 86 + .../Faker/Provider/ProviderOverrideTest.php | 189 + .../faker/test/Faker/Provider/TextTest.php | 54 + .../test/Faker/Provider/UserAgentTest.php | 38 + .../faker/test/Faker/Provider/UuidTest.php | 26 + .../test/Faker/Provider/at_AT/PaymentTest.php | 30 + .../test/Faker/Provider/be_BE/PaymentTest.php | 30 + .../test/Faker/Provider/bg_BG/PaymentTest.php | 30 + .../Faker/Provider/de_AT/InternetTest.php | 32 + .../Faker/Provider/de_AT/PhoneNumberTest.php | 28 + .../test/Faker/Provider/fr_FR/CompanyTest.php | 74 + .../test/Faker/Provider/id_ID/PersonTest.php | 40 + .../test/Faker/Provider/ja_JP/PersonTest.php | 36 + .../test/Faker/Provider/pt_BR/CompanyTest.php | 25 + .../test/Faker/Provider/pt_BR/PersonTest.php | 33 + .../test/Faker/Provider/pt_PT/AddressTest.php | 30 + .../test/Faker/Provider/pt_PT/PersonTest.php | 52 + .../Faker/Provider/pt_PT/PhoneNumberTest.php | 25 + .../test/Faker/Provider/ro_RO/PersonTest.php | 95 + .../Faker/Provider/ro_RO/PhoneNumberTest.php | 31 + .../test/Faker/Provider/sv_SE/PersonTest.php | 60 + .../test/Faker/Provider/uk_UA/AddressTest.php | 80 + .../Faker/Provider/uk_UA/PhoneNumberTest.php | 35 + vendor/fzaninotto/faker/test/documentor.php | 16 + vendor/fzaninotto/faker/test/test.php | 39 + vendor/illuminate/auth/Access/Gate.php | 447 + .../auth/Access/HandlesAuthorization.php | 30 + vendor/illuminate/auth/Access/Response.php | 43 + .../auth/Access/UnauthorizedException.php | 10 + vendor/illuminate/auth/AuthManager.php | 128 + .../illuminate/auth/AuthServiceProvider.php | 85 + vendor/illuminate/auth/Authenticatable.php | 57 + .../auth/Console/ClearResetsCommand.php | 34 + .../illuminate/auth/DatabaseUserProvider.php | 146 + .../illuminate/auth/EloquentUserProvider.php | 174 + .../auth/GeneratorServiceProvider.php | 65 + vendor/illuminate/auth/GenericUser.php | 122 + vendor/illuminate/auth/Guard.php | 769 + .../Middleware/AuthenticateWithBasicAuth.php | 39 + .../auth/Passwords/CanResetPassword.php | 16 + .../Passwords/DatabaseTokenRepository.php | 193 + .../auth/Passwords/PasswordBroker.php | 252 + .../PasswordResetServiceProvider.php | 87 + .../Passwords/TokenRepositoryInterface.php | 40 + vendor/illuminate/auth/composer.json | 38 + .../broadcasting/BroadcastEvent.php | 87 + .../broadcasting/BroadcastManager.php | 211 + .../broadcasting/BroadcastServiceProvider.php | 49 + .../Broadcasters/LogBroadcaster.php | 39 + .../Broadcasters/PusherBroadcaster.php | 35 + .../Broadcasters/RedisBroadcaster.php | 50 + vendor/illuminate/broadcasting/composer.json | 35 + vendor/illuminate/bus/BusServiceProvider.php | 51 + vendor/illuminate/bus/Dispatcher.php | 410 + vendor/illuminate/bus/MarshalException.php | 23 + vendor/illuminate/bus/Queueable.php | 46 + vendor/illuminate/bus/composer.json | 33 + vendor/illuminate/cache/ApcStore.php | 130 + vendor/illuminate/cache/ApcWrapper.php | 92 + vendor/illuminate/cache/ArrayStore.php | 112 + vendor/illuminate/cache/CacheManager.php | 312 + .../illuminate/cache/CacheServiceProvider.php | 69 + .../cache/Console/CacheTableCommand.php | 81 + .../illuminate/cache/Console/ClearCommand.php | 74 + .../illuminate/cache/Console/stubs/cache.stub | 31 + vendor/illuminate/cache/DatabaseStore.php | 255 + vendor/illuminate/cache/FileStore.php | 248 + .../illuminate/cache/MemcachedConnector.php | 53 + vendor/illuminate/cache/MemcachedStore.php | 164 + vendor/illuminate/cache/NullStore.php | 106 + vendor/illuminate/cache/RateLimiter.php | 98 + vendor/illuminate/cache/RedisStore.php | 197 + vendor/illuminate/cache/RedisTaggedCache.php | 88 + vendor/illuminate/cache/Repository.php | 376 + vendor/illuminate/cache/TagSet.php | 100 + vendor/illuminate/cache/TaggableStore.php | 30 + vendor/illuminate/cache/TaggedCache.php | 249 + vendor/illuminate/cache/WinCacheStore.php | 121 + vendor/illuminate/cache/XCacheStore.php | 121 + vendor/illuminate/cache/composer.json | 38 + vendor/illuminate/config/Repository.php | 156 + vendor/illuminate/config/composer.json | 33 + .../console/AppNamespaceDetectorTrait.php | 18 + vendor/illuminate/console/Application.php | 166 + vendor/illuminate/console/Command.php | 443 + .../illuminate/console/ConfirmableTrait.php | 53 + .../illuminate/console/GeneratorCommand.php | 219 + vendor/illuminate/console/OutputStyle.php | 71 + vendor/illuminate/console/Parser.php | 141 + .../console/ScheduleServiceProvider.php | 37 + .../console/Scheduling/CallbackEvent.php | 122 + .../illuminate/console/Scheduling/Event.php | 848 + .../console/Scheduling/Schedule.php | 109 + .../console/Scheduling/ScheduleRunCommand.php | 62 + vendor/illuminate/console/composer.json | 39 + .../container/BindingResolutionException.php | 13 + vendor/illuminate/container/Container.php | 1216 ++ .../container/ContextualBindingBuilder.php | 66 + vendor/illuminate/container/composer.json | 31 + .../contracts/Auth/Access/Authorizable.php | 15 + .../illuminate/contracts/Auth/Access/Gate.php | 41 + .../contracts/Auth/Authenticatable.php | 42 + .../contracts/Auth/CanResetPassword.php | 13 + vendor/illuminate/contracts/Auth/Guard.php | 101 + .../contracts/Auth/PasswordBroker.php | 77 + .../illuminate/contracts/Auth/Registrar.php | 22 + .../contracts/Auth/UserProvider.php | 49 + .../contracts/Broadcasting/Broadcaster.php | 16 + .../contracts/Broadcasting/Factory.php | 14 + .../Broadcasting/ShouldBroadcast.php | 13 + .../Broadcasting/ShouldBroadcastNow.php | 8 + .../illuminate/contracts/Bus/Dispatcher.php | 54 + .../contracts/Bus/HandlerResolver.php | 48 + .../contracts/Bus/QueueingDispatcher.php | 14 + .../illuminate/contracts/Bus/SelfHandling.php | 8 + vendor/illuminate/contracts/Cache/Factory.php | 14 + .../illuminate/contracts/Cache/Repository.php | 99 + vendor/illuminate/contracts/Cache/Store.php | 73 + .../contracts/Config/Repository.php | 57 + .../contracts/Console/Application.php | 22 + .../illuminate/contracts/Console/Kernel.php | 47 + .../Container/BindingResolutionException.php | 10 + .../contracts/Container/Container.php | 144 + .../Container/ContextualBindingBuilder.php | 22 + .../illuminate/contracts/Cookie/Factory.php | 43 + .../contracts/Cookie/QueueingFactory.php | 28 + .../contracts/Database/ModelIdentifier.php | 33 + .../contracts/Debug/ExceptionHandler.php | 34 + .../contracts/Encryption/DecryptException.php | 10 + .../contracts/Encryption/EncryptException.php | 10 + .../contracts/Encryption/Encrypter.php | 22 + .../contracts/Events/Dispatcher.php | 90 + .../illuminate/contracts/Filesystem/Cloud.php | 8 + .../contracts/Filesystem/Factory.php | 14 + .../Filesystem/FileNotFoundException.php | 10 + .../contracts/Filesystem/Filesystem.php | 175 + .../contracts/Foundation/Application.php | 100 + .../illuminate/contracts/Hashing/Hasher.php | 34 + vendor/illuminate/contracts/Http/Kernel.php | 37 + vendor/illuminate/contracts/Logging/Log.php | 98 + .../illuminate/contracts/Mail/MailQueue.php | 29 + vendor/illuminate/contracts/Mail/Mailer.php | 32 + .../Pagination/LengthAwarePaginator.php | 20 + .../contracts/Pagination/Paginator.php | 109 + .../contracts/Pagination/Presenter.php | 20 + vendor/illuminate/contracts/Pipeline/Hub.php | 15 + .../contracts/Pipeline/Pipeline.php | 40 + .../Queue/EntityNotFoundException.php | 22 + .../contracts/Queue/EntityResolver.php | 15 + vendor/illuminate/contracts/Queue/Factory.php | 14 + vendor/illuminate/contracts/Queue/Job.php | 49 + vendor/illuminate/contracts/Queue/Monitor.php | 30 + vendor/illuminate/contracts/Queue/Queue.php | 66 + .../contracts/Queue/QueueableEntity.php | 13 + .../contracts/Queue/ShouldBeQueued.php | 11 + .../contracts/Queue/ShouldQueue.php | 8 + .../illuminate/contracts/Redis/Database.php | 15 + .../contracts/Routing/Middleware.php | 20 + .../contracts/Routing/Registrar.php | 91 + .../contracts/Routing/ResponseFactory.php | 126 + .../Routing/TerminableMiddleware.php | 18 + .../contracts/Routing/UrlGenerator.php | 64 + .../contracts/Routing/UrlRoutable.php | 20 + .../contracts/Support/Arrayable.php | 13 + .../illuminate/contracts/Support/Htmlable.php | 13 + .../illuminate/contracts/Support/Jsonable.php | 14 + .../contracts/Support/MessageBag.php | 100 + .../contracts/Support/MessageProvider.php | 13 + .../contracts/Support/Renderable.php | 13 + .../contracts/Validation/Factory.php | 46 + .../Validation/UnauthorizedException.php | 10 + .../Validation/ValidatesWhenResolved.php | 13 + .../Validation/ValidationException.php | 47 + .../contracts/Validation/Validator.php | 40 + vendor/illuminate/contracts/View/Factory.php | 71 + vendor/illuminate/contracts/View/View.php | 24 + vendor/illuminate/contracts/composer.json | 30 + vendor/illuminate/cookie/CookieJar.php | 168 + .../cookie/CookieServiceProvider.php | 22 + .../Middleware/AddQueuedCookiesToResponse.php | 45 + .../cookie/Middleware/EncryptCookies.php | 161 + vendor/illuminate/cookie/composer.json | 34 + .../illuminate/database/Capsule/Manager.php | 201 + vendor/illuminate/database/Connection.php | 1148 ++ .../database/ConnectionInterface.php | 149 + .../database/ConnectionResolver.php | 92 + .../database/ConnectionResolverInterface.php | 29 + .../database/Connectors/ConnectionFactory.php | 232 + .../database/Connectors/Connector.php | 106 + .../Connectors/ConnectorInterface.php | 14 + .../database/Connectors/MySqlConnector.php | 112 + .../database/Connectors/PostgresConnector.php | 117 + .../database/Connectors/SQLiteConnector.php | 39 + .../Connectors/SqlServerConnector.php | 137 + .../Console/Migrations/BaseCommand.php | 18 + .../Console/Migrations/InstallCommand.php | 70 + .../Console/Migrations/MigrateCommand.php | 126 + .../Console/Migrations/MigrateMakeCommand.php | 114 + .../Console/Migrations/RefreshCommand.php | 102 + .../Console/Migrations/ResetCommand.php | 94 + .../Console/Migrations/RollbackCommand.php | 88 + .../Console/Migrations/StatusCommand.php | 78 + .../database/Console/Seeds/SeedCommand.php | 103 + .../Console/Seeds/SeederMakeCommand.php | 96 + .../database/Console/Seeds/stubs/seeder.stub | 16 + .../illuminate/database/DatabaseManager.php | 298 + .../database/DatabaseServiceProvider.php | 84 + .../database/DetectsLostConnections.php | 28 + .../illuminate/database/Eloquent/Builder.php | 957 + .../database/Eloquent/Collection.php | 253 + .../illuminate/database/Eloquent/Factory.php | 218 + .../database/Eloquent/FactoryBuilder.php | 135 + .../Eloquent/MassAssignmentException.php | 10 + vendor/illuminate/database/Eloquent/Model.php | 3518 ++++ .../Eloquent/ModelNotFoundException.php | 40 + .../database/Eloquent/QueueEntityResolver.php | 27 + .../database/Eloquent/Relations/BelongsTo.php | 306 + .../Eloquent/Relations/BelongsToMany.php | 1251 ++ .../database/Eloquent/Relations/HasMany.php | 47 + .../Eloquent/Relations/HasManyThrough.php | 408 + .../database/Eloquent/Relations/HasOne.php | 47 + .../Eloquent/Relations/HasOneOrMany.php | 403 + .../database/Eloquent/Relations/MorphMany.php | 47 + .../database/Eloquent/Relations/MorphOne.php | 47 + .../Eloquent/Relations/MorphOneOrMany.php | 233 + .../Eloquent/Relations/MorphPivot.php | 79 + .../database/Eloquent/Relations/MorphTo.php | 269 + .../Eloquent/Relations/MorphToMany.php | 160 + .../database/Eloquent/Relations/Pivot.php | 174 + .../database/Eloquent/Relations/Relation.php | 339 + .../database/Eloquent/ScopeInterface.php | 25 + .../database/Eloquent/SoftDeletes.php | 169 + .../database/Eloquent/SoftDeletingScope.php | 155 + vendor/illuminate/database/Grammar.php | 188 + .../database/MigrationServiceProvider.php | 221 + .../DatabaseMigrationRepository.php | 184 + .../database/Migrations/Migration.php | 23 + .../database/Migrations/MigrationCreator.php | 181 + .../MigrationRepositoryInterface.php | 66 + .../database/Migrations/Migrator.php | 405 + .../database/Migrations/stubs/blank.stub | 27 + .../database/Migrations/stubs/create.stub | 30 + .../database/Migrations/stubs/update.stub | 31 + .../illuminate/database/MySqlConnection.php | 66 + .../database/PostgresConnection.php | 51 + vendor/illuminate/database/Query/Builder.php | 2073 +++ .../illuminate/database/Query/Expression.php | 44 + .../database/Query/Grammars/Grammar.php | 800 + .../database/Query/Grammars/MySqlGrammar.php | 141 + .../Query/Grammars/PostgresGrammar.php | 180 + .../database/Query/Grammars/SQLiteGrammar.php | 140 + .../Query/Grammars/SqlServerGrammar.php | 267 + .../illuminate/database/Query/JoinClause.php | 215 + .../Query/Processors/MySqlProcessor.php | 23 + .../Query/Processors/PostgresProcessor.php | 47 + .../database/Query/Processors/Processor.php | 49 + .../Query/Processors/SQLiteProcessor.php | 23 + .../Query/Processors/SqlServerProcessor.php | 43 + vendor/illuminate/database/QueryException.php | 78 + vendor/illuminate/database/README.md | 70 + .../illuminate/database/SQLiteConnection.php | 51 + .../illuminate/database/Schema/Blueprint.php | 1023 + vendor/illuminate/database/Schema/Builder.php | 243 + .../database/Schema/Grammars/Grammar.php | 459 + .../database/Schema/Grammars/MySqlGrammar.php | 711 + .../Schema/Grammars/PostgresGrammar.php | 554 + .../Schema/Grammars/SQLiteGrammar.php | 615 + .../Schema/Grammars/SqlServerGrammar.php | 562 + .../database/Schema/MySqlBuilder.php | 42 + .../database/SeedServiceProvider.php | 69 + vendor/illuminate/database/Seeder.php | 97 + .../database/SqlServerConnection.php | 95 + vendor/illuminate/database/composer.json | 42 + .../illuminate/encryption/BaseEncrypter.php | 82 + vendor/illuminate/encryption/Encrypter.php | 107 + .../encryption/EncryptionServiceProvider.php | 33 + .../illuminate/encryption/McryptEncrypter.php | 203 + vendor/illuminate/encryption/composer.json | 37 + .../illuminate/events/CallQueuedHandler.php | 80 + vendor/illuminate/events/Dispatcher.php | 497 + .../events/EventServiceProvider.php | 22 + vendor/illuminate/events/composer.json | 33 + vendor/illuminate/filesystem/ClassFinder.php | 145 + vendor/illuminate/filesystem/Filesystem.php | 442 + .../filesystem/FilesystemAdapter.php | 349 + .../filesystem/FilesystemManager.php | 274 + .../filesystem/FilesystemServiceProvider.php | 80 + vendor/illuminate/filesystem/composer.json | 38 + vendor/illuminate/hashing/BcryptHasher.php | 82 + .../hashing/HashServiceProvider.php | 35 + vendor/illuminate/hashing/composer.json | 32 + .../http/Exception/HttpResponseException.php | 37 + .../http/Exception/PostTooLargeException.php | 10 + vendor/illuminate/http/JsonResponse.php | 80 + .../illuminate/http/Middleware/FrameGuard.php | 24 + vendor/illuminate/http/RedirectResponse.php | 200 + vendor/illuminate/http/Request.php | 910 + vendor/illuminate/http/Response.php | 94 + vendor/illuminate/http/ResponseTrait.php | 58 + vendor/illuminate/http/composer.json | 34 + .../pagination/AbstractPaginator.php | 487 + ...apThreeNextPreviousButtonRendererTrait.php | 48 + .../pagination/BootstrapThreePresenter.php | 134 + .../pagination/LengthAwarePaginator.php | 164 + .../pagination/PaginationServiceProvider.php | 24 + vendor/illuminate/pagination/Paginator.php | 135 + .../SimpleBootstrapThreePresenter.php | 47 + vendor/illuminate/pagination/UrlWindow.php | 222 + .../pagination/UrlWindowPresenterTrait.php | 66 + vendor/illuminate/pagination/composer.json | 32 + vendor/illuminate/pipeline/Hub.php | 74 + vendor/illuminate/pipeline/Pipeline.php | 159 + .../pipeline/PipelineServiceProvider.php | 39 + vendor/illuminate/pipeline/composer.json | 32 + vendor/illuminate/queue/BeanstalkdQueue.php | 143 + vendor/illuminate/queue/CallQueuedHandler.php | 80 + vendor/illuminate/queue/Capsule/Manager.php | 183 + .../queue/Connectors/BeanstalkdConnector.php | 26 + .../queue/Connectors/ConnectorInterface.php | 14 + .../queue/Connectors/DatabaseConnector.php | 44 + .../queue/Connectors/IronConnector.php | 61 + .../queue/Connectors/NullConnector.php | 19 + .../queue/Connectors/RedisConnector.php | 54 + .../queue/Connectors/SqsConnector.php | 29 + .../queue/Connectors/SyncConnector.php | 19 + .../queue/Console/FailedTableCommand.php | 91 + .../queue/Console/FlushFailedCommand.php | 34 + .../queue/Console/ForgetFailedCommand.php | 49 + .../queue/Console/ListFailedCommand.php | 113 + .../queue/Console/ListenCommand.php | 144 + .../queue/Console/RestartCommand.php | 34 + .../illuminate/queue/Console/RetryCommand.php | 76 + .../queue/Console/SubscribeCommand.php | 162 + .../illuminate/queue/Console/TableCommand.php | 91 + .../illuminate/queue/Console/WorkCommand.php | 177 + .../queue/Console/stubs/failed_jobs.stub | 33 + .../illuminate/queue/Console/stubs/jobs.stub | 37 + .../queue/ConsoleServiceProvider.php | 71 + vendor/illuminate/queue/DatabaseQueue.php | 323 + .../Failed/DatabaseFailedJobProvider.php | 112 + .../Failed/FailedJobProviderInterface.php | 46 + .../queue/Failed/NullFailedJobProvider.php | 61 + .../queue/IlluminateQueueClosure.php | 38 + .../illuminate/queue/InteractsWithQueue.php | 63 + vendor/illuminate/queue/IronQueue.php | 263 + .../illuminate/queue/Jobs/BeanstalkdJob.php | 154 + vendor/illuminate/queue/Jobs/DatabaseJob.php | 139 + vendor/illuminate/queue/Jobs/IronJob.php | 180 + vendor/illuminate/queue/Jobs/Job.php | 270 + vendor/illuminate/queue/Jobs/RedisJob.php | 139 + vendor/illuminate/queue/Jobs/SqsJob.php | 147 + vendor/illuminate/queue/Jobs/SyncJob.php | 87 + vendor/illuminate/queue/Listener.php | 265 + vendor/illuminate/queue/NullQueue.php | 59 + vendor/illuminate/queue/Queue.php | 226 + vendor/illuminate/queue/QueueManager.php | 243 + .../illuminate/queue/QueueServiceProvider.php | 326 + vendor/illuminate/queue/README.md | 34 + vendor/illuminate/queue/RedisQueue.php | 319 + vendor/illuminate/queue/SerializesModels.php | 80 + vendor/illuminate/queue/SqsQueue.php | 151 + vendor/illuminate/queue/SyncQueue.php | 134 + vendor/illuminate/queue/Worker.php | 384 + vendor/illuminate/queue/composer.json | 46 + .../session/CacheBasedSessionHandler.php | 94 + .../session/CommandsServiceProvider.php | 40 + .../session/Console/SessionTableCommand.php | 81 + .../session/Console/stubs/database.stub | 31 + .../session/CookieSessionHandler.php | 96 + .../session/DatabaseSessionHandler.php | 130 + vendor/illuminate/session/EncryptedStore.php | 69 + .../session/ExistenceAwareInterface.php | 14 + .../illuminate/session/FileSessionHandler.php | 97 + .../session/Middleware/StartSession.php | 244 + .../illuminate/session/SessionInterface.php | 31 + vendor/illuminate/session/SessionManager.php | 206 + .../session/SessionServiceProvider.php | 51 + vendor/illuminate/session/Store.php | 682 + .../session/TokenMismatchException.php | 10 + vendor/illuminate/session/composer.json | 38 + .../support/AggregateServiceProvider.php | 52 + vendor/illuminate/support/Arr.php | 459 + vendor/illuminate/support/ClassLoader.php | 104 + vendor/illuminate/support/Collection.php | 1062 ++ vendor/illuminate/support/Debug/Dumper.php | 22 + .../illuminate/support/Debug/HtmlDumper.php | 29 + vendor/illuminate/support/Facades/App.php | 19 + vendor/illuminate/support/Facades/Artisan.php | 19 + vendor/illuminate/support/Facades/Auth.php | 20 + vendor/illuminate/support/Facades/Blade.php | 19 + vendor/illuminate/support/Facades/Bus.php | 19 + vendor/illuminate/support/Facades/Cache.php | 20 + vendor/illuminate/support/Facades/Config.php | 19 + vendor/illuminate/support/Facades/Cookie.php | 42 + vendor/illuminate/support/Facades/Crypt.php | 19 + vendor/illuminate/support/Facades/DB.php | 20 + vendor/illuminate/support/Facades/Event.php | 19 + vendor/illuminate/support/Facades/Facade.php | 229 + vendor/illuminate/support/Facades/File.php | 19 + vendor/illuminate/support/Facades/Gate.php | 19 + vendor/illuminate/support/Facades/Hash.php | 19 + vendor/illuminate/support/Facades/Input.php | 33 + vendor/illuminate/support/Facades/Lang.php | 19 + vendor/illuminate/support/Facades/Log.php | 19 + vendor/illuminate/support/Facades/Mail.php | 19 + .../illuminate/support/Facades/Password.php | 54 + vendor/illuminate/support/Facades/Queue.php | 20 + .../illuminate/support/Facades/Redirect.php | 19 + vendor/illuminate/support/Facades/Redis.php | 19 + vendor/illuminate/support/Facades/Request.php | 19 + .../illuminate/support/Facades/Response.php | 19 + vendor/illuminate/support/Facades/Route.php | 19 + vendor/illuminate/support/Facades/Schema.php | 30 + vendor/illuminate/support/Facades/Session.php | 20 + vendor/illuminate/support/Facades/Storage.php | 19 + vendor/illuminate/support/Facades/URL.php | 19 + .../illuminate/support/Facades/Validator.php | 19 + vendor/illuminate/support/Facades/View.php | 19 + vendor/illuminate/support/Fluent.php | 192 + vendor/illuminate/support/HtmlString.php | 46 + vendor/illuminate/support/Manager.php | 139 + vendor/illuminate/support/MessageBag.php | 309 + .../support/NamespacedItemResolver.php | 104 + vendor/illuminate/support/Pluralizer.php | 101 + vendor/illuminate/support/ServiceProvider.php | 236 + vendor/illuminate/support/Str.php | 460 + .../support/Traits/CapsuleManagerTrait.php | 69 + .../illuminate/support/Traits/Macroable.php | 83 + vendor/illuminate/support/ViewErrorBag.php | 107 + vendor/illuminate/support/composer.json | 42 + vendor/illuminate/support/helpers.php | 774 + vendor/illuminate/translation/FileLoader.php | 127 + .../translation/LoaderInterface.php | 25 + .../TranslationServiceProvider.php | 62 + vendor/illuminate/translation/Translator.php | 367 + vendor/illuminate/translation/composer.json | 33 + .../validation/DatabasePresenceVerifier.php | 120 + vendor/illuminate/validation/Factory.php | 241 + .../validation/PresenceVerifierInterface.php | 30 + .../validation/ValidatesWhenResolvedTrait.php | 73 + .../validation/ValidationServiceProvider.php | 68 + vendor/illuminate/validation/Validator.php | 2639 +++ vendor/illuminate/validation/composer.json | 38 + .../view/Compilers/BladeCompiler.php | 889 + vendor/illuminate/view/Compilers/Compiler.php | 68 + .../view/Compilers/CompilerInterface.php | 30 + .../view/Engines/CompilerEngine.php | 101 + vendor/illuminate/view/Engines/Engine.php | 23 + .../view/Engines/EngineInterface.php | 15 + .../view/Engines/EngineResolver.php | 59 + vendor/illuminate/view/Engines/PhpEngine.php | 69 + vendor/illuminate/view/Expression.php | 46 + vendor/illuminate/view/Factory.php | 870 + vendor/illuminate/view/FileViewFinder.php | 266 + .../Middleware/ShareErrorsFromSession.php | 51 + vendor/illuminate/view/View.php | 392 + .../illuminate/view/ViewFinderInterface.php | 55 + .../illuminate/view/ViewServiceProvider.php | 124 + vendor/illuminate/view/composer.json | 35 + vendor/laravel/lumen-framework/.gitignore | 4 + vendor/laravel/lumen-framework/.travis.yml | 14 + vendor/laravel/lumen-framework/LICENSE.txt | 21 + vendor/laravel/lumen-framework/composer.json | 70 + vendor/laravel/lumen-framework/config/app.php | 46 + .../laravel/lumen-framework/config/auth.php | 67 + .../lumen-framework/config/broadcasting.php | 49 + .../laravel/lumen-framework/config/cache.php | 75 + .../lumen-framework/config/database.php | 134 + .../lumen-framework/config/filesystems.php | 72 + .../laravel/lumen-framework/config/mail.php | 124 + .../laravel/lumen-framework/config/queue.php | 93 + .../lumen-framework/config/session.php | 153 + .../laravel/lumen-framework/config/view.php | 33 + .../lumen-framework/lang/en/validation.php | 107 + vendor/laravel/lumen-framework/phpunit.php | 30 + vendor/laravel/lumen-framework/phpunit.xml | 24 + vendor/laravel/lumen-framework/readme.md | 25 + .../lumen-framework/src/Application.php | 1819 ++ .../src/Console/Commands/ServeCommand.php | 57 + .../Commands/stubs/DatabaseSeeder.stub | 20 + .../src/Console/Commands/stubs/routes.stub | 16 + .../lumen-framework/src/Console/Kernel.php | 205 + .../src/Exceptions/Handler.php | 102 + .../src/Foundation/Composer.php | 98 + .../Providers/EventServiceProvider.php | 60 + .../Foundation/Testing/DatabaseMigrations.php | 18 + .../Testing/DatabaseTransactions.php | 18 + .../Foundation/Testing/WithoutMiddleware.php | 20 + .../src/Http/Middleware/VerifyCsrfToken.php | 92 + .../lumen-framework/src/Http/Redirector.php | 96 + .../src/Http/ResponseFactory.php | 63 + .../src/Providers/CacheServiceProvider.php | 23 + .../lumen-framework/src/Routing/Closure.php | 75 + .../src/Routing/Controller.php | 52 + .../src/Routing/DispatchesJobs.php | 44 + .../src/Routing/UrlGenerator.php | 333 + .../src/Routing/ValidatesRequests.php | 102 + .../src/Testing/ApplicationTrait.php | 267 + .../src/Testing/AssertionsTrait.php | 190 + .../src/Testing/CrawlerTrait.php | 772 + .../lumen-framework/src/Testing/TestCase.php | 78 + .../laravel/lumen-framework/src/helpers.php | 427 + .../lumen-framework/storage/logs/.gitignore | 2 + .../tests/FullApplicationTest.php | 496 + .../tests/fixtures/TestController.php | 11 + vendor/monolog/monolog/.php_cs | 15 + vendor/monolog/monolog/CHANGELOG.mdown | 265 + vendor/monolog/monolog/LICENSE | 19 + vendor/monolog/monolog/README.mdown | 95 + vendor/monolog/monolog/composer.json | 65 + vendor/monolog/monolog/doc/01-usage.md | 228 + .../doc/02-handlers-formatters-processors.md | 142 + vendor/monolog/monolog/doc/03-utilities.md | 13 + vendor/monolog/monolog/doc/04-extending.md | 76 + vendor/monolog/monolog/doc/sockets.md | 39 + vendor/monolog/monolog/phpunit.xml.dist | 19 + .../monolog/src/Monolog/ErrorHandler.php | 224 + .../Monolog/Formatter/ChromePHPFormatter.php | 79 + .../Monolog/Formatter/ElasticaFormatter.php | 87 + .../Monolog/Formatter/FlowdockFormatter.php | 116 + .../Monolog/Formatter/FormatterInterface.php | 36 + .../Formatter/GelfMessageFormatter.php | 111 + .../src/Monolog/Formatter/HtmlFormatter.php | 140 + .../src/Monolog/Formatter/JsonFormatter.php | 116 + .../src/Monolog/Formatter/LineFormatter.php | 159 + .../src/Monolog/Formatter/LogglyFormatter.php | 47 + .../Monolog/Formatter/LogstashFormatter.php | 166 + .../Monolog/Formatter/MongoDBFormatter.php | 105 + .../Monolog/Formatter/NormalizerFormatter.php | 193 + .../src/Monolog/Formatter/ScalarFormatter.php | 48 + .../Monolog/Formatter/WildfireFormatter.php | 113 + .../src/Monolog/Handler/AbstractHandler.php | 184 + .../Handler/AbstractProcessingHandler.php | 66 + .../Monolog/Handler/AbstractSyslogHandler.php | 92 + .../src/Monolog/Handler/AmqpHandler.php | 98 + .../Monolog/Handler/BrowserConsoleHandler.php | 192 + .../src/Monolog/Handler/BufferHandler.php | 117 + .../src/Monolog/Handler/ChromePHPHandler.php | 204 + .../src/Monolog/Handler/CouchDBHandler.php | 72 + .../src/Monolog/Handler/CubeHandler.php | 149 + .../monolog/src/Monolog/Handler/Curl/Util.php | 57 + .../Handler/DoctrineCouchDBHandler.php | 45 + .../src/Monolog/Handler/DynamoDbHandler.php | 89 + .../Monolog/Handler/ElasticSearchHandler.php | 128 + .../src/Monolog/Handler/ErrorLogHandler.php | 82 + .../src/Monolog/Handler/FilterHandler.php | 140 + .../ActivationStrategyInterface.php | 28 + .../ChannelLevelActivationStrategy.php | 59 + .../ErrorLevelActivationStrategy.php | 34 + .../Monolog/Handler/FingersCrossedHandler.php | 153 + .../src/Monolog/Handler/FirePHPHandler.php | 195 + .../src/Monolog/Handler/FleepHookHandler.php | 126 + .../src/Monolog/Handler/FlowdockHandler.php | 127 + .../src/Monolog/Handler/GelfHandler.php | 73 + .../src/Monolog/Handler/GroupHandler.php | 80 + .../src/Monolog/Handler/HandlerInterface.php | 90 + .../src/Monolog/Handler/HipChatHandler.php | 337 + .../src/Monolog/Handler/IFTTTHandler.php | 69 + .../src/Monolog/Handler/LogEntriesHandler.php | 55 + .../src/Monolog/Handler/LogglyHandler.php | 102 + .../src/Monolog/Handler/MailHandler.php | 55 + .../src/Monolog/Handler/MandrillHandler.php | 68 + .../Handler/MissingExtensionException.php | 21 + .../src/Monolog/Handler/MongoDBHandler.php | 55 + .../Monolog/Handler/NativeMailerHandler.php | 176 + .../src/Monolog/Handler/NewRelicHandler.php | 198 + .../src/Monolog/Handler/NullHandler.php | 45 + .../src/Monolog/Handler/PHPConsoleHandler.php | 242 + .../src/Monolog/Handler/PsrHandler.php | 56 + .../src/Monolog/Handler/PushoverHandler.php | 185 + .../src/Monolog/Handler/RavenHandler.php | 207 + .../src/Monolog/Handler/RedisHandler.php | 97 + .../src/Monolog/Handler/RollbarHandler.php | 95 + .../Monolog/Handler/RotatingFileHandler.php | 155 + .../src/Monolog/Handler/SamplingHandler.php | 82 + .../src/Monolog/Handler/SlackHandler.php | 284 + .../src/Monolog/Handler/SocketHandler.php | 284 + .../src/Monolog/Handler/StreamHandler.php | 146 + .../Monolog/Handler/SwiftMailerHandler.php | 88 + .../src/Monolog/Handler/SyslogHandler.php | 67 + .../Monolog/Handler/SyslogUdp/UdpSocket.php | 56 + .../src/Monolog/Handler/SyslogUdpHandler.php | 82 + .../src/Monolog/Handler/TestHandler.php | 148 + .../Handler/WhatFailureGroupHandler.php | 57 + .../Monolog/Handler/ZendMonitorHandler.php | 95 + vendor/monolog/monolog/src/Monolog/Logger.php | 649 + .../src/Monolog/Processor/GitProcessor.php | 64 + .../Processor/IntrospectionProcessor.php | 102 + .../Processor/MemoryPeakUsageProcessor.php | 35 + .../src/Monolog/Processor/MemoryProcessor.php | 63 + .../Processor/MemoryUsageProcessor.php | 35 + .../Monolog/Processor/ProcessIdProcessor.php | 31 + .../Processor/PsrLogMessageProcessor.php | 48 + .../src/Monolog/Processor/TagProcessor.php | 44 + .../src/Monolog/Processor/UidProcessor.php | 46 + .../src/Monolog/Processor/WebProcessor.php | 105 + .../monolog/monolog/src/Monolog/Registry.php | 134 + .../tests/Monolog/ErrorHandlerTest.php | 31 + .../Formatter/ChromePHPFormatterTest.php | 158 + .../Formatter/ElasticaFormatterTest.php | 79 + .../Formatter/FlowdockFormatterTest.php | 55 + .../Formatter/GelfMessageFormatterTest.php | 204 + .../Monolog/Formatter/JsonFormatterTest.php | 78 + .../Monolog/Formatter/LineFormatterTest.php | 208 + .../Monolog/Formatter/LogglyFormatterTest.php | 40 + .../Formatter/LogstashFormatterTest.php | 289 + .../Formatter/MongoDBFormatterTest.php | 253 + .../Formatter/NormalizerFormatterTest.php | 270 + .../Monolog/Formatter/ScalarFormatterTest.php | 100 + .../Formatter/WildfireFormatterTest.php | 142 + .../Monolog/Handler/AbstractHandlerTest.php | 115 + .../Handler/AbstractProcessingHandlerTest.php | 80 + .../tests/Monolog/Handler/AmqpHandlerTest.php | 136 + .../Handler/BrowserConsoleHandlerTest.php | 130 + .../Monolog/Handler/BufferHandlerTest.php | 158 + .../Monolog/Handler/ChromePHPHandlerTest.php | 141 + .../Monolog/Handler/CouchDBHandlerTest.php | 31 + .../Handler/DoctrineCouchDBHandlerTest.php | 52 + .../Monolog/Handler/DynamoDbHandlerTest.php | 75 + .../Handler/ElasticSearchHandlerTest.php | 239 + .../Monolog/Handler/ErrorLogHandlerTest.php | 66 + .../Monolog/Handler/FilterHandlerTest.php | 170 + .../Handler/FingersCrossedHandlerTest.php | 255 + .../Monolog/Handler/FirePHPHandlerTest.php | 96 + .../tests/Monolog/Handler/Fixtures/.gitkeep | 0 .../Monolog/Handler/FleepHookHandlerTest.php | 85 + .../Monolog/Handler/FlowdockHandlerTest.php | 88 + .../Monolog/Handler/GelfHandlerLegacyTest.php | 95 + .../tests/Monolog/Handler/GelfHandlerTest.php | 117 + .../Handler/GelfMockMessagePublisher.php | 25 + .../Monolog/Handler/GroupHandlerTest.php | 89 + .../Monolog/Handler/HipChatHandlerTest.php | 244 + .../Monolog/Handler/LogEntriesHandlerTest.php | 84 + .../tests/Monolog/Handler/MailHandlerTest.php | 75 + .../tests/Monolog/Handler/MockRavenClient.php | 27 + .../Monolog/Handler/MongoDBHandlerTest.php | 65 + .../Handler/NativeMailerHandlerTest.php | 61 + .../Monolog/Handler/NewRelicHandlerTest.php | 192 + .../tests/Monolog/Handler/NullHandlerTest.php | 33 + .../Monolog/Handler/PHPConsoleHandlerTest.php | 274 + .../tests/Monolog/Handler/PsrHandlerTest.php | 50 + .../Monolog/Handler/PushoverHandlerTest.php | 141 + .../Monolog/Handler/RavenHandlerTest.php | 199 + .../Monolog/Handler/RedisHandlerTest.php | 127 + .../Handler/RotatingFileHandlerTest.php | 99 + .../Monolog/Handler/SamplingHandlerTest.php | 33 + .../Monolog/Handler/SlackHandlerTest.php | 133 + .../Monolog/Handler/SocketHandlerTest.php | 282 + .../Monolog/Handler/StreamHandlerTest.php | 168 + .../Handler/SwiftMailerHandlerTest.php | 79 + .../Monolog/Handler/SyslogHandlerTest.php | 44 + .../Monolog/Handler/SyslogUdpHandlerTest.php | 49 + .../tests/Monolog/Handler/TestHandlerTest.php | 66 + .../tests/Monolog/Handler/UdpSocketTest.php | 64 + .../Handler/WhatFailureGroupHandlerTest.php | 121 + .../Handler/ZendMonitorHandlerTest.php | 69 + .../monolog/tests/Monolog/LoggerTest.php | 471 + .../Monolog/Processor/GitProcessorTest.php | 29 + .../Processor/IntrospectionProcessorTest.php | 123 + .../MemoryPeakUsageProcessorTest.php | 42 + .../Processor/MemoryUsageProcessorTest.php | 42 + .../Processor/ProcessIdProcessorTest.php | 30 + .../Processor/PsrLogMessageProcessorTest.php | 43 + .../Monolog/Processor/TagProcessorTest.php | 49 + .../Monolog/Processor/UidProcessorTest.php | 32 + .../Monolog/Processor/WebProcessorTest.php | 98 + .../tests/Monolog/PsrLogCompatTest.php | 47 + .../monolog/tests/Monolog/RegistryTest.php | 153 + .../monolog/tests/Monolog/TestCase.php | 58 + vendor/mtdowling/cron-expression/LICENSE | 19 + vendor/mtdowling/cron-expression/README.md | 82 + .../mtdowling/cron-expression/composer.json | 23 + .../cron-expression/phpunit.xml.dist | 17 + .../src/Cron/AbstractField.php | 104 + .../src/Cron/CronExpression.php | 332 + .../src/Cron/DayOfMonthField.php | 103 + .../src/Cron/DayOfWeekField.php | 134 + .../cron-expression/src/Cron/FieldFactory.php | 55 + .../src/Cron/FieldInterface.php | 39 + .../cron-expression/src/Cron/HoursField.php | 38 + .../cron-expression/src/Cron/MinutesField.php | 30 + .../cron-expression/src/Cron/MonthField.php | 44 + .../cron-expression/src/Cron/YearField.php | 34 + .../tests/Cron/AbstractFieldTest.php | 84 + .../tests/Cron/CronExpressionTest.php | 376 + .../tests/Cron/DayOfMonthFieldTest.php | 50 + .../tests/Cron/DayOfWeekFieldTest.php | 116 + .../tests/Cron/FieldFactoryTest.php | 42 + .../tests/Cron/HoursFieldTest.php | 38 + .../tests/Cron/MinutesFieldTest.php | 36 + .../tests/Cron/MonthFieldTest.php | 61 + .../tests/Cron/YearFieldTest.php | 36 + vendor/nesbot/carbon/.editorconfig | 14 + vendor/nesbot/carbon/LICENSE | 19 + vendor/nesbot/carbon/composer.json | 31 + vendor/nesbot/carbon/readme.md | 81 + vendor/nesbot/carbon/src/Carbon/Carbon.php | 2554 +++ .../carbon/src/Carbon/CarbonInterval.php | 517 + vendor/nesbot/carbon/src/Carbon/Lang/ar.php | 32 + vendor/nesbot/carbon/src/Carbon/Lang/az.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/bg.php | 32 + vendor/nesbot/carbon/src/Carbon/Lang/bn.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/ca.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/cs.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/da.php | 29 + vendor/nesbot/carbon/src/Carbon/Lang/de.php | 39 + vendor/nesbot/carbon/src/Carbon/Lang/el.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/en.php | 29 + vendor/nesbot/carbon/src/Carbon/Lang/eo.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/es.php | 29 + vendor/nesbot/carbon/src/Carbon/Lang/eu.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/fa.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/fi.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/fo.php | 29 + vendor/nesbot/carbon/src/Carbon/Lang/fr.php | 29 + vendor/nesbot/carbon/src/Carbon/Lang/he.php | 29 + vendor/nesbot/carbon/src/Carbon/Lang/hr.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/hu.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/id.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/it.php | 29 + vendor/nesbot/carbon/src/Carbon/Lang/ja.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/ko.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/lt.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/lv.php | 44 + vendor/nesbot/carbon/src/Carbon/Lang/ms.php | 27 + vendor/nesbot/carbon/src/Carbon/Lang/nl.php | 27 + vendor/nesbot/carbon/src/Carbon/Lang/no.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/pl.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/pt.php | 30 + .../nesbot/carbon/src/Carbon/Lang/pt_BR.php | 27 + vendor/nesbot/carbon/src/Carbon/Lang/ro.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/ru.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/sk.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/sl.php | 37 + vendor/nesbot/carbon/src/Carbon/Lang/sr.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/sv.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/th.php | 31 + vendor/nesbot/carbon/src/Carbon/Lang/tr.php | 29 + vendor/nesbot/carbon/src/Carbon/Lang/uk.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/uz.php | 28 + vendor/nesbot/carbon/src/Carbon/Lang/vi.php | 30 + .../nesbot/carbon/src/Carbon/Lang/zh-TW.php | 30 + vendor/nesbot/carbon/src/Carbon/Lang/zh.php | 30 + vendor/nikic/fast-route/.travis.yml | 12 + vendor/nikic/fast-route/LICENSE | 31 + vendor/nikic/fast-route/README.md | 199 + vendor/nikic/fast-route/composer.json | 21 + vendor/nikic/fast-route/phpunit.xml | 24 + .../fast-route/src/BadRouteException.php | 6 + vendor/nikic/fast-route/src/DataGenerator.php | 25 + .../src/DataGenerator/CharCountBased.php | 28 + .../src/DataGenerator/GroupCountBased.php | 28 + .../src/DataGenerator/GroupPosBased.php | 25 + .../src/DataGenerator/MarkBased.php | 25 + .../src/DataGenerator/RegexBasedAbstract.php | 113 + vendor/nikic/fast-route/src/Dispatcher.php | 25 + .../src/Dispatcher/CharCountBased.php | 28 + .../src/Dispatcher/GroupCountBased.php | 28 + .../src/Dispatcher/GroupPosBased.php | 30 + .../fast-route/src/Dispatcher/MarkBased.php | 28 + .../src/Dispatcher/RegexBasedAbstract.php | 64 + vendor/nikic/fast-route/src/Route.php | 38 + .../nikic/fast-route/src/RouteCollector.php | 44 + vendor/nikic/fast-route/src/RouteParser.php | 21 + .../nikic/fast-route/src/RouteParser/Std.php | 49 + vendor/nikic/fast-route/src/bootstrap.php | 12 + vendor/nikic/fast-route/src/functions.php | 64 + .../test/Dispatcher/CharCountBasedTest.php | 13 + .../test/Dispatcher/DispatcherTest.php | 466 + .../test/Dispatcher/GroupCountBasedTest.php | 13 + .../test/Dispatcher/GroupPosBasedTest.php | 13 + .../test/Dispatcher/MarkBasedTest.php | 20 + vendor/nikic/fast-route/test/bootstrap.php | 11 + vendor/paragonie/random_compat/.gitignore | 4 + .../paragonie/random_compat/.scrutinizer.yml | 4 + vendor/paragonie/random_compat/.travis.yml | 26 + vendor/paragonie/random_compat/ERRATA.md | 40 + vendor/paragonie/random_compat/LICENSE | 22 + vendor/paragonie/random_compat/README.md | 149 + vendor/paragonie/random_compat/SECURITY.md | 108 + vendor/paragonie/random_compat/composer.json | 32 + .../random_compat/lib/byte_safe_strings.php | 160 + .../random_compat/lib/cast_to_int.php | 64 + .../random_compat/lib/error_polyfill.php | 42 + vendor/paragonie/random_compat/lib/random.php | 137 + .../lib/random_bytes_com_dotnet.php | 77 + .../lib/random_bytes_dev_urandom.php | 137 + .../lib/random_bytes_libsodium.php | 84 + .../random_compat/lib/random_bytes_mcrypt.php | 72 + .../lib/random_bytes_openssl.php | 76 + .../random_compat/lib/random_int.php | 185 + .../random_compat/tests/full/DieHardTest.php | 61 + .../random_compat/tests/full/StatTest.php | 52 + .../paragonie/random_compat/tests/phpunit.sh | 122 + .../random_compat/tests/specific/capicom.php | 7 + .../tests/specific/dev_urandom.php | 7 + .../tests/specific/libsodium.php | 7 + .../random_compat/tests/specific/mcrypt.php | 7 + .../random_compat/tests/specific/openssl.php | 7 + .../tests/unit/RandomBytesTest.php | 52 + .../tests/unit/RandomIntTest.php | 52 + .../random_compat/tests/unit/UtilityTest.php | 95 + .../reflection-docblock/.gitignore | 2 + .../reflection-docblock/.travis.yml | 32 + .../phpdocumentor/reflection-docblock/LICENSE | 21 + .../reflection-docblock/README.md | 57 + .../reflection-docblock/composer.json | 26 + .../reflection-docblock/composer.lock | 827 + .../reflection-docblock/phpunit.xml.dist | 14 + .../src/phpDocumentor/Reflection/DocBlock.php | 468 + .../Reflection/DocBlock/Context.php | 154 + .../Reflection/DocBlock/Description.php | 223 + .../Reflection/DocBlock/Location.php | 76 + .../Reflection/DocBlock/Serializer.php | 198 + .../phpDocumentor/Reflection/DocBlock/Tag.php | 377 + .../Reflection/DocBlock/Tag/AuthorTag.php | 131 + .../Reflection/DocBlock/Tag/CoversTag.php | 24 + .../Reflection/DocBlock/Tag/DeprecatedTag.php | 26 + .../Reflection/DocBlock/Tag/ExampleTag.php | 156 + .../Reflection/DocBlock/Tag/LinkTag.php | 81 + .../Reflection/DocBlock/Tag/MethodTag.php | 209 + .../Reflection/DocBlock/Tag/ParamTag.php | 119 + .../DocBlock/Tag/PropertyReadTag.php | 24 + .../Reflection/DocBlock/Tag/PropertyTag.php | 24 + .../DocBlock/Tag/PropertyWriteTag.php | 24 + .../Reflection/DocBlock/Tag/ReturnTag.php | 99 + .../Reflection/DocBlock/Tag/SeeTag.php | 81 + .../Reflection/DocBlock/Tag/SinceTag.php | 26 + .../Reflection/DocBlock/Tag/SourceTag.php | 137 + .../Reflection/DocBlock/Tag/ThrowsTag.php | 24 + .../Reflection/DocBlock/Tag/UsesTag.php | 24 + .../Reflection/DocBlock/Tag/VarTag.php | 24 + .../Reflection/DocBlock/Tag/VersionTag.php | 108 + .../Reflection/DocBlock/Type/Collection.php | 221 + .../Reflection/DocBlock/DescriptionTest.php | 245 + .../Reflection/DocBlock/Tag/CoversTagTest.php | 86 + .../DocBlock/Tag/DeprecatedTagTest.php | 115 + .../DocBlock/Tag/ExampleTagTest.php | 203 + .../Reflection/DocBlock/Tag/LinkTagTest.php | 87 + .../Reflection/DocBlock/Tag/MethodTagTest.php | 146 + .../Reflection/DocBlock/Tag/ParamTagTest.php | 118 + .../Reflection/DocBlock/Tag/ReturnTagTest.php | 102 + .../Reflection/DocBlock/Tag/SeeTagTest.php | 86 + .../Reflection/DocBlock/Tag/SinceTagTest.php | 115 + .../Reflection/DocBlock/Tag/SourceTagTest.php | 116 + .../Reflection/DocBlock/Tag/ThrowsTagTest.php | 102 + .../Reflection/DocBlock/Tag/UsesTagTest.php | 86 + .../Reflection/DocBlock/Tag/VarTagTest.php | 94 + .../DocBlock/Tag/VersionTagTest.php | 115 + .../Reflection/DocBlock/TagTest.php | 313 + .../DocBlock/Type/CollectionTest.php | 195 + .../phpDocumentor/Reflection/DocBlockTest.php | 337 + vendor/phpspec/prophecy/.gitignore | 4 + vendor/phpspec/prophecy/.travis.yml | 19 + vendor/phpspec/prophecy/CHANGES.md | 122 + vendor/phpspec/prophecy/CONTRIBUTING.md | 21 + vendor/phpspec/prophecy/LICENSE | 23 + vendor/phpspec/prophecy/README.md | 390 + vendor/phpspec/prophecy/composer.json | 40 + vendor/phpspec/prophecy/composer.lock | 731 + .../Argument/ArgumentsWildcardSpec.php | 146 + .../Argument/Token/AnyValueTokenSpec.php | 28 + .../Argument/Token/AnyValuesTokenSpec.php | 28 + .../Argument/Token/ArrayCountTokenSpec.php | 64 + .../Argument/Token/ArrayEntryTokenSpec.php | 229 + .../Token/ArrayEveryEntryTokenSpec.php | 109 + .../Argument/Token/CallbackTokenSpec.php | 42 + .../Argument/Token/ExactValueTokenSpec.php | 155 + .../Token/IdenticalValueTokenSpec.php | 152 + .../Argument/Token/LogicalAndTokenSpec.php | 78 + .../Argument/Token/LogicalNotTokenSpec.php | 65 + .../Argument/Token/ObjectStateTokenSpec.php | 101 + .../Token/StringContainsTokenSpec.php | 49 + .../Prophecy/Argument/Token/TypeTokenSpec.php | 62 + .../prophecy/spec/Prophecy/ArgumentSpec.php | 101 + .../spec/Prophecy/Call/CallCenterSpec.php | 195 + .../prophecy/spec/Prophecy/Call/CallSpec.php | 54 + .../Comparator/ClosureComparatorSpec.php | 39 + .../spec/Prophecy/Comparator/FactorySpec.php | 20 + .../DisableConstructorPatchSpec.php | 59 + .../ClassPatch/HhvmExceptionPatchSpec.php | 37 + .../Doubler/ClassPatch/KeywordPatchSpec.php | 44 + .../Doubler/ClassPatch/MagicCallPatchSpec.php | 76 + .../ClassPatch/ProphecySubjectPatchSpec.php | 83 + .../ReflectionClassNewInstancePatchSpec.php | 47 + .../ClassPatch/SplFileInfoPatchSpec.php | 91 + .../ClassPatch/TraversablePatchSpec.php | 61 + .../spec/Prophecy/Doubler/DoublerSpec.php | 122 + .../Generator/ClassCodeGeneratorSpec.php | 191 + .../Doubler/Generator/ClassCreatorSpec.php | 44 + .../Doubler/Generator/ClassMirrorSpec.php | 610 + .../Generator/Node/ArgumentNodeSpec.php | 62 + .../Doubler/Generator/Node/ClassNodeSpec.php | 154 + .../Doubler/Generator/Node/MethodNodeSpec.php | 138 + .../spec/Prophecy/Doubler/LazyDoubleSpec.php | 96 + .../Prophecy/Doubler/NameGeneratorSpec.php | 72 + .../Call/UnexpectedCallExceptionSpec.php | 32 + .../Doubler/ClassCreatorExceptionSpec.php | 28 + .../Doubler/ClassMirrorExceptionSpec.php | 27 + .../Doubler/ClassNotFoundExceptionSpec.php | 25 + .../Exception/Doubler/DoubleExceptionSpec.php | 14 + .../InterfaceNotFoundExceptionSpec.php | 24 + .../Doubler/MethodNotFoundExceptionSpec.php | 40 + .../Prediction/AggregateExceptionSpec.php | 57 + .../Prediction/NoCallsExceptionSpec.php | 29 + .../UnexpectedCallsCountExceptionSpec.php | 31 + .../UnexpectedCallsExceptionSpec.php | 36 + .../Prophecy/MethodProphecyExceptionSpec.php | 30 + .../Prophecy/ObjectProphecyExceptionSpec.php | 27 + .../Prediction/CallPredictionSpec.php | 42 + .../Prediction/CallTimesPredictionSpec.php | 54 + .../Prediction/CallbackPredictionSpec.php | 36 + .../Prediction/NoCallsPredictionSpec.php | 43 + .../Prophecy/Promise/CallbackPromiseSpec.php | 110 + .../Promise/ReturnArgumentPromiseSpec.php | 41 + .../Prophecy/Promise/ReturnPromiseSpec.php | 61 + .../Prophecy/Promise/ThrowPromiseSpec.php | 58 + .../Prophecy/Prophecy/MethodProphecySpec.php | 384 + .../Prophecy/Prophecy/ObjectProphecySpec.php | 319 + .../spec/Prophecy/Prophecy/RevealerSpec.php | 51 + .../prophecy/spec/Prophecy/ProphetSpec.php | 91 + .../spec/Prophecy/Util/StringUtilSpec.php | 97 + .../prophecy/src/Prophecy/Argument.php | 198 + .../Prophecy/Argument/ArgumentsWildcard.php | 101 + .../Prophecy/Argument/Token/AnyValueToken.php | 52 + .../Argument/Token/AnyValuesToken.php | 52 + .../Argument/Token/ArrayCountToken.php | 86 + .../Argument/Token/ArrayEntryToken.php | 143 + .../Argument/Token/ArrayEveryEntryToken.php | 82 + .../Prophecy/Argument/Token/CallbackToken.php | 75 + .../Argument/Token/ExactValueToken.php | 116 + .../Argument/Token/IdenticalValueToken.php | 74 + .../Argument/Token/LogicalAndToken.php | 80 + .../Argument/Token/LogicalNotToken.php | 73 + .../Argument/Token/ObjectStateToken.php | 104 + .../Argument/Token/StringContainsToken.php | 67 + .../Argument/Token/TokenInterface.php | 43 + .../src/Prophecy/Argument/Token/TypeToken.php | 76 + .../prophecy/src/Prophecy/Call/Call.php | 127 + .../prophecy/src/Prophecy/Call/CallCenter.php | 152 + .../Prophecy/Comparator/ClosureComparator.php | 42 + .../src/Prophecy/Comparator/Factory.php | 46 + .../src/Prophecy/Doubler/CachedDoubler.php | 68 + .../ClassPatch/ClassPatchInterface.php | 48 + .../ClassPatch/DisableConstructorPatch.php | 72 + .../Doubler/ClassPatch/HhvmExceptionPatch.php | 63 + .../Doubler/ClassPatch/KeywordPatch.php | 135 + .../Doubler/ClassPatch/MagicCallPatch.php | 73 + .../ClassPatch/ProphecySubjectPatch.php | 98 + .../ReflectionClassNewInstancePatch.php | 57 + .../Doubler/ClassPatch/SplFileInfoPatch.php | 85 + .../Doubler/ClassPatch/TraversablePatch.php | 83 + .../src/Prophecy/Doubler/DoubleInterface.php | 22 + .../prophecy/src/Prophecy/Doubler/Doubler.php | 146 + .../Doubler/Generator/ClassCodeGenerator.php | 92 + .../Doubler/Generator/ClassCreator.php | 67 + .../Doubler/Generator/ClassMirror.php | 210 + .../Doubler/Generator/Node/ArgumentNode.php | 75 + .../Doubler/Generator/Node/ClassNode.php | 130 + .../Doubler/Generator/Node/MethodNode.php | 177 + .../Doubler/Generator/ReflectionInterface.php | 22 + .../src/Prophecy/Doubler/LazyDouble.php | 127 + .../src/Prophecy/Doubler/NameGenerator.php | 52 + .../Call/UnexpectedCallException.php | 40 + .../Doubler/ClassCreatorException.php | 31 + .../Doubler/ClassMirrorException.php | 31 + .../Doubler/ClassNotFoundException.php | 33 + .../Exception/Doubler/DoubleException.php | 18 + .../Exception/Doubler/DoublerException.php | 18 + .../Doubler/InterfaceNotFoundException.php | 20 + .../Doubler/MethodNotFoundException.php | 60 + .../Doubler/ReturnByReferenceException.php | 41 + .../src/Prophecy/Exception/Exception.php | 26 + .../Exception/InvalidArgumentException.php | 16 + .../Prediction/AggregateException.php | 50 + .../Prediction/FailedPredictionException.php | 24 + .../Exception/Prediction/NoCallsException.php | 18 + .../Prediction/PredictionException.php | 18 + .../UnexpectedCallsCountException.php | 31 + .../Prediction/UnexpectedCallsException.php | 32 + .../Prophecy/MethodProphecyException.php | 34 + .../Prophecy/ObjectProphecyException.php | 34 + .../Exception/Prophecy/ProphecyException.php | 18 + .../Prophecy/Prediction/CallPrediction.php | 86 + .../Prediction/CallTimesPrediction.php | 107 + .../Prediction/CallbackPrediction.php | 65 + .../Prophecy/Prediction/NoCallsPrediction.php | 68 + .../Prediction/PredictionInterface.php | 37 + .../src/Prophecy/Promise/CallbackPromise.php | 66 + .../src/Prophecy/Promise/PromiseInterface.php | 35 + .../Promise/ReturnArgumentPromise.php | 61 + .../src/Prophecy/Promise/ReturnPromise.php | 55 + .../src/Prophecy/Promise/ThrowPromise.php | 91 + .../src/Prophecy/Prophecy/MethodProphecy.php | 437 + .../src/Prophecy/Prophecy/ObjectProphecy.php | 279 + .../Prophecy/Prophecy/ProphecyInterface.php | 27 + .../Prophecy/ProphecySubjectInterface.php | 34 + .../src/Prophecy/Prophecy/Revealer.php | 44 + .../Prophecy/Prophecy/RevealerInterface.php | 29 + .../phpspec/prophecy/src/Prophecy/Prophet.php | 134 + .../prophecy/src/Prophecy/Util/ExportUtil.php | 185 + .../prophecy/src/Prophecy/Util/StringUtil.php | 89 + .../phpunit/php-code-coverage/.gitattributes | 1 + vendor/phpunit/php-code-coverage/.gitignore | 11 + vendor/phpunit/php-code-coverage/.travis.yml | 20 + .../phpunit/php-code-coverage/CONTRIBUTING.md | 5 + .../php-code-coverage/ChangeLog-2.2.md | 56 + vendor/phpunit/php-code-coverage/LICENSE | 33 + vendor/phpunit/php-code-coverage/README.md | 50 + vendor/phpunit/php-code-coverage/build.xml | 41 + .../php-code-coverage/build/travis-ci.xml | 21 + .../phpunit/php-code-coverage/composer.json | 50 + .../php-code-coverage/phpunit.xml.dist | 23 + .../php-code-coverage/scripts/auto_append.php | 5 + .../scripts/auto_prepend.php | 10 + .../php-code-coverage/src/CodeCoverage.php | 920 + .../src/CodeCoverage/Driver.php | 47 + .../src/CodeCoverage/Driver/HHVM.php | 26 + .../src/CodeCoverage/Driver/PHPDBG.php | 105 + .../src/CodeCoverage/Driver/Xdebug.php | 97 + .../src/CodeCoverage/Exception.php | 18 + .../Exception/UnintentionallyCoveredCode.php | 18 + .../src/CodeCoverage/Filter.php | 293 + .../src/CodeCoverage/Report/Clover.php | 284 + .../src/CodeCoverage/Report/Crap4j.php | 164 + .../src/CodeCoverage/Report/Factory.php | 242 + .../src/CodeCoverage/Report/HTML.php | 182 + .../src/CodeCoverage/Report/HTML/Renderer.php | 271 + .../Report/HTML/Renderer/Dashboard.php | 295 + .../Report/HTML/Renderer/Directory.php | 97 + .../Report/HTML/Renderer/File.php | 556 + .../Renderer/Template/coverage_bar.html.dist | 5 + .../Renderer/Template/css/bootstrap.min.css | 5 + .../HTML/Renderer/Template/css/nv.d3.min.css | 1 + .../HTML/Renderer/Template/css/style.css | 122 + .../Renderer/Template/dashboard.html.dist | 284 + .../Renderer/Template/directory.html.dist | 61 + .../Template/directory_item.html.dist | 13 + .../HTML/Renderer/Template/file.html.dist | 90 + .../Renderer/Template/file_item.html.dist | 14 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../Renderer/Template/js/bootstrap.min.js | 7 + .../HTML/Renderer/Template/js/d3.min.js | 5 + .../HTML/Renderer/Template/js/holder.min.js | 12 + .../Renderer/Template/js/html5shiv.min.js | 4 + .../HTML/Renderer/Template/js/jquery.min.js | 5 + .../HTML/Renderer/Template/js/nv.d3.min.js | 8 + .../HTML/Renderer/Template/js/respond.min.js | 5 + .../Renderer/Template/method_item.html.dist | 11 + .../src/CodeCoverage/Report/Node.php | 339 + .../CodeCoverage/Report/Node/Directory.php | 478 + .../src/CodeCoverage/Report/Node/File.php | 679 + .../src/CodeCoverage/Report/Node/Iterator.php | 105 + .../src/CodeCoverage/Report/PHP.php | 50 + .../src/CodeCoverage/Report/Text.php | 246 + .../src/CodeCoverage/Report/XML.php | 234 + .../src/CodeCoverage/Report/XML/Directory.php | 16 + .../src/CodeCoverage/Report/XML/File.php | 73 + .../CodeCoverage/Report/XML/File/Coverage.php | 66 + .../CodeCoverage/Report/XML/File/Method.php | 58 + .../CodeCoverage/Report/XML/File/Report.php | 72 + .../src/CodeCoverage/Report/XML/File/Unit.php | 97 + .../src/CodeCoverage/Report/XML/Node.php | 89 + .../src/CodeCoverage/Report/XML/Project.php | 63 + .../src/CodeCoverage/Report/XML/Tests.php | 45 + .../src/CodeCoverage/Report/XML/Totals.php | 140 + .../src/CodeCoverage/Util.php | 45 + .../Util/InvalidArgumentHelper.php | 39 + .../tests/PHP/CodeCoverage/FilterTest.php | 281 + .../PHP/CodeCoverage/Report/CloverTest.php | 66 + .../PHP/CodeCoverage/Report/FactoryTest.php | 222 + .../tests/PHP/CodeCoverage/UtilTest.php | 30 + .../tests/PHP/CodeCoverageTest.php | 487 + .../php-code-coverage/tests/TestCase.php | 311 + .../tests/_files/BankAccount-clover.xml | 26 + .../tests/_files/BankAccount.php | 33 + .../tests/_files/BankAccountTest.php | 66 + .../_files/CoverageClassExtendedTest.php | 12 + .../tests/_files/CoverageClassTest.php | 12 + .../CoverageFunctionParenthesesTest.php | 11 + ...erageFunctionParenthesesWhitespaceTest.php | 11 + .../tests/_files/CoverageFunctionTest.php | 11 + .../CoverageMethodOneLineAnnotationTest.php | 11 + .../_files/CoverageMethodParenthesesTest.php | 12 + ...overageMethodParenthesesWhitespaceTest.php | 12 + .../tests/_files/CoverageMethodTest.php | 12 + .../tests/_files/CoverageNoneTest.php | 9 + .../tests/_files/CoverageNotPrivateTest.php | 12 + .../tests/_files/CoverageNotProtectedTest.php | 12 + .../tests/_files/CoverageNotPublicTest.php | 12 + .../tests/_files/CoverageNothingTest.php | 13 + .../tests/_files/CoveragePrivateTest.php | 12 + .../tests/_files/CoverageProtectedTest.php | 12 + .../tests/_files/CoveragePublicTest.php | 12 + .../CoverageTwoDefaultClassAnnotations.php | 18 + .../tests/_files/CoveredClass.php | 36 + .../tests/_files/CoveredFunction.php | 4 + .../NamespaceCoverageClassExtendedTest.php | 12 + .../_files/NamespaceCoverageClassTest.php | 12 + ...NamespaceCoverageCoversClassPublicTest.php | 15 + .../NamespaceCoverageCoversClassTest.php | 20 + .../_files/NamespaceCoverageMethodTest.php | 12 + .../NamespaceCoverageNotPrivateTest.php | 12 + .../NamespaceCoverageNotProtectedTest.php | 12 + .../_files/NamespaceCoverageNotPublicTest.php | 12 + .../_files/NamespaceCoveragePrivateTest.php | 12 + .../_files/NamespaceCoverageProtectedTest.php | 12 + .../_files/NamespaceCoveragePublicTest.php | 12 + .../tests/_files/NamespaceCoveredClass.php | 38 + .../_files/NotExistingCoveredElementTest.php | 24 + .../class-with-anonymous-function-clover.xml | 22 + .../tests/_files/ignored-lines-clover.xml | 17 + ...urce_with_class_and_anonymous_function.php | 19 + .../tests/_files/source_with_ignore.php | 37 + .../tests/_files/source_with_namespace.php | 20 + .../source_with_oneline_annotations.php | 36 + .../tests/_files/source_without_ignore.php | 4 + .../tests/_files/source_without_namespace.php | 18 + .../phpunit/php-file-iterator/.gitattributes | 1 + vendor/phpunit/php-file-iterator/.gitignore | 7 + vendor/phpunit/php-file-iterator/ChangeLog.md | 10 + vendor/phpunit/php-file-iterator/LICENSE | 33 + vendor/phpunit/php-file-iterator/README.md | 12 + .../phpunit/php-file-iterator/composer.json | 36 + .../phpunit/php-file-iterator/src/Facade.php | 123 + .../phpunit/php-file-iterator/src/Factory.php | 91 + .../php-file-iterator/src/Iterator.php | 158 + .../phpunit/php-text-template/.gitattributes | 1 + vendor/phpunit/php-text-template/.gitignore | 5 + vendor/phpunit/php-text-template/LICENSE | 33 + vendor/phpunit/php-text-template/README.md | 14 + .../phpunit/php-text-template/composer.json | 29 + .../php-text-template/src/Template.php | 135 + vendor/phpunit/php-timer/.gitattributes | 1 + vendor/phpunit/php-timer/.gitignore | 7 + vendor/phpunit/php-timer/.travis.yml | 22 + vendor/phpunit/php-timer/LICENSE | 33 + vendor/phpunit/php-timer/README.md | 47 + vendor/phpunit/php-timer/composer.json | 29 + vendor/phpunit/php-timer/src/Timer.php | 107 + vendor/phpunit/php-timer/tests/TimerTest.php | 101 + .../phpunit/php-token-stream/.gitattributes | 1 + vendor/phpunit/php-token-stream/.gitignore | 4 + vendor/phpunit/php-token-stream/.travis.yml | 35 + vendor/phpunit/php-token-stream/LICENSE | 33 + vendor/phpunit/php-token-stream/README.md | 13 + vendor/phpunit/php-token-stream/build.xml | 33 + .../php-token-stream/build/phpunit.xml | 17 + vendor/phpunit/php-token-stream/composer.json | 34 + vendor/phpunit/php-token-stream/src/Token.php | 846 + .../php-token-stream/src/Token/Stream.php | 606 + .../src/Token/Stream/CachingFactory.php | 51 + .../tests/Token/ClassTest.php | 112 + .../tests/Token/ClosureTest.php | 85 + .../tests/Token/FunctionTest.php | 146 + .../tests/Token/IncludeTest.php | 73 + .../tests/Token/InterfaceTest.php | 191 + .../tests/Token/NamespaceTest.php | 80 + .../php-token-stream/tests/TokenTest.php | 42 + .../_fixture/classExtendsNamespacedClass.php | 10 + .../tests/_fixture/classInNamespace.php | 6 + .../tests/_fixture/classInScopedNamespace.php | 9 + ...h_method_that_declares_anonymous_class.php | 15 + ..._method_that_declares_anonymous_class2.php | 16 + .../tests/_fixture/closure.php | 7 + .../tests/_fixture/issue19.php | 3 + .../tests/_fixture/issue30.php | 8 + ...tipleNamespacesWithOneClassUsingBraces.php | 12 + ...espacesWithOneClassUsingNonBraceSyntax.php | 14 + .../tests/_fixture/source.php | 36 + .../tests/_fixture/source2.php | 6 + .../tests/_fixture/source3.php | 14 + .../tests/_fixture/source4.php | 30 + .../tests/_fixture/source5.php | 5 + .../php-token-stream/tests/bootstrap.php | 7 + .../phpunit-mock-objects/.gitattributes | 1 + .../phpunit/phpunit-mock-objects/.gitignore | 8 + .../phpunit/phpunit-mock-objects/.travis.yml | 26 + .../phpunit-mock-objects/CONTRIBUTING.md | 5 + vendor/phpunit/phpunit-mock-objects/LICENSE | 33 + vendor/phpunit/phpunit-mock-objects/README.md | 21 + vendor/phpunit/phpunit-mock-objects/build.xml | 42 + .../phpunit-mock-objects/build/travis-ci.xml | 12 + .../phpunit-mock-objects/composer.json | 50 + .../phpunit-mock-objects/phpunit.xml.dist | 22 + .../Framework/MockObject/Builder/Identity.php | 30 + .../MockObject/Builder/InvocationMocker.php | 255 + .../Framework/MockObject/Builder/Match.php | 26 + .../MockObject/Builder/MethodNameMatch.php | 28 + .../MockObject/Builder/Namespace.php | 39 + .../MockObject/Builder/ParametersMatch.php | 49 + .../src/Framework/MockObject/Builder/Stub.php | 26 + .../Exception/BadMethodCallException.php | 16 + .../MockObject/Exception/Exception.php | 18 + .../MockObject/Exception/RuntimeException.php | 16 + .../src/Framework/MockObject/Generator.php | 1120 ++ .../Generator/mocked_class.tpl.dist | 36 + .../Generator/mocked_class_method.tpl.dist | 7 + .../Generator/mocked_clone.tpl.dist | 4 + .../Generator/mocked_method.tpl.dist | 22 + .../Generator/mocked_static_method.tpl.dist | 5 + .../Generator/proxied_method.tpl.dist | 22 + .../MockObject/Generator/trait_class.tpl.dist | 4 + .../Generator/unmocked_clone.tpl.dist | 5 + .../MockObject/Generator/wsdl_class.tpl.dist | 7 + .../MockObject/Generator/wsdl_method.tpl.dist | 4 + .../src/Framework/MockObject/Invocation.php | 18 + .../MockObject/Invocation/Object.php | 35 + .../MockObject/Invocation/Static.php | 152 + .../Framework/MockObject/InvocationMocker.php | 156 + .../src/Framework/MockObject/Invokable.php | 39 + .../src/Framework/MockObject/Matcher.php | 271 + .../MockObject/Matcher/AnyInvokedCount.php | 32 + .../MockObject/Matcher/AnyParameters.php | 34 + .../Matcher/ConsecutiveParameters.php | 123 + .../MockObject/Matcher/Invocation.php | 48 + .../MockObject/Matcher/InvokedAtIndex.php | 86 + .../Matcher/InvokedAtLeastCount.php | 57 + .../MockObject/Matcher/InvokedAtLeastOnce.php | 45 + .../MockObject/Matcher/InvokedAtMostCount.php | 57 + .../MockObject/Matcher/InvokedCount.php | 109 + .../MockObject/Matcher/InvokedRecorder.php | 67 + .../MockObject/Matcher/MethodName.php | 66 + .../MockObject/Matcher/Parameters.php | 127 + .../Matcher/StatelessInvocation.php | 56 + .../src/Framework/MockObject/MockBuilder.php | 322 + .../src/Framework/MockObject/MockObject.php | 47 + .../src/Framework/MockObject/Stub.php | 31 + .../MockObject/Stub/ConsecutiveCalls.php | 48 + .../Framework/MockObject/Stub/Exception.php | 41 + .../MockObject/Stub/MatcherCollection.php | 26 + .../src/Framework/MockObject/Stub/Return.php | 41 + .../MockObject/Stub/ReturnArgument.php | 38 + .../MockObject/Stub/ReturnCallback.php | 51 + .../Framework/MockObject/Stub/ReturnSelf.php | 34 + .../MockObject/Stub/ReturnValueMap.php | 47 + .../src/Framework/MockObject/Verifiable.php | 25 + .../tests/GeneratorTest.php | 200 + .../tests/MockBuilderTest.php | 107 + .../tests/MockObject/232.phpt | 129 + .../MockObject/Invocation/ObjectTest.php | 85 + .../MockObject/Invocation/StaticTest.php | 54 + .../Matcher/ConsecutiveParametersTest.php | 45 + .../tests/MockObject/abstract_class.phpt | 143 + .../tests/MockObject/class.phpt | 121 + .../MockObject/class_call_parent_clone.phpt | 73 + .../class_call_parent_constructor.phpt | 72 + .../class_dont_call_parent_clone.phpt | 72 + .../class_dont_call_parent_constructor.phpt | 72 + ...ing_interface_call_parent_constructor.phpt | 77 + ...nterface_dont_call_parent_constructor.phpt | 77 + .../tests/MockObject/class_partial.phpt | 99 + .../class_with_method_named_method.phpt | 88 + ...s_with_method_with_variadic_arguments.phpt | 99 + .../tests/MockObject/interface.phpt | 93 + .../invocation_object_clone_object.phpt | 122 + .../tests/MockObject/namespaced_class.phpt | 123 + .../namespaced_class_call_parent_clone.phpt | 75 + ...espaced_class_call_parent_constructor.phpt | 74 + ...mespaced_class_dont_call_parent_clone.phpt | 74 + ...ed_class_dont_call_parent_constructor.phpt | 74 + ...ing_interface_call_parent_constructor.phpt | 79 + ...nterface_dont_call_parent_constructor.phpt | 79 + .../MockObject/namespaced_class_partial.phpt | 101 + .../MockObject/namespaced_interface.phpt | 95 + .../tests/MockObject/nonexistent_class.phpt | 70 + .../nonexistent_class_with_namespace.phpt | 78 + ...ith_namespace_starting_with_separator.phpt | 78 + .../tests/MockObject/proxy.phpt | 117 + .../MockObject/scalar_type_declarations.phpt | 99 + .../tests/MockObject/wsdl_class.phpt | 37 + .../MockObject/wsdl_class_namespace.phpt | 39 + .../tests/MockObject/wsdl_class_partial.phpt | 30 + .../tests/MockObjectTest.php | 842 + .../tests/ProxyObjectTest.php | 40 + .../tests/_fixture/AbstractMockTestClass.php | 10 + .../tests/_fixture/AbstractTrait.php | 15 + .../tests/_fixture/AnInterface.php | 5 + .../tests/_fixture/AnotherInterface.php | 5 + .../tests/_fixture/Bar.php | 8 + .../ClassThatImplementsSerializable.php | 15 + .../tests/_fixture/ClassWithStaticMethod.php | 7 + .../tests/_fixture/Foo.php | 8 + .../tests/_fixture/FunctionCallback.php | 9 + .../tests/_fixture/GoogleSearch.wsdl | 198 + .../_fixture/InterfaceWithStaticMethod.php | 5 + .../tests/_fixture/MethodCallback.php | 21 + .../_fixture/MethodCallbackByReference.php | 13 + .../tests/_fixture/MockTestInterface.php | 6 + .../tests/_fixture/Mockable.php | 28 + .../tests/_fixture/PartialMockTestClass.php | 18 + .../tests/_fixture/SingletonClass.php | 28 + .../tests/_fixture/SomeClass.php | 13 + .../tests/_fixture/StaticMockTestClass.php | 12 + .../_fixture/TraversableMockTestInterface.php | 4 + .../phpunit-mock-objects/tests/bootstrap.php | 3 + vendor/phpunit/phpunit/.gitattributes | 3 + vendor/phpunit/phpunit/.gitignore | 22 + vendor/phpunit/phpunit/.php_cs | 69 + vendor/phpunit/phpunit/.travis.yml | 41 + vendor/phpunit/phpunit/CODE_OF_CONDUCT.md | 14 + vendor/phpunit/phpunit/CONTRIBUTING.md | 67 + vendor/phpunit/phpunit/ChangeLog-4.0.md | 176 + vendor/phpunit/phpunit/ChangeLog-4.1.md | 73 + vendor/phpunit/phpunit/ChangeLog-4.2.md | 56 + vendor/phpunit/phpunit/ChangeLog-4.3.md | 54 + vendor/phpunit/phpunit/ChangeLog-4.4.md | 57 + vendor/phpunit/phpunit/ChangeLog-4.5.md | 28 + vendor/phpunit/phpunit/ChangeLog-4.6.md | 95 + vendor/phpunit/phpunit/ChangeLog-4.7.md | 71 + vendor/phpunit/phpunit/ChangeLog-4.8.md | 140 + vendor/phpunit/phpunit/LICENSE | 33 + vendor/phpunit/phpunit/README.md | 46 + vendor/phpunit/phpunit/build.xml | 283 + vendor/phpunit/phpunit/build/bin/phpab | 897 + .../phpunit/build/binary-phar-autoload.php.in | 34 + vendor/phpunit/phpunit/build/ca.pem | 25 + .../build/library-phar-autoload.php.in | 9 + .../phpunit/phpunit/build/phar-manifest.php | 27 + vendor/phpunit/phpunit/build/phar-version.php | 22 + .../phpunit/phpunit/build/travis-ci-fail.xml | 16 + vendor/phpunit/phpunit/composer.json | 69 + vendor/phpunit/phpunit/phpdox.xml.dist | 23 + vendor/phpunit/phpunit/phpunit | 47 + vendor/phpunit/phpunit/phpunit.xml.dist | 34 + vendor/phpunit/phpunit/phpunit.xsd | 261 + vendor/phpunit/phpunit/src/Exception.php | 18 + .../phpunit/src/Extensions/GroupTestSuite.php | 60 + .../phpunit/src/Extensions/PhptTestCase.php | 241 + .../phpunit/src/Extensions/PhptTestSuite.php | 40 + .../phpunit/src/Extensions/RepeatedTest.php | 90 + .../phpunit/src/Extensions/TestDecorator.php | 109 + .../phpunit/src/Extensions/TicketListener.php | 204 + .../phpunit/phpunit/src/Framework/Assert.php | 3165 ++++ .../src/Framework/Assert/Functions.php | 2569 +++ .../src/Framework/AssertionFailedError.php | 27 + .../src/Framework/BaseTestListener.php | 55 + .../src/Framework/CodeCoverageException.php | 16 + .../phpunit/src/Framework/Constraint.php | 153 + .../phpunit/src/Framework/Constraint/And.php | 125 + .../src/Framework/Constraint/ArrayHasKey.php | 82 + .../src/Framework/Constraint/ArraySubset.php | 85 + .../src/Framework/Constraint/Attribute.php | 87 + .../src/Framework/Constraint/Callback.php | 59 + .../Constraint/ClassHasAttribute.php | 82 + .../Constraint/ClassHasStaticAttribute.php | 56 + .../src/Framework/Constraint/Composite.php | 70 + .../src/Framework/Constraint/Count.php | 104 + .../src/Framework/Constraint/Exception.php | 88 + .../Framework/Constraint/ExceptionCode.php | 69 + .../Framework/Constraint/ExceptionMessage.php | 69 + .../Constraint/ExceptionMessageRegExp.php | 77 + .../src/Framework/Constraint/FileExists.php | 60 + .../src/Framework/Constraint/GreaterThan.php | 55 + .../src/Framework/Constraint/IsAnything.php | 62 + .../src/Framework/Constraint/IsEmpty.php | 66 + .../src/Framework/Constraint/IsEqual.php | 179 + .../src/Framework/Constraint/IsFalse.php | 40 + .../src/Framework/Constraint/IsIdentical.php | 132 + .../src/Framework/Constraint/IsInstanceOf.php | 94 + .../src/Framework/Constraint/IsJson.php | 69 + .../src/Framework/Constraint/IsNull.php | 40 + .../src/Framework/Constraint/IsTrue.php | 40 + .../src/Framework/Constraint/IsType.php | 143 + .../src/Framework/Constraint/JsonMatches.php | 71 + .../JsonMatches/ErrorMessageProvider.php | 69 + .../src/Framework/Constraint/LessThan.php | 55 + .../phpunit/src/Framework/Constraint/Not.php | 160 + .../Constraint/ObjectHasAttribute.php | 35 + .../phpunit/src/Framework/Constraint/Or.php | 117 + .../src/Framework/Constraint/PCREMatch.php | 63 + .../src/Framework/Constraint/SameSize.php | 28 + .../Framework/Constraint/StringContains.php | 81 + .../Framework/Constraint/StringEndsWith.php | 55 + .../Framework/Constraint/StringMatches.php | 101 + .../Framework/Constraint/StringStartsWith.php | 55 + .../Constraint/TraversableContains.php | 127 + .../Constraint/TraversableContainsOnly.php | 95 + .../phpunit/src/Framework/Constraint/Xor.php | 122 + .../phpunit/phpunit/src/Framework/Error.php | 34 + .../src/Framework/Error/Deprecated.php | 24 + .../phpunit/src/Framework/Error/Notice.php | 24 + .../phpunit/src/Framework/Error/Warning.php | 24 + .../phpunit/src/Framework/Exception.php | 77 + .../src/Framework/ExceptionWrapper.php | 91 + .../Framework/ExpectationFailedException.php | 41 + .../phpunit/src/Framework/IncompleteTest.php | 19 + .../src/Framework/IncompleteTestCase.php | 84 + .../src/Framework/IncompleteTestError.php | 19 + .../Framework/InvalidCoversTargetError.php | 19 + .../InvalidCoversTargetException.php | 16 + .../phpunit/src/Framework/OutputError.php | 19 + .../phpunit/src/Framework/RiskyTest.php | 19 + .../phpunit/src/Framework/RiskyTestError.php | 19 + .../phpunit/src/Framework/SelfDescribing.php | 24 + .../phpunit/src/Framework/SkippedTest.php | 18 + .../phpunit/src/Framework/SkippedTestCase.php | 82 + .../src/Framework/SkippedTestError.php | 19 + .../src/Framework/SkippedTestSuiteError.php | 19 + .../phpunit/src/Framework/SyntheticError.php | 80 + vendor/phpunit/phpunit/src/Framework/Test.php | 26 + .../phpunit/src/Framework/TestCase.php | 2205 +++ .../phpunit/src/Framework/TestFailure.php | 167 + .../phpunit/src/Framework/TestListener.php | 99 + .../phpunit/src/Framework/TestResult.php | 1128 ++ .../phpunit/src/Framework/TestSuite.php | 1036 ++ .../src/Framework/TestSuite/DataProvider.php | 27 + .../UnintentionallyCoveredCodeError.php | 19 + .../phpunit/phpunit/src/Framework/Warning.php | 81 + .../phpunit/src/Runner/BaseTestRunner.php | 140 + .../phpunit/phpunit/src/Runner/Exception.php | 16 + .../phpunit/src/Runner/Filter/Factory.php | 51 + .../phpunit/src/Runner/Filter/Group.php | 59 + .../src/Runner/Filter/Group/Exclude.php | 20 + .../src/Runner/Filter/Group/Include.php | 20 + .../phpunit/src/Runner/Filter/Test.php | 116 + .../src/Runner/StandardTestSuiteLoader.php | 118 + .../phpunit/src/Runner/TestSuiteLoader.php | 32 + vendor/phpunit/phpunit/src/Runner/Version.php | 75 + vendor/phpunit/phpunit/src/TextUI/Command.php | 1016 + .../phpunit/src/TextUI/ResultPrinter.php | 653 + .../phpunit/phpunit/src/TextUI/TestRunner.php | 1031 + vendor/phpunit/phpunit/src/Util/Blacklist.php | 115 + .../phpunit/src/Util/Configuration.php | 1155 ++ .../phpunit/phpunit/src/Util/ErrorHandler.php | 117 + .../phpunit/phpunit/src/Util/Fileloader.php | 72 + .../phpunit/phpunit/src/Util/Filesystem.php | 42 + vendor/phpunit/phpunit/src/Util/Filter.php | 107 + vendor/phpunit/phpunit/src/Util/Getopt.php | 163 + .../phpunit/phpunit/src/Util/GlobalState.php | 192 + .../src/Util/InvalidArgumentHelper.php | 41 + vendor/phpunit/phpunit/src/Util/Log/JSON.php | 244 + vendor/phpunit/phpunit/src/Util/Log/JUnit.php | 454 + vendor/phpunit/phpunit/src/Util/Log/TAP.php | 257 + vendor/phpunit/phpunit/src/Util/PHP.php | 227 + .../phpunit/phpunit/src/Util/PHP/Default.php | 84 + .../Util/PHP/Template/TestCaseMethod.tpl.dist | 89 + .../phpunit/phpunit/src/Util/PHP/Windows.php | 106 + vendor/phpunit/phpunit/src/Util/Printer.php | 172 + vendor/phpunit/phpunit/src/Util/Regex.php | 26 + vendor/phpunit/phpunit/src/Util/String.php | 71 + vendor/phpunit/phpunit/src/Util/Test.php | 1084 ++ .../src/Util/TestDox/NamePrettifier.php | 142 + .../src/Util/TestDox/ResultPrinter.php | 339 + .../src/Util/TestDox/ResultPrinter/HTML.php | 80 + .../src/Util/TestDox/ResultPrinter/Text.php | 54 + .../phpunit/src/Util/TestSuiteIterator.php | 103 + vendor/phpunit/phpunit/src/Util/Type.php | 38 + vendor/phpunit/phpunit/src/Util/XML.php | 932 + .../tests/Extensions/PhptTestCaseTest.php | 36 + .../tests/Extensions/RepeatedTestTest.php | 64 + vendor/phpunit/phpunit/tests/Fail/fail.phpt | 5 + .../phpunit/tests/Framework/AssertTest.php | 4130 ++++ .../tests/Framework/BaseTestListenerTest.php | 34 + .../tests/Framework/Constraint/CountTest.php | 63 + .../Constraint/ExceptionMessageRegExpTest.php | 56 + .../Constraint/ExceptionMessageTest.php | 52 + .../JsonMatches/ErrorMessageProviderTest.php | 83 + .../Framework/Constraint/JsonMatchesTest.php | 48 + .../tests/Framework/ConstraintTest.php | 3489 ++++ .../phpunit/tests/Framework/SuiteTest.php | 242 + .../phpunit/tests/Framework/TestCaseTest.php | 550 + .../tests/Framework/TestFailureTest.php | 27 + .../tests/Framework/TestImplementorTest.php | 30 + .../tests/Framework/TestListenerTest.php | 108 + .../phpunit/tests/Regression/1021.phpt | 19 + .../tests/Regression/1021/Issue1021Test.php | 23 + .../phpunit/phpunit/tests/Regression/523.phpt | 19 + .../tests/Regression/523/Issue523Test.php | 13 + .../phpunit/phpunit/tests/Regression/578.phpt | 37 + .../tests/Regression/578/Issue578Test.php | 20 + .../phpunit/phpunit/tests/Regression/684.phpt | 25 + .../tests/Regression/684/Issue684Test.php | 4 + .../phpunit/phpunit/tests/Regression/783.phpt | 21 + .../tests/Regression/783/ChildSuite.php | 15 + .../phpunit/tests/Regression/783/OneTest.php | 10 + .../tests/Regression/783/ParentSuite.php | 13 + .../phpunit/tests/Regression/783/TwoTest.php | 10 + .../phpunit/tests/Regression/GitHub/1149.phpt | 20 + .../Regression/GitHub/1149/Issue1149Test.php | 18 + .../phpunit/tests/Regression/GitHub/1216.phpt | 25 + .../Regression/GitHub/1216/Issue1216Test.php | 8 + .../Regression/GitHub/1216/bootstrap1216.php | 2 + .../Regression/GitHub/1216/phpunit1216.xml | 8 + .../phpunit/tests/Regression/GitHub/1265.phpt | 21 + .../Regression/GitHub/1265/Issue1265Test.php | 8 + .../Regression/GitHub/1265/phpunit1265.xml | 2 + .../phpunit/tests/Regression/GitHub/1330.phpt | 24 + .../Regression/GitHub/1330/Issue1330Test.php | 8 + .../Regression/GitHub/1330/phpunit1330.xml | 5 + .../phpunit/tests/Regression/GitHub/1335.phpt | 21 + .../Regression/GitHub/1335/Issue1335Test.php | 67 + .../Regression/GitHub/1335/bootstrap1335.php | 13 + .../phpunit/tests/Regression/GitHub/1337.phpt | 21 + .../Regression/GitHub/1337/Issue1337Test.php | 19 + .../phpunit/tests/Regression/GitHub/1348.phpt | 36 + .../Regression/GitHub/1348/Issue1348Test.php | 14 + .../phpunit/tests/Regression/GitHub/1351.phpt | 48 + .../GitHub/1351/ChildProcessClass1351.php | 4 + .../Regression/GitHub/1351/Issue1351Test.php | 48 + .../phpunit/tests/Regression/GitHub/1374.phpt | 21 + .../Regression/GitHub/1374/Issue1374Test.php | 21 + .../phpunit/tests/Regression/GitHub/1437.phpt | 28 + .../Regression/GitHub/1437/Issue1437Test.php | 9 + .../phpunit/tests/Regression/GitHub/1468.phpt | 22 + .../Regression/GitHub/1468/Issue1468Test.php | 11 + .../phpunit/tests/Regression/GitHub/1471.phpt | 28 + .../Regression/GitHub/1471/Issue1471Test.php | 12 + .../phpunit/tests/Regression/GitHub/1472.phpt | 26 + .../Regression/GitHub/1472/Issue1472Test.php | 21 + .../phpunit/tests/Regression/GitHub/1570.phpt | 21 + .../Regression/GitHub/1570/Issue1570Test.php | 8 + .../phpunit/tests/Regression/GitHub/244.phpt | 32 + .../Regression/GitHub/244/Issue244Test.php | 55 + .../phpunit/tests/Regression/GitHub/322.phpt | 26 + .../Regression/GitHub/322/Issue322Test.php | 17 + .../Regression/GitHub/322/phpunit322.xml | 11 + .../phpunit/tests/Regression/GitHub/433.phpt | 31 + .../Regression/GitHub/433/Issue433Test.php | 21 + .../phpunit/tests/Regression/GitHub/445.phpt | 32 + .../Regression/GitHub/445/Issue445Test.php | 21 + .../phpunit/tests/Regression/GitHub/498.phpt | 29 + .../Regression/GitHub/498/Issue498Test.php | 44 + .../phpunit/tests/Regression/GitHub/503.phpt | 33 + .../Regression/GitHub/503/Issue503Test.php | 11 + .../phpunit/tests/Regression/GitHub/581.phpt | 42 + .../Regression/GitHub/581/Issue581Test.php | 11 + .../phpunit/tests/Regression/GitHub/74.phpt | 28 + .../Regression/GitHub/74/Issue74Test.php | 9 + .../Regression/GitHub/74/NewException.php | 4 + .../phpunit/tests/Regression/GitHub/765.phpt | 26 + .../Regression/GitHub/765/Issue765Test.php | 22 + .../phpunit/tests/Regression/GitHub/797.phpt | 22 + .../Regression/GitHub/797/Issue797Test.php | 10 + .../Regression/GitHub/797/bootstrap797.php | 6 + .../phpunit/tests/Regression/GitHub/863.phpt | 24 + .../tests/Regression/GitHub/873-php5.phpt | 22 + .../tests/Regression/GitHub/873-php7.phpt | 22 + .../Regression/GitHub/873/Issue873Test.php | 9 + .../tests/Runner/BaseTestRunnerTest.php | 22 + .../tests/TextUI/abstract-test-class.phpt | 25 + .../phpunit/tests/TextUI/colors-always.phpt | 19 + .../tests/TextUI/concrete-test-class.phpt | 19 + .../tests/TextUI/custom-printer-debug.phpt | 27 + .../tests/TextUI/custom-printer-verbose.phpt | 32 + .../tests/TextUI/dataprovider-debug.phpt | 34 + .../dataprovider-log-xml-isolation.phpt | 47 + .../tests/TextUI/dataprovider-log-xml.phpt | 46 + .../tests/TextUI/dataprovider-testdox.phpt | 17 + .../phpunit/phpunit/tests/TextUI/debug.phpt | 26 + .../tests/TextUI/default-isolation.phpt | 20 + .../phpunit/phpunit/tests/TextUI/default.phpt | 19 + .../tests/TextUI/dependencies-isolation.phpt | 40 + .../phpunit/tests/TextUI/dependencies.phpt | 39 + .../tests/TextUI/dependencies2-isolation.phpt | 20 + .../phpunit/tests/TextUI/dependencies2.phpt | 19 + .../tests/TextUI/dependencies3-isolation.phpt | 20 + .../phpunit/tests/TextUI/dependencies3.phpt | 19 + .../phpunit/tests/TextUI/empty-testcase.phpt | 25 + .../phpunit/tests/TextUI/exception-stack.phpt | 65 + .../tests/TextUI/exclude-group-isolation.phpt | 22 + .../phpunit/tests/TextUI/exclude-group.phpt | 21 + .../tests/TextUI/failure-isolation.phpt | 142 + .../phpunit/phpunit/tests/TextUI/failure.phpt | 141 + .../phpunit/tests/TextUI/fatal-isolation.phpt | 26 + .../tests/TextUI/filter-class-isolation.phpt | 22 + .../phpunit/tests/TextUI/filter-class.phpt | 21 + ...ider-by-classname-and-range-isolation.phpt | 22 + ...r-dataprovider-by-classname-and-range.phpt | 21 + ...lter-dataprovider-by-number-isolation.phpt | 22 + .../TextUI/filter-dataprovider-by-number.phpt | 21 + ...-dataprovider-by-only-range-isolation.phpt | 22 + .../filter-dataprovider-by-only-range.phpt | 21 + ...dataprovider-by-only-regexp-isolation.phpt | 22 + .../filter-dataprovider-by-only-regexp.phpt | 21 + ...dataprovider-by-only-string-isolation.phpt | 22 + .../filter-dataprovider-by-only-string.phpt | 21 + ...ilter-dataprovider-by-range-isolation.phpt | 22 + .../TextUI/filter-dataprovider-by-range.phpt | 21 + ...lter-dataprovider-by-regexp-isolation.phpt | 22 + .../TextUI/filter-dataprovider-by-regexp.phpt | 21 + ...lter-dataprovider-by-string-isolation.phpt | 22 + .../TextUI/filter-dataprovider-by-string.phpt | 21 + .../filter-method-case-insensitive.phpt | 21 + ...ilter-method-case-sensitive-no-result.phpt | 21 + .../tests/TextUI/filter-method-isolation.phpt | 22 + .../phpunit/tests/TextUI/filter-method.phpt | 21 + .../tests/TextUI/filter-no-results.phpt | 21 + .../phpunit/tests/TextUI/group-isolation.phpt | 22 + .../phpunit/phpunit/tests/TextUI/group.phpt | 21 + vendor/phpunit/phpunit/tests/TextUI/help.phpt | 87 + .../phpunit/phpunit/tests/TextUI/help2.phpt | 88 + .../phpunit/tests/TextUI/ini-isolation.phpt | 22 + .../phpunit/tests/TextUI/list-groups.phpt | 19 + .../TextUI/log-json-no-pretty-print.phpt | 27 + .../tests/TextUI/log-json-post-66021.phpt | 72 + .../tests/TextUI/log-json-pre-66021.phpt | 78 + .../phpunit/phpunit/tests/TextUI/log-tap.phpt | 26 + .../phpunit/phpunit/tests/TextUI/log-xml.phpt | 29 + .../tests/TextUI/options-after-arguments.phpt | 19 + .../tests/TextUI/output-isolation.phpt | 21 + .../phpunit/phpunit/tests/TextUI/repeat.phpt | 21 + .../report-useless-tests-incomplete.phpt | 21 + .../report-useless-tests-isolation.phpt | 22 + .../tests/TextUI/report-useless-tests.phpt | 21 + vendor/phpunit/phpunit/tests/TextUI/tap.phpt | 18 + .../tests/TextUI/test-suffix-multiple.phpt | 20 + .../tests/TextUI/test-suffix-single.phpt | 20 + .../phpunit/tests/TextUI/testdox-html.phpt | 21 + .../phpunit/tests/TextUI/testdox-text.phpt | 25 + .../phpunit/phpunit/tests/TextUI/testdox.phpt | 19 + .../phpunit/tests/Util/ConfigurationTest.php | 503 + .../phpunit/phpunit/tests/Util/GetoptTest.php | 62 + .../phpunit/tests/Util/GlobalStateTest.php | 35 + .../phpunit/phpunit/tests/Util/RegexTest.php | 52 + .../tests/Util/TestDox/NamePrettifierTest.php | 81 + .../phpunit/phpunit/tests/Util/TestTest.php | 673 + vendor/phpunit/phpunit/tests/Util/XMLTest.php | 318 + .../phpunit/tests/_files/AbstractTest.php | 7 + .../phpunit/phpunit/tests/_files/Author.php | 27 + .../phpunit/tests/_files/BankAccount.php | 82 + .../phpunit/tests/_files/BankAccountTest.php | 87 + .../tests/_files/BankAccountTest.test.php | 87 + .../tests/_files/BaseTestListenerSample.php | 11 + .../tests/_files/BeforeAndAfterTest.php | 35 + .../_files/BeforeClassAndAfterClassTest.php | 35 + vendor/phpunit/phpunit/tests/_files/Book.php | 20 + .../phpunit/tests/_files/Calculator.php | 14 + .../ChangeCurrentWorkingDirectoryTest.php | 9 + .../_files/ClassWithNonPublicAttributes.php | 29 + .../ClassWithScalarTypeDeclarations.php | 7 + .../tests/_files/ClassWithToString.php | 22 + .../phpunit/tests/_files/ConcreteTest.my.php | 7 + .../phpunit/tests/_files/ConcreteTest.php | 7 + .../_files/CoverageClassExtendedTest.php | 12 + .../tests/_files/CoverageClassTest.php | 12 + .../CoverageFunctionParenthesesTest.php | 11 + ...erageFunctionParenthesesWhitespaceTest.php | 11 + .../tests/_files/CoverageFunctionTest.php | 11 + .../CoverageMethodOneLineAnnotationTest.php | 11 + .../_files/CoverageMethodParenthesesTest.php | 12 + ...overageMethodParenthesesWhitespaceTest.php | 12 + .../tests/_files/CoverageMethodTest.php | 12 + .../_files/CoverageNamespacedFunctionTest.php | 11 + .../phpunit/tests/_files/CoverageNoneTest.php | 9 + .../tests/_files/CoverageNotPrivateTest.php | 12 + .../tests/_files/CoverageNotProtectedTest.php | 12 + .../tests/_files/CoverageNotPublicTest.php | 12 + .../tests/_files/CoverageNothingTest.php | 13 + .../tests/_files/CoveragePrivateTest.php | 12 + .../tests/_files/CoverageProtectedTest.php | 12 + .../tests/_files/CoveragePublicTest.php | 12 + .../CoverageTwoDefaultClassAnnotations.php | 17 + .../phpunit/tests/_files/CoveredClass.php | 36 + .../phpunit/tests/_files/CoveredFunction.php | 4 + .../phpunit/tests/_files/CustomPrinter.php | 4 + .../tests/_files/DataProviderDebugTest.php | 48 + .../tests/_files/DataProviderFilterTest.php | 39 + .../_files/DataProviderIncompleteTest.php | 37 + .../tests/_files/DataProviderSkippedTest.php | 37 + .../phpunit/tests/_files/DataProviderTest.php | 21 + .../tests/_files/DependencyFailureTest.php | 22 + .../tests/_files/DependencySuccessTest.php | 21 + .../tests/_files/DependencyTestSuite.php | 13 + .../phpunit/tests/_files/DoubleTestCase.php | 25 + .../phpunit/tests/_files/DummyException.php | 5 + .../tests/_files/EmptyTestCaseTest.php | 4 + .../ExceptionInAssertPostConditionsTest.php | 35 + .../ExceptionInAssertPreConditionsTest.php | 35 + .../tests/_files/ExceptionInSetUpTest.php | 35 + .../tests/_files/ExceptionInTearDownTest.php | 35 + .../phpunit/tests/_files/ExceptionInTest.php | 35 + .../tests/_files/ExceptionNamespaceTest.php | 38 + .../tests/_files/ExceptionStackTest.php | 21 + .../phpunit/tests/_files/ExceptionTest.php | 139 + .../phpunit/phpunit/tests/_files/Failure.php | 8 + .../phpunit/tests/_files/FailureTest.php | 75 + .../phpunit/tests/_files/FatalTest.php | 13 + .../phpunit/tests/_files/IncompleteTest.php | 8 + .../tests/_files/Inheritance/InheritanceA.php | 7 + .../tests/_files/Inheritance/InheritanceB.php | 8 + .../tests/_files/InheritedTestCase.php | 7 + .../phpunit/phpunit/tests/_files/IniTest.php | 8 + .../phpunit/tests/_files/IsolationTest.php | 13 + .../tests/_files/JsonData/arrayObject.json | 1 + .../tests/_files/JsonData/simpleObject.json | 1 + .../phpunit/tests/_files/MockRunner.php | 7 + .../tests/_files/MultiDependencyTest.php | 23 + .../NamespaceCoverageClassExtendedTest.php | 12 + .../_files/NamespaceCoverageClassTest.php | 12 + ...NamespaceCoverageCoversClassPublicTest.php | 15 + .../NamespaceCoverageCoversClassTest.php | 20 + .../_files/NamespaceCoverageMethodTest.php | 12 + .../NamespaceCoverageNotPrivateTest.php | 12 + .../NamespaceCoverageNotProtectedTest.php | 12 + .../_files/NamespaceCoverageNotPublicTest.php | 12 + .../_files/NamespaceCoveragePrivateTest.php | 12 + .../_files/NamespaceCoverageProtectedTest.php | 12 + .../_files/NamespaceCoveragePublicTest.php | 12 + .../tests/_files/NamespaceCoveredClass.php | 38 + .../tests/_files/NamespaceCoveredFunction.php | 7 + .../tests/_files/NoArgTestCaseTest.php | 7 + .../phpunit/tests/_files/NoTestCaseClass.php | 4 + .../phpunit/tests/_files/NoTestCases.php | 7 + .../phpunit/tests/_files/NonStatic.php | 8 + .../_files/NotExistingCoveredElementTest.php | 24 + .../tests/_files/NotPublicTestCase.php | 11 + .../phpunit/tests/_files/NotVoidTestCase.php | 4 + .../phpunit/tests/_files/NothingTest.php | 7 + .../phpunit/tests/_files/OneTestCase.php | 11 + .../phpunit/tests/_files/OutputTestCase.php | 27 + .../phpunit/tests/_files/OverrideTestCase.php | 7 + .../RequirementsClassBeforeClassHookTest.php | 12 + .../_files/RequirementsClassDocBlockTest.php | 22 + .../phpunit/tests/_files/RequirementsTest.php | 148 + .../tests/_files/SampleArrayAccess.php | 36 + .../phpunit/tests/_files/SampleClass.php | 14 + .../phpunit/tests/_files/Singleton.php | 22 + .../phpunit/tests/_files/StackTest.php | 24 + .../phpunit/phpunit/tests/_files/Struct.php | 10 + .../phpunit/phpunit/tests/_files/Success.php | 7 + .../tests/_files/TemplateMethodsTest.php | 51 + .../phpunit/tests/_files/TestIncomplete.php | 8 + .../phpunit/tests/_files/TestIterator.php | 36 + .../phpunit/tests/_files/TestIterator2.php | 35 + .../phpunit/tests/_files/TestSkipped.php | 8 + .../phpunit/tests/_files/TestTestError.php | 8 + .../phpunit/tests/_files/TestWithTest.php | 24 + .../tests/_files/ThrowExceptionTestCase.php | 8 + .../tests/_files/ThrowNoExceptionTestCase.php | 7 + .../phpunit/phpunit/tests/_files/WasRun.php | 10 + vendor/phpunit/phpunit/tests/_files/bar.xml | 1 + .../_files/configuration.colors.empty.xml | 1 + .../_files/configuration.colors.false.xml | 1 + .../_files/configuration.colors.invalid.xml | 1 + .../_files/configuration.colors.true.xml | 1 + .../_files/configuration.custom-printer.xml | 2 + .../phpunit/tests/_files/configuration.xml | 120 + .../tests/_files/configuration_empty.xml | 57 + .../tests/_files/configuration_xinclude.xml | 75 + .../tests/_files/expectedFileFormat.txt | 1 + vendor/phpunit/phpunit/tests/_files/foo.xml | 1 + ...uctureAttributesAreSameButValuesAreNot.xml | 10 + .../tests/_files/structureExpected.xml | 10 + .../tests/_files/structureIgnoreTextNodes.xml | 13 + .../_files/structureIsSameButDataIsNot.xml | 10 + .../structureWrongNumberOfAttributes.xml | 10 + .../_files/structureWrongNumberOfNodes.xml | 9 + vendor/phpunit/phpunit/tests/bootstrap.php | 6 + vendor/psr/log/.gitignore | 1 + vendor/psr/log/LICENSE | 19 + vendor/psr/log/Psr/Log/AbstractLogger.php | 120 + .../log/Psr/Log/InvalidArgumentException.php | 7 + vendor/psr/log/Psr/Log/LogLevel.php | 18 + .../psr/log/Psr/Log/LoggerAwareInterface.php | 17 + vendor/psr/log/Psr/Log/LoggerAwareTrait.php | 22 + vendor/psr/log/Psr/Log/LoggerInterface.php | 114 + vendor/psr/log/Psr/Log/LoggerTrait.php | 131 + vendor/psr/log/Psr/Log/NullLogger.php | 27 + .../log/Psr/Log/Test/LoggerInterfaceTest.php | 116 + vendor/psr/log/README.md | 45 + vendor/psr/log/composer.json | 17 + vendor/rcrowe/twigbridge/CHANGELOG.md | 29 + vendor/rcrowe/twigbridge/LICENSE | 19 + vendor/rcrowe/twigbridge/README.md | 191 + vendor/rcrowe/twigbridge/UPGRADE.md | 19 + vendor/rcrowe/twigbridge/composer.json | 45 + .../rcrowe/twigbridge/config/twigbridge.php | 214 + vendor/rcrowe/twigbridge/src/Bridge.php | 152 + .../rcrowe/twigbridge/src/Command/Clean.php | 50 + vendor/rcrowe/twigbridge/src/Command/Lint.php | 393 + .../twigbridge/src/Command/TwigBridge.php | 47 + .../rcrowe/twigbridge/src/Engine/Compiler.php | 111 + vendor/rcrowe/twigbridge/src/Engine/Twig.php | 127 + .../src/Extension/Bridge/Former.php | 62 + .../twigbridge/src/Extension/Laravel/Auth.php | 57 + .../src/Extension/Laravel/Config.php | 57 + .../twigbridge/src/Extension/Laravel/Dump.php | 68 + .../twigbridge/src/Extension/Laravel/Form.php | 67 + .../twigbridge/src/Extension/Laravel/Html.php | 71 + .../src/Extension/Laravel/Input.php | 57 + .../src/Extension/Laravel/Legacy/Facades.php | 248 + .../src/Extension/Laravel/Session.php | 60 + .../twigbridge/src/Extension/Laravel/Str.php | 97 + .../src/Extension/Laravel/Translator.php | 82 + .../twigbridge/src/Extension/Laravel/Url.php | 83 + .../src/Extension/Loader/Facade/Caller.php | 93 + .../src/Extension/Loader/Facades.php | 55 + .../src/Extension/Loader/Filters.php | 56 + .../src/Extension/Loader/Functions.php | 56 + .../src/Extension/Loader/Loader.php | 73 + vendor/rcrowe/twigbridge/src/Facade/Twig.php | 30 + .../rcrowe/twigbridge/src/ServiceProvider.php | 311 + vendor/rcrowe/twigbridge/src/Twig/Loader.php | 139 + .../rcrowe/twigbridge/src/Twig/Template.php | 128 + vendor/sebastian/comparator/.gitignore | 6 + vendor/sebastian/comparator/.travis.yml | 25 + vendor/sebastian/comparator/LICENSE | 33 + vendor/sebastian/comparator/README.md | 41 + vendor/sebastian/comparator/build.xml | 34 + .../sebastian/comparator/build/travis-ci.xml | 11 + vendor/sebastian/comparator/composer.json | 44 + vendor/sebastian/comparator/phpunit.xml.dist | 21 + .../comparator/src/ArrayComparator.php | 136 + .../sebastian/comparator/src/Comparator.php | 68 + .../comparator/src/ComparisonFailure.php | 129 + .../comparator/src/DOMNodeComparator.php | 110 + .../comparator/src/DateTimeComparator.php | 80 + .../comparator/src/DoubleComparator.php | 60 + .../comparator/src/ExceptionComparator.php | 51 + vendor/sebastian/comparator/src/Factory.php | 107 + .../comparator/src/MockObjectComparator.php | 45 + .../comparator/src/NumericComparator.php | 72 + .../comparator/src/ObjectComparator.php | 109 + .../comparator/src/ResourceComparator.php | 56 + .../comparator/src/ScalarComparator.php | 94 + .../src/SplObjectStorageComparator.php | 73 + .../comparator/src/TypeComparator.php | 63 + .../comparator/tests/ArrayComparatorTest.php | 163 + .../tests/DOMNodeComparatorTest.php | 162 + .../tests/DateTimeComparatorTest.php | 216 + .../comparator/tests/DoubleComparatorTest.php | 134 + .../tests/ExceptionComparatorTest.php | 136 + .../comparator/tests/FactoryTest.php | 115 + .../tests/MockObjectComparatorTest.php | 166 + .../tests/NumericComparatorTest.php | 122 + .../comparator/tests/ObjectComparatorTest.php | 150 + .../tests/ResourceComparatorTest.php | 120 + .../comparator/tests/ScalarComparatorTest.php | 158 + .../tests/SplObjectStorageComparatorTest.php | 137 + .../comparator/tests/TypeComparatorTest.php | 104 + .../comparator/tests/_files/Author.php | 28 + .../comparator/tests/_files/Book.php | 21 + .../tests/_files/ClassWithToString.php | 19 + .../comparator/tests/_files/SampleClass.php | 29 + .../comparator/tests/_files/Struct.php | 25 + .../comparator/tests/_files/TestClass.php | 14 + .../tests/_files/TestClassComparator.php | 14 + .../sebastian/comparator/tests/autoload.php | 38 + .../sebastian/comparator/tests/bootstrap.php | 7 + vendor/sebastian/diff/.gitignore | 10 + vendor/sebastian/diff/.travis.yml | 16 + vendor/sebastian/diff/LICENSE | 33 + vendor/sebastian/diff/README.md | 126 + vendor/sebastian/diff/build.xml | 26 + vendor/sebastian/diff/composer.json | 33 + vendor/sebastian/diff/phpunit.xml.dist | 17 + vendor/sebastian/diff/src/Chunk.php | 110 + vendor/sebastian/diff/src/Diff.php | 81 + vendor/sebastian/diff/src/Differ.php | 256 + .../diff/src/LCS/LongestCommonSubsequence.php | 33 + ...LongestCommonSubsequenceImplementation.php | 98 + ...LongestCommonSubsequenceImplementation.php | 79 + vendor/sebastian/diff/src/Line.php | 62 + vendor/sebastian/diff/src/Parser.php | 105 + vendor/sebastian/diff/tests/DifferTest.php | Bin 0 -> 11371 bytes .../LCS/TimeEfficientImplementationTest.php | 175 + vendor/sebastian/diff/tests/ParserTest.php | 62 + .../sebastian/diff/tests/fixtures/patch.txt | 9 + .../sebastian/diff/tests/fixtures/patch2.txt | 21 + vendor/sebastian/environment/.gitignore | 5 + vendor/sebastian/environment/.travis.yml | 16 + vendor/sebastian/environment/LICENSE | 33 + vendor/sebastian/environment/README.md | 72 + vendor/sebastian/environment/build.xml | 26 + vendor/sebastian/environment/composer.json | 29 + vendor/sebastian/environment/phpunit.xml.dist | 20 + vendor/sebastian/environment/src/Console.php | 81 + vendor/sebastian/environment/src/Runtime.php | 192 + .../environment/tests/ConsoleTest.php | 60 + .../environment/tests/RuntimeTest.php | 112 + vendor/sebastian/exporter/.gitignore | 9 + vendor/sebastian/exporter/.travis.yml | 23 + vendor/sebastian/exporter/LICENSE | 33 + vendor/sebastian/exporter/README.md | 171 + vendor/sebastian/exporter/build.xml | 27 + vendor/sebastian/exporter/composer.json | 47 + vendor/sebastian/exporter/phpunit.xml.dist | 21 + vendor/sebastian/exporter/src/Exporter.php | 296 + .../sebastian/exporter/tests/ExporterTest.php | 333 + vendor/sebastian/global-state/.gitignore | 6 + vendor/sebastian/global-state/.travis.yml | 20 + vendor/sebastian/global-state/LICENSE | 33 + vendor/sebastian/global-state/README.md | 15 + vendor/sebastian/global-state/build.xml | 33 + vendor/sebastian/global-state/composer.json | 37 + .../sebastian/global-state/phpunit.xml.dist | 21 + .../sebastian/global-state/src/Blacklist.php | 149 + .../global-state/src/CodeExporter.php | 93 + .../sebastian/global-state/src/Exception.php | 17 + .../sebastian/global-state/src/Restorer.php | 141 + .../global-state/src/RuntimeException.php | 17 + .../sebastian/global-state/src/Snapshot.php | 423 + .../global-state/tests/BlacklistTest.php | 113 + .../global-state/tests/SnapshotTest.php | 119 + .../tests/_fixture/BlacklistedChildClass.php | 17 + .../tests/_fixture/BlacklistedClass.php | 18 + .../tests/_fixture/BlacklistedImplementor.php | 18 + .../tests/_fixture/BlacklistedInterface.php | 17 + .../tests/_fixture/SnapshotClass.php | 37 + .../tests/_fixture/SnapshotDomDocument.php | 19 + .../tests/_fixture/SnapshotFunctions.php | 15 + .../tests/_fixture/SnapshotTrait.php | 17 + vendor/sebastian/recursion-context/.gitignore | 9 + .../sebastian/recursion-context/.travis.yml | 21 + vendor/sebastian/recursion-context/LICENSE | 33 + vendor/sebastian/recursion-context/README.md | 13 + vendor/sebastian/recursion-context/build.xml | 27 + .../sebastian/recursion-context/composer.json | 36 + .../recursion-context/phpunit.xml.dist | 20 + .../recursion-context/src/Context.php | 153 + .../recursion-context/src/Exception.php | 17 + .../src/InvalidArgumentException.php | 17 + .../recursion-context/tests/ContextTest.php | 144 + vendor/sebastian/version/.gitattributes | 1 + vendor/sebastian/version/.gitignore | 1 + vendor/sebastian/version/LICENSE | 33 + vendor/sebastian/version/README.md | 37 + vendor/sebastian/version/composer.json | 21 + vendor/sebastian/version/src/Version.php | 82 + vendor/symfony/console/.gitignore | 3 + vendor/symfony/console/Application.php | 1139 ++ vendor/symfony/console/CHANGELOG.md | 62 + vendor/symfony/console/Command/Command.php | 666 + .../symfony/console/Command/HelpCommand.php | 93 + .../symfony/console/Command/ListCommand.php | 97 + vendor/symfony/console/ConsoleEvents.php | 61 + .../Descriptor/ApplicationDescription.php | 159 + .../symfony/console/Descriptor/Descriptor.php | 121 + .../Descriptor/DescriptorInterface.php | 31 + .../console/Descriptor/JsonDescriptor.php | 166 + .../console/Descriptor/MarkdownDescriptor.php | 143 + .../console/Descriptor/TextDescriptor.php | 287 + .../console/Descriptor/XmlDescriptor.php | 263 + .../console/Event/ConsoleCommandEvent.php | 62 + vendor/symfony/console/Event/ConsoleEvent.php | 67 + .../console/Event/ConsoleExceptionEvent.php | 67 + .../console/Event/ConsoleTerminateEvent.php | 58 + .../console/Formatter/OutputFormatter.php | 226 + .../Formatter/OutputFormatterInterface.php | 69 + .../Formatter/OutputFormatterStyle.php | 219 + .../OutputFormatterStyleInterface.php | 64 + .../Formatter/OutputFormatterStyleStack.php | 121 + .../console/Helper/DebugFormatterHelper.php | 127 + .../console/Helper/DescriptorHelper.php | 96 + .../symfony/console/Helper/DialogHelper.php | 483 + .../console/Helper/FormatterHelper.php | 82 + vendor/symfony/console/Helper/Helper.php | 121 + .../console/Helper/HelperInterface.php | 41 + vendor/symfony/console/Helper/HelperSet.php | 116 + .../console/Helper/InputAwareHelper.php | 33 + .../symfony/console/Helper/ProcessHelper.php | 151 + vendor/symfony/console/Helper/ProgressBar.php | 638 + .../symfony/console/Helper/ProgressHelper.php | 465 + .../symfony/console/Helper/QuestionHelper.php | 446 + .../console/Helper/SymfonyQuestionHelper.php | 106 + vendor/symfony/console/Helper/Table.php | 606 + vendor/symfony/console/Helper/TableCell.php | 77 + vendor/symfony/console/Helper/TableHelper.php | 268 + .../symfony/console/Helper/TableSeparator.php | 29 + vendor/symfony/console/Helper/TableStyle.php | 255 + vendor/symfony/console/Input/ArgvInput.php | 349 + vendor/symfony/console/Input/ArrayInput.php | 207 + vendor/symfony/console/Input/Input.php | 233 + .../symfony/console/Input/InputArgument.php | 128 + .../console/Input/InputAwareInterface.php | 28 + .../symfony/console/Input/InputDefinition.php | 455 + .../symfony/console/Input/InputInterface.php | 152 + vendor/symfony/console/Input/InputOption.php | 209 + vendor/symfony/console/Input/StringInput.php | 83 + vendor/symfony/console/LICENSE | 19 + .../symfony/console/Logger/ConsoleLogger.php | 119 + .../symfony/console/Output/BufferedOutput.php | 48 + .../symfony/console/Output/ConsoleOutput.php | 156 + .../console/Output/ConsoleOutputInterface.php | 35 + vendor/symfony/console/Output/NullOutput.php | 111 + vendor/symfony/console/Output/Output.php | 161 + .../console/Output/OutputInterface.php | 95 + .../symfony/console/Output/StreamOutput.php | 99 + .../console/Question/ChoiceQuestion.php | 175 + .../console/Question/ConfirmationQuestion.php | 61 + vendor/symfony/console/Question/Question.php | 247 + vendor/symfony/console/README.md | 67 + .../console/Resources/bin/hiddeninput.exe | Bin 0 -> 9216 bytes vendor/symfony/console/Shell.php | 228 + vendor/symfony/console/Style/OutputStyle.php | 116 + .../symfony/console/Style/StyleInterface.php | 159 + vendor/symfony/console/Style/SymfonyStyle.php | 406 + .../console/Tester/ApplicationTester.php | 128 + .../symfony/console/Tester/CommandTester.php | 132 + .../symfony/console/Tests/ApplicationTest.php | 1058 ++ .../console/Tests/Command/CommandTest.php | 350 + .../console/Tests/Command/HelpCommandTest.php | 70 + .../console/Tests/Command/ListCommandTest.php | 112 + .../Descriptor/AbstractDescriptorTest.php | 105 + .../Tests/Descriptor/JsonDescriptorTest.php | 35 + .../Descriptor/MarkdownDescriptorTest.php | 27 + .../Tests/Descriptor/ObjectsProvider.php | 77 + .../Tests/Descriptor/TextDescriptorTest.php | 27 + .../Tests/Descriptor/XmlDescriptorTest.php | 27 + .../console/Tests/Fixtures/BarBucCommand.php | 11 + .../Tests/Fixtures/DescriptorApplication1.php | 18 + .../Tests/Fixtures/DescriptorApplication2.php | 24 + .../Tests/Fixtures/DescriptorCommand1.php | 27 + .../Tests/Fixtures/DescriptorCommand2.php | 32 + .../console/Tests/Fixtures/DummyOutput.php | 36 + .../console/Tests/Fixtures/Foo1Command.php | 26 + .../console/Tests/Fixtures/Foo2Command.php | 21 + .../console/Tests/Fixtures/Foo3Command.php | 29 + .../console/Tests/Fixtures/Foo4Command.php | 11 + .../console/Tests/Fixtures/Foo5Command.php | 10 + .../console/Tests/Fixtures/Foo6Command.php | 12 + .../console/Tests/Fixtures/FooCommand.php | 33 + .../Fixtures/FooSubnamespaced1Command.php | 26 + .../Fixtures/FooSubnamespaced2Command.php | 26 + .../console/Tests/Fixtures/FoobarCommand.php | 25 + .../Style/SymfonyStyle/command/command_0.php | 11 + .../Style/SymfonyStyle/command/command_1.php | 13 + .../Style/SymfonyStyle/command/command_2.php | 16 + .../Style/SymfonyStyle/command/command_3.php | 12 + .../Style/SymfonyStyle/command/command_4.php | 34 + .../Style/SymfonyStyle/command/command_5.php | 29 + .../Style/SymfonyStyle/command/command_6.php | 16 + .../Style/SymfonyStyle/command/command_7.php | 15 + .../Style/SymfonyStyle/output/output_0.txt | 3 + .../Style/SymfonyStyle/output/output_1.txt | 9 + .../Style/SymfonyStyle/output/output_2.txt | 13 + .../Style/SymfonyStyle/output/output_3.txt | 7 + .../Style/SymfonyStyle/output/output_4.txt | 32 + .../Style/SymfonyStyle/output/output_5.txt | 11 + .../Style/SymfonyStyle/output/output_6.txt | 6 + .../Style/SymfonyStyle/output/output_7.txt | 5 + .../console/Tests/Fixtures/TestCommand.php | 28 + .../console/Tests/Fixtures/application_1.json | 1 + .../console/Tests/Fixtures/application_1.md | 201 + .../console/Tests/Fixtures/application_1.txt | 17 + .../console/Tests/Fixtures/application_1.xml | 110 + .../console/Tests/Fixtures/application_2.json | 1 + .../console/Tests/Fixtures/application_2.md | 396 + .../console/Tests/Fixtures/application_2.txt | 22 + .../console/Tests/Fixtures/application_2.xml | 190 + .../Tests/Fixtures/application_astext1.txt | 20 + .../Tests/Fixtures/application_astext2.txt | 16 + .../Tests/Fixtures/application_asxml1.txt | 146 + .../Tests/Fixtures/application_asxml2.txt | 37 + .../Tests/Fixtures/application_gethelp.txt | 1 + .../Fixtures/application_renderexception1.txt | 8 + .../Fixtures/application_renderexception2.txt | 11 + .../Fixtures/application_renderexception3.txt | 27 + .../application_renderexception3decorated.txt | 27 + .../Fixtures/application_renderexception4.txt | 9 + ...plication_renderexception_doublewidth1.txt | 11 + ..._renderexception_doublewidth1decorated.txt | 11 + ...plication_renderexception_doublewidth2.txt | 12 + .../Tests/Fixtures/application_run1.txt | 17 + .../Tests/Fixtures/application_run2.txt | 29 + .../Tests/Fixtures/application_run3.txt | 27 + .../Tests/Fixtures/application_run4.txt | 1 + .../console/Tests/Fixtures/command_1.json | 1 + .../console/Tests/Fixtures/command_1.md | 11 + .../console/Tests/Fixtures/command_1.txt | 7 + .../console/Tests/Fixtures/command_1.xml | 12 + .../console/Tests/Fixtures/command_2.json | 1 + .../console/Tests/Fixtures/command_2.md | 33 + .../console/Tests/Fixtures/command_2.txt | 13 + .../console/Tests/Fixtures/command_2.xml | 21 + .../console/Tests/Fixtures/command_astext.txt | 18 + .../console/Tests/Fixtures/command_asxml.txt | 38 + .../Tests/Fixtures/definition_astext.txt | 11 + .../Tests/Fixtures/definition_asxml.txt | 39 + .../Tests/Fixtures/input_argument_1.json | 1 + .../Tests/Fixtures/input_argument_1.md | 7 + .../Tests/Fixtures/input_argument_1.txt | 1 + .../Tests/Fixtures/input_argument_1.xml | 5 + .../Tests/Fixtures/input_argument_2.json | 1 + .../Tests/Fixtures/input_argument_2.md | 7 + .../Tests/Fixtures/input_argument_2.txt | 1 + .../Tests/Fixtures/input_argument_2.xml | 5 + .../Tests/Fixtures/input_argument_3.json | 1 + .../Tests/Fixtures/input_argument_3.md | 7 + .../Tests/Fixtures/input_argument_3.txt | 1 + .../Tests/Fixtures/input_argument_3.xml | 7 + .../Tests/Fixtures/input_argument_4.json | 1 + .../Tests/Fixtures/input_argument_4.md | 8 + .../Tests/Fixtures/input_argument_4.txt | 2 + .../Tests/Fixtures/input_argument_4.xml | 6 + .../Tests/Fixtures/input_definition_1.json | 1 + .../Tests/Fixtures/input_definition_1.md | 0 .../Tests/Fixtures/input_definition_1.txt | 0 .../Tests/Fixtures/input_definition_1.xml | 5 + .../Tests/Fixtures/input_definition_2.json | 1 + .../Tests/Fixtures/input_definition_2.md | 9 + .../Tests/Fixtures/input_definition_2.txt | 2 + .../Tests/Fixtures/input_definition_2.xml | 10 + .../Tests/Fixtures/input_definition_3.json | 1 + .../Tests/Fixtures/input_definition_3.md | 11 + .../Tests/Fixtures/input_definition_3.txt | 2 + .../Tests/Fixtures/input_definition_3.xml | 9 + .../Tests/Fixtures/input_definition_4.json | 1 + .../Tests/Fixtures/input_definition_4.md | 21 + .../Tests/Fixtures/input_definition_4.txt | 5 + .../Tests/Fixtures/input_definition_4.xml | 14 + .../Tests/Fixtures/input_option_1.json | 1 + .../console/Tests/Fixtures/input_option_1.md | 9 + .../console/Tests/Fixtures/input_option_1.txt | 1 + .../console/Tests/Fixtures/input_option_1.xml | 4 + .../Tests/Fixtures/input_option_2.json | 1 + .../console/Tests/Fixtures/input_option_2.md | 9 + .../console/Tests/Fixtures/input_option_2.txt | 1 + .../console/Tests/Fixtures/input_option_2.xml | 7 + .../Tests/Fixtures/input_option_3.json | 1 + .../console/Tests/Fixtures/input_option_3.md | 9 + .../console/Tests/Fixtures/input_option_3.txt | 1 + .../console/Tests/Fixtures/input_option_3.xml | 5 + .../Tests/Fixtures/input_option_4.json | 1 + .../console/Tests/Fixtures/input_option_4.md | 9 + .../console/Tests/Fixtures/input_option_4.txt | 1 + .../console/Tests/Fixtures/input_option_4.xml | 5 + .../Tests/Fixtures/input_option_5.json | 1 + .../console/Tests/Fixtures/input_option_5.md | 10 + .../console/Tests/Fixtures/input_option_5.txt | 2 + .../console/Tests/Fixtures/input_option_5.xml | 6 + .../Tests/Fixtures/input_option_6.json | 1 + .../console/Tests/Fixtures/input_option_6.md | 9 + .../console/Tests/Fixtures/input_option_6.txt | 1 + .../console/Tests/Fixtures/input_option_6.xml | 5 + .../OutputFormatterStyleStackTest.php | 70 + .../Formatter/OutputFormatterStyleTest.php | 99 + .../Tests/Formatter/OutputFormatterTest.php | 273 + .../Tests/Helper/FormatterHelperTest.php | 98 + .../console/Tests/Helper/HelperSetTest.php | 153 + .../Tests/Helper/LegacyDialogHelperTest.php | 195 + .../Tests/Helper/LegacyProgressHelperTest.php | 227 + .../Tests/Helper/LegacyTableHelperTest.php | 322 + .../Tests/Helper/ProcessHelperTest.php | 117 + .../console/Tests/Helper/ProgressBarTest.php | 650 + .../Tests/Helper/QuestionHelperTest.php | 383 + .../console/Tests/Helper/TableStyleTest.php | 27 + .../console/Tests/Helper/TableTest.php | 567 + .../console/Tests/Input/ArgvInputTest.php | 317 + .../console/Tests/Input/ArrayInputTest.php | 138 + .../console/Tests/Input/InputArgumentTest.php | 111 + .../Tests/Input/InputDefinitionTest.php | 437 + .../console/Tests/Input/InputOptionTest.php | 204 + .../symfony/console/Tests/Input/InputTest.php | 132 + .../console/Tests/Input/StringInputTest.php | 99 + .../Tests/Logger/ConsoleLoggerTest.php | 58 + .../Tests/Output/ConsoleOutputTest.php | 25 + .../console/Tests/Output/NullOutputTest.php | 39 + .../console/Tests/Output/OutputTest.php | 156 + .../console/Tests/Output/StreamOutputTest.php | 60 + .../console/Tests/Style/SymfonyStyleTest.php | 89 + .../Tests/Tester/ApplicationTesterTest.php | 69 + .../Tests/Tester/CommandTesterTest.php | 84 + vendor/symfony/console/composer.json | 40 + vendor/symfony/console/phpunit.xml.dist | 29 + vendor/symfony/debug/.gitignore | 3 + vendor/symfony/debug/CHANGELOG.md | 35 + vendor/symfony/debug/Debug.php | 62 + vendor/symfony/debug/DebugClassLoader.php | 309 + vendor/symfony/debug/ErrorHandler.php | 741 + .../Exception/ClassNotFoundException.php | 33 + .../debug/Exception/ContextErrorException.php | 36 + .../debug/Exception/DummyException.php | 23 + .../debug/Exception/FatalErrorException.php | 99 + .../debug/Exception/FatalThrowableError.php | 44 + .../debug/Exception/FlattenException.php | 292 + .../debug/Exception/OutOfMemoryException.php | 21 + .../Exception/UndefinedFunctionException.php | 33 + .../Exception/UndefinedMethodException.php | 33 + vendor/symfony/debug/ExceptionHandler.php | 472 + .../ClassNotFoundFatalErrorHandler.php | 212 + .../FatalErrorHandlerInterface.php | 32 + .../UndefinedFunctionFatalErrorHandler.php | 84 + .../UndefinedMethodFatalErrorHandler.php | 60 + vendor/symfony/debug/LICENSE | 19 + vendor/symfony/debug/README.md | 43 + vendor/symfony/debug/Resources/ext/README.md | 133 + vendor/symfony/debug/Resources/ext/config.m4 | 63 + vendor/symfony/debug/Resources/ext/config.w32 | 13 + .../debug/Resources/ext/php_symfony_debug.h | 60 + .../debug/Resources/ext/symfony_debug.c | 283 + .../debug/Resources/ext/tests/001.phpt | 151 + .../debug/Resources/ext/tests/002.phpt | 64 + .../debug/Resources/ext/tests/002_1.phpt | 47 + .../debug/Resources/ext/tests/003.phpt | 85 + .../debug/Tests/DebugClassLoaderTest.php | 296 + .../symfony/debug/Tests/ErrorHandlerTest.php | 503 + .../Tests/Exception/FlattenExceptionTest.php | 256 + .../debug/Tests/ExceptionHandlerTest.php | 134 + .../ClassNotFoundFatalErrorHandlerTest.php | 200 + ...UndefinedFunctionFatalErrorHandlerTest.php | 80 + .../UndefinedMethodFatalErrorHandlerTest.php | 66 + .../debug/Tests/Fixtures/ClassAlias.php | 3 + .../debug/Tests/Fixtures/DeprecatedClass.php | 12 + .../Tests/Fixtures/DeprecatedInterface.php | 12 + .../debug/Tests/Fixtures/PEARClass.php | 5 + .../debug/Tests/Fixtures/casemismatch.php | 7 + .../debug/Tests/Fixtures/notPsr0Bis.php | 7 + .../Tests/Fixtures/psr4/Psr4CaseMismatch.php | 7 + .../debug/Tests/Fixtures/reallyNotPsr0.php | 7 + .../debug/Tests/Fixtures2/RequiredTwice.php | 7 + vendor/symfony/debug/Tests/HeaderMock.php | 38 + .../debug/Tests/MockExceptionHandler.php | 24 + vendor/symfony/debug/composer.json | 38 + vendor/symfony/debug/phpunit.xml.dist | 31 + vendor/symfony/dom-crawler/.gitignore | 3 + vendor/symfony/dom-crawler/CHANGELOG.md | 45 + vendor/symfony/dom-crawler/Crawler.php | 1016 + .../dom-crawler/Field/ChoiceFormField.php | 319 + .../dom-crawler/Field/FileFormField.php | 108 + .../symfony/dom-crawler/Field/FormField.php | 114 + .../dom-crawler/Field/InputFormField.php | 45 + .../dom-crawler/Field/TextareaFormField.php | 37 + vendor/symfony/dom-crawler/Form.php | 471 + .../symfony/dom-crawler/FormFieldRegistry.php | 222 + vendor/symfony/dom-crawler/LICENSE | 19 + vendor/symfony/dom-crawler/Link.php | 224 + vendor/symfony/dom-crawler/README.md | 36 + .../symfony/dom-crawler/Tests/CrawlerTest.php | 1084 ++ .../Tests/Field/ChoiceFormFieldTest.php | 388 + .../Tests/Field/FileFormFieldTest.php | 114 + .../dom-crawler/Tests/Field/FormFieldTest.php | 38 + .../Tests/Field/FormFieldTestCase.php | 27 + .../Tests/Field/InputFormFieldTest.php | 49 + .../Tests/Field/TextareaFormFieldTest.php | 46 + .../dom-crawler/Tests/Fixtures/no-extension | 1 + .../Tests/Fixtures/windows-1250.html | 8 + vendor/symfony/dom-crawler/Tests/FormTest.php | 973 + vendor/symfony/dom-crawler/Tests/LinkTest.php | 160 + vendor/symfony/dom-crawler/composer.json | 36 + vendor/symfony/dom-crawler/phpunit.xml.dist | 29 + vendor/symfony/event-dispatcher/.gitignore | 3 + vendor/symfony/event-dispatcher/CHANGELOG.md | 23 + .../ContainerAwareEventDispatcher.php | 187 + .../Debug/TraceableEventDispatcher.php | 335 + .../TraceableEventDispatcherInterface.php | 34 + .../Debug/WrappedListener.php | 71 + .../RegisterListenersPass.php | 110 + vendor/symfony/event-dispatcher/Event.php | 120 + .../event-dispatcher/EventDispatcher.php | 177 + .../EventDispatcherInterface.php | 88 + .../EventSubscriberInterface.php | 46 + .../symfony/event-dispatcher/GenericEvent.php | 186 + .../ImmutableEventDispatcher.php | 93 + vendor/symfony/event-dispatcher/LICENSE | 19 + vendor/symfony/event-dispatcher/README.md | 27 + .../Tests/AbstractEventDispatcherTest.php | 382 + .../ContainerAwareEventDispatcherTest.php | 249 + .../Debug/TraceableEventDispatcherTest.php | 199 + .../RegisterListenersPassTest.php | 200 + .../Tests/EventDispatcherTest.php | 22 + .../event-dispatcher/Tests/EventTest.php | 96 + .../Tests/GenericEventTest.php | 139 + .../Tests/ImmutableEventDispatcherTest.php | 105 + vendor/symfony/event-dispatcher/composer.json | 41 + .../symfony/event-dispatcher/phpunit.xml.dist | 29 + vendor/symfony/finder/.gitignore | 3 + .../finder/Adapter/AbstractAdapter.php | 236 + .../finder/Adapter/AbstractFindAdapter.php | 327 + .../finder/Adapter/AdapterInterface.php | 144 + .../symfony/finder/Adapter/BsdFindAdapter.php | 103 + .../symfony/finder/Adapter/GnuFindAdapter.php | 104 + vendor/symfony/finder/Adapter/PhpAdapter.php | 97 + vendor/symfony/finder/CHANGELOG.md | 34 + .../symfony/finder/Comparator/Comparator.php | 98 + .../finder/Comparator/DateComparator.php | 53 + .../finder/Comparator/NumberComparator.php | 81 + .../Exception/AccessDeniedException.php | 19 + .../Exception/AdapterFailureException.php | 46 + .../finder/Exception/ExceptionInterface.php | 23 + .../OperationNotPermitedException.php | 19 + .../ShellCommandFailureException.php | 45 + .../symfony/finder/Expression/Expression.php | 146 + vendor/symfony/finder/Expression/Glob.php | 109 + vendor/symfony/finder/Expression/Regex.php | 321 + .../finder/Expression/ValueInterface.php | 60 + vendor/symfony/finder/Finder.php | 798 + vendor/symfony/finder/Glob.php | 104 + .../finder/Iterator/CustomFilterIterator.php | 63 + .../Iterator/DateRangeFilterIterator.php | 60 + .../Iterator/DepthRangeFilterIterator.php | 47 + .../ExcludeDirectoryFilterIterator.php | 85 + .../finder/Iterator/FilePathsIterator.php | 131 + .../Iterator/FileTypeFilterIterator.php | 55 + .../Iterator/FilecontentFilterIterator.php | 76 + .../Iterator/FilenameFilterIterator.php | 67 + .../finder/Iterator/FilterIterator.php | 49 + .../Iterator/MultiplePcreFilterIterator.php | 66 + .../finder/Iterator/PathFilterIterator.php | 74 + .../Iterator/RecursiveDirectoryIterator.php | 149 + .../Iterator/SizeRangeFilterIterator.php | 59 + .../finder/Iterator/SortableIterator.php | 82 + vendor/symfony/finder/LICENSE | 19 + vendor/symfony/finder/README.md | 53 + vendor/symfony/finder/Shell/Command.php | 294 + vendor/symfony/finder/Shell/Shell.php | 97 + vendor/symfony/finder/SplFileInfo.php | 77 + vendor/symfony/finder/Tests/BsdFinderTest.php | 28 + .../Tests/Comparator/ComparatorTest.php | 64 + .../Tests/Comparator/DateComparatorTest.php | 63 + .../Tests/Comparator/NumberComparatorTest.php | 107 + .../Tests/Expression/ExpressionTest.php | 68 + .../finder/Tests/Expression/GlobTest.php | 47 + .../finder/Tests/Expression/RegexTest.php | 143 + .../finder/Tests/FakeAdapter/DummyAdapter.php | 57 + .../Tests/FakeAdapter/FailingAdapter.php | 45 + .../finder/Tests/FakeAdapter/NamedAdapter.php | 57 + .../Tests/FakeAdapter/UnsupportedAdapter.php | 44 + vendor/symfony/finder/Tests/FinderTest.php | 742 + .../finder/Tests/Fixtures/A/B/C/abc.dat | 0 .../symfony/finder/Tests/Fixtures/A/B/ab.dat | 0 vendor/symfony/finder/Tests/Fixtures/A/a.dat | 0 .../Tests/Fixtures/copy/A/B/C/abc.dat.copy | 0 .../Tests/Fixtures/copy/A/B/ab.dat.copy | 0 .../finder/Tests/Fixtures/copy/A/a.dat.copy | 0 .../symfony/finder/Tests/Fixtures/dolor.txt | 2 + .../symfony/finder/Tests/Fixtures/ipsum.txt | 2 + .../symfony/finder/Tests/Fixtures/lorem.txt | 2 + vendor/symfony/finder/Tests/Fixtures/one/a | 0 .../finder/Tests/Fixtures/one/b/c.neon | 0 .../finder/Tests/Fixtures/one/b/d.neon | 0 .../Fixtures/r+e.gex[c]a(r)s/dir/bar.dat | 0 .../finder/Tests/Fixtures/with space/foo.txt | 0 vendor/symfony/finder/Tests/GlobTest.php | 24 + vendor/symfony/finder/Tests/GnuFinderTest.php | 28 + .../Iterator/CustomFilterIteratorTest.php | 46 + .../Iterator/DateRangeFilterIteratorTest.php | 74 + .../Iterator/DepthRangeFilterIteratorTest.php | 83 + .../ExcludeDirectoryFilterIteratorTest.php | 66 + .../Tests/Iterator/FilePathsIteratorTest.php | 69 + .../Iterator/FileTypeFilterIteratorTest.php | 73 + .../FilecontentFilterIteratorTest.php | 86 + .../Iterator/FilenameFilterIteratorTest.php | 54 + .../Tests/Iterator/FilterIteratorTest.php | 50 + .../finder/Tests/Iterator/Iterator.php | 55 + .../Tests/Iterator/IteratorTestCase.php | 98 + .../Tests/Iterator/MockFileListIterator.php | 21 + .../finder/Tests/Iterator/MockSplFileInfo.php | 134 + .../MultiplePcreFilterIteratorTest.php | 67 + .../Tests/Iterator/PathFilterIteratorTest.php | 83 + .../Tests/Iterator/RealIteratorTestCase.php | 110 + .../RecursiveDirectoryIteratorTest.php | 59 + .../Iterator/SizeRangeFilterIteratorTest.php | 69 + .../Tests/Iterator/SortableIteratorTest.php | 183 + .../finder/Tests/Shell/CommandTest.php | 162 + vendor/symfony/finder/composer.json | 30 + vendor/symfony/finder/phpunit.xml.dist | 28 + vendor/symfony/http-foundation/.gitignore | 3 + .../symfony/http-foundation/AcceptHeader.php | 172 + .../http-foundation/AcceptHeaderItem.php | 226 + .../symfony/http-foundation/ApacheRequest.php | 43 + .../http-foundation/BinaryFileResponse.php | 322 + vendor/symfony/http-foundation/CHANGELOG.md | 122 + vendor/symfony/http-foundation/Cookie.php | 190 + .../ExpressionRequestMatcher.php | 47 + .../File/Exception/AccessDeniedException.php | 30 + .../File/Exception/FileException.php | 21 + .../File/Exception/FileNotFoundException.php | 30 + .../Exception/UnexpectedTypeException.php | 20 + .../File/Exception/UploadException.php | 21 + vendor/symfony/http-foundation/File/File.php | 136 + .../File/MimeType/ExtensionGuesser.php | 96 + .../MimeType/ExtensionGuesserInterface.php | 27 + .../MimeType/FileBinaryMimeTypeGuesser.php | 87 + .../File/MimeType/FileinfoMimeTypeGuesser.php | 71 + .../MimeType/MimeTypeExtensionGuesser.php | 807 + .../File/MimeType/MimeTypeGuesser.php | 144 + .../MimeType/MimeTypeGuesserInterface.php | 35 + .../http-foundation/File/UploadedFile.php | 293 + vendor/symfony/http-foundation/FileBag.php | 145 + vendor/symfony/http-foundation/HeaderBag.php | 324 + vendor/symfony/http-foundation/IpUtils.php | 129 + .../symfony/http-foundation/JsonResponse.php | 226 + vendor/symfony/http-foundation/LICENSE | 19 + .../symfony/http-foundation/ParameterBag.php | 291 + vendor/symfony/http-foundation/README.md | 56 + .../http-foundation/RedirectResponse.php | 102 + vendor/symfony/http-foundation/Request.php | 1920 ++ .../http-foundation/RequestMatcher.php | 178 + .../RequestMatcherInterface.php | 29 + .../symfony/http-foundation/RequestStack.php | 103 + .../stubs/SessionHandlerInterface.php | 102 + vendor/symfony/http-foundation/Response.php | 1171 ++ .../http-foundation/ResponseHeaderBag.php | 304 + vendor/symfony/http-foundation/ServerBag.php | 98 + .../Session/Attribute/AttributeBag.php | 157 + .../Attribute/AttributeBagInterface.php | 72 + .../Attribute/NamespacedAttributeBag.php | 160 + .../Session/Flash/AutoExpireFlashBag.php | 175 + .../Session/Flash/FlashBag.php | 182 + .../Session/Flash/FlashBagInterface.php | 93 + .../http-foundation/Session/Session.php | 249 + .../Session/SessionBagInterface.php | 48 + .../Session/SessionInterface.php | 182 + .../Handler/LegacyPdoSessionHandler.php | 271 + .../Handler/MemcacheSessionHandler.php | 119 + .../Handler/MemcachedSessionHandler.php | 125 + .../Storage/Handler/MongoDbSessionHandler.php | 188 + .../Handler/NativeFileSessionHandler.php | 58 + .../Storage/Handler/NativeSessionHandler.php | 24 + .../Storage/Handler/NullSessionHandler.php | 70 + .../Storage/Handler/PdoSessionHandler.php | 695 + .../Handler/WriteCheckSessionHandler.php | 91 + .../Session/Storage/MetadataBag.php | 170 + .../Storage/MockArraySessionStorage.php | 268 + .../Storage/MockFileSessionStorage.php | 138 + .../Session/Storage/NativeSessionStorage.php | 430 + .../Storage/PhpBridgeSessionStorage.php | 68 + .../Session/Storage/Proxy/AbstractProxy.php | 154 + .../Session/Storage/Proxy/NativeProxy.php | 41 + .../Storage/Proxy/SessionHandlerProxy.php | 95 + .../Storage/SessionStorageInterface.php | 139 + .../http-foundation/StreamedResponse.php | 119 + .../Tests/AcceptHeaderItemTest.php | 112 + .../Tests/AcceptHeaderTest.php | 102 + .../Tests/ApacheRequestTest.php | 92 + .../Tests/BinaryFileResponseTest.php | 250 + .../http-foundation/Tests/CookieTest.php | 147 + .../Tests/ExpressionRequestMatcherTest.php | 68 + .../http-foundation/Tests/File/FakeFile.php | 45 + .../http-foundation/Tests/File/FileTest.php | 179 + .../Tests/File/Fixtures/.unknownextension | 1 + .../Tests/File/Fixtures/directory/.empty | 0 .../Tests/File/Fixtures/other-file.example | 0 .../http-foundation/Tests/File/Fixtures/test | Bin 0 -> 35 bytes .../Tests/File/Fixtures/test.gif | Bin 0 -> 35 bytes .../Tests/File/MimeType/MimeTypeTest.php | 89 + .../Tests/File/UploadedFileTest.php | 272 + .../http-foundation/Tests/FileBagTest.php | 148 + .../http-foundation/Tests/HeaderBagTest.php | 216 + .../http-foundation/Tests/IpUtilsTest.php | 81 + .../Tests/JsonResponseTest.php | 226 + .../Tests/ParameterBagTest.php | 266 + .../Tests/RedirectResponseTest.php | 83 + .../Tests/RequestMatcherTest.php | 150 + .../Tests/RequestStackTest.php | 69 + .../http-foundation/Tests/RequestTest.php | 1886 ++ .../Tests/ResponseHeaderBagTest.php | 298 + .../http-foundation/Tests/ResponseTest.php | 893 + .../Tests/ResponseTestCase.php | 88 + .../http-foundation/Tests/ServerBagTest.php | 154 + .../Session/Attribute/AttributeBagTest.php | 193 + .../Attribute/NamespacedAttributeBagTest.php | 183 + .../Session/Flash/AutoExpireFlashBagTest.php | 155 + .../Tests/Session/Flash/FlashBagTest.php | 155 + .../Tests/Session/SessionTest.php | 227 + .../Handler/LegacyPdoSessionHandlerTest.php | 113 + .../Handler/MemcacheSessionHandlerTest.php | 134 + .../Handler/MemcachedSessionHandlerTest.php | 134 + .../Handler/MongoDbSessionHandlerTest.php | 255 + .../Handler/NativeFileSessionHandlerTest.php | 81 + .../Handler/NativeSessionHandlerTest.php | 40 + .../Handler/NullSessionHandlerTest.php | 58 + .../Storage/Handler/PdoSessionHandlerTest.php | 357 + .../Handler/WriteCheckSessionHandlerTest.php | 94 + .../Tests/Session/Storage/MetadataBagTest.php | 138 + .../Storage/MockArraySessionStorageTest.php | 106 + .../Storage/MockFileSessionStorageTest.php | 126 + .../Storage/NativeSessionStorageTest.php | 264 + .../Storage/PhpBridgeSessionStorageTest.php | 122 + .../Storage/Proxy/AbstractProxyTest.php | 205 + .../Session/Storage/Proxy/NativeProxyTest.php | 35 + .../Storage/Proxy/SessionHandlerProxyTest.php | 127 + .../Tests/StreamedResponseTest.php | 121 + vendor/symfony/http-foundation/composer.json | 34 + .../symfony/http-foundation/phpunit.xml.dist | 29 + vendor/symfony/http-kernel/.gitignore | 5 + vendor/symfony/http-kernel/Bundle/Bundle.php | 203 + .../http-kernel/Bundle/BundleInterface.php | 84 + vendor/symfony/http-kernel/CHANGELOG.md | 73 + .../CacheClearer/CacheClearerInterface.php | 27 + .../CacheClearer/ChainCacheClearer.php | 55 + .../http-kernel/CacheWarmer/CacheWarmer.php | 32 + .../CacheWarmer/CacheWarmerAggregate.php | 74 + .../CacheWarmer/CacheWarmerInterface.php | 32 + .../CacheWarmer/WarmableInterface.php | 27 + vendor/symfony/http-kernel/Client.php | 226 + .../Config/EnvParametersResource.php | 95 + .../http-kernel/Config/FileLocator.php | 56 + .../Controller/ControllerReference.php | 46 + .../Controller/ControllerResolver.php | 164 + .../ControllerResolverInterface.php | 57 + .../TraceableControllerResolver.php | 66 + .../DataCollector/ConfigDataCollector.php | 291 + .../DataCollector/DataCollector.php | 58 + .../DataCollector/DataCollectorInterface.php | 39 + .../DataCollector/DumpDataCollector.php | 304 + .../DataCollector/EventDataCollector.php | 107 + .../DataCollector/ExceptionDataCollector.php | 104 + .../LateDataCollectorInterface.php | 25 + .../DataCollector/LoggerDataCollector.php | 195 + .../DataCollector/MemoryDataCollector.php | 109 + .../DataCollector/RequestDataCollector.php | 342 + .../DataCollector/RouterDataCollector.php | 102 + .../DataCollector/TimeDataCollector.php | 136 + .../DataCollector/Util/ValueExporter.php | 78 + .../http-kernel/Debug/ErrorHandler.php | 27 + .../http-kernel/Debug/ExceptionHandler.php | 27 + .../Debug/TraceableEventDispatcher.php | 99 + .../AddClassesToCachePass.php | 46 + .../ConfigurableExtension.php | 45 + .../ContainerAwareHttpKernel.php | 82 + .../DependencyInjection/Extension.php | 44 + .../FragmentRendererPass.php | 73 + .../LazyLoadingFragmentHandler.php | 58 + .../MergeExtensionConfigurationPass.php | 41 + .../RegisterListenersPass.php | 25 + .../Event/FilterControllerEvent.php | 102 + .../http-kernel/Event/FilterResponseEvent.php | 62 + .../http-kernel/Event/FinishRequestEvent.php | 21 + .../http-kernel/Event/GetResponseEvent.php | 65 + .../GetResponseForControllerResultEvent.php | 61 + .../Event/GetResponseForExceptionEvent.php | 67 + .../symfony/http-kernel/Event/KernelEvent.php | 94 + .../http-kernel/Event/PostResponseEvent.php | 73 + .../AddRequestFormatsListener.php | 57 + .../EventListener/DebugHandlersListener.php | 136 + .../EventListener/DumpListener.php | 55 + .../EventListener/ErrorsLoggerListener.php | 52 + .../http-kernel/EventListener/EsiListener.php | 25 + .../EventListener/ExceptionListener.php | 120 + .../EventListener/FragmentListener.php | 108 + .../EventListener/LocaleListener.php | 113 + .../EventListener/ProfilerListener.php | 165 + .../EventListener/ResponseListener.php | 58 + .../EventListener/RouterListener.php | 174 + .../EventListener/SaveSessionListener.php | 66 + .../EventListener/SessionListener.php | 53 + .../StreamedResponseListener.php | 51 + .../EventListener/SurrogateListener.php | 58 + .../EventListener/TestSessionListener.php | 83 + .../EventListener/TranslatorListener.php | 69 + .../Exception/AccessDeniedHttpException.php | 33 + .../Exception/BadRequestHttpException.php | 32 + .../Exception/ConflictHttpException.php | 32 + .../Exception/FatalErrorException.php | 23 + .../Exception/FlattenException.php | 25 + .../Exception/GoneHttpException.php | 32 + .../http-kernel/Exception/HttpException.php | 41 + .../Exception/HttpExceptionInterface.php | 34 + .../Exception/LengthRequiredHttpException.php | 32 + .../MethodNotAllowedHttpException.php | 35 + .../Exception/NotAcceptableHttpException.php | 32 + .../Exception/NotFoundHttpException.php | 32 + .../PreconditionFailedHttpException.php | 32 + .../PreconditionRequiredHttpException.php | 34 + .../ServiceUnavailableHttpException.php | 38 + .../TooManyRequestsHttpException.php | 40 + .../Exception/UnauthorizedHttpException.php | 35 + .../UnprocessableEntityHttpException.php | 32 + .../UnsupportedMediaTypeHttpException.php | 32 + .../AbstractSurrogateFragmentRenderer.php | 95 + .../Fragment/EsiFragmentRenderer.php | 28 + .../http-kernel/Fragment/FragmentHandler.php | 150 + .../Fragment/FragmentRendererInterface.php | 42 + .../Fragment/HIncludeFragmentRenderer.php | 164 + .../Fragment/InlineFragmentRenderer.php | 152 + .../Fragment/RoutableFragmentRenderer.php | 90 + .../Fragment/SsiFragmentRenderer.php | 28 + vendor/symfony/http-kernel/HttpCache/Esi.php | 295 + .../HttpCache/EsiResponseCacheStrategy.php | 33 + .../EsiResponseCacheStrategyInterface.php | 28 + .../http-kernel/HttpCache/HttpCache.php | 706 + .../HttpCache/ResponseCacheStrategy.php | 85 + .../ResponseCacheStrategyInterface.php | 41 + vendor/symfony/http-kernel/HttpCache/Ssi.php | 194 + .../symfony/http-kernel/HttpCache/Store.php | 449 + .../http-kernel/HttpCache/StoreInterface.php | 96 + .../HttpCache/SurrogateInterface.php | 103 + vendor/symfony/http-kernel/HttpKernel.php | 285 + .../http-kernel/HttpKernelInterface.php | 43 + vendor/symfony/http-kernel/Kernel.php | 761 + vendor/symfony/http-kernel/KernelEvents.php | 115 + .../symfony/http-kernel/KernelInterface.php | 175 + vendor/symfony/http-kernel/LICENSE | 19 + .../http-kernel/Log/DebugLoggerInterface.php | 38 + .../http-kernel/Log/LoggerInterface.php | 44 + vendor/symfony/http-kernel/Log/NullLogger.php | 44 + .../Profiler/BaseMemcacheProfilerStorage.php | 310 + .../Profiler/FileProfilerStorage.php | 282 + .../Profiler/MemcacheProfilerStorage.php | 107 + .../Profiler/MemcachedProfilerStorage.php | 103 + .../Profiler/MongoDbProfilerStorage.php | 259 + .../Profiler/MysqlProfilerStorage.php | 79 + .../Profiler/PdoProfilerStorage.php | 263 + .../symfony/http-kernel/Profiler/Profile.php | 292 + .../symfony/http-kernel/Profiler/Profiler.php | 296 + .../Profiler/ProfilerStorageInterface.php | 59 + .../Profiler/RedisProfilerStorage.php | 394 + .../Profiler/SqliteProfilerStorage.php | 139 + vendor/symfony/http-kernel/README.md | 99 + .../http-kernel/TerminableInterface.php | 35 + .../http-kernel/Tests/Bundle/BundleTest.php | 44 + .../CacheClearer/ChainCacheClearerTest.php | 57 + .../CacheWarmer/CacheWarmerAggregateTest.php | 100 + .../Tests/CacheWarmer/CacheWarmerTest.php | 67 + .../symfony/http-kernel/Tests/ClientTest.php | 179 + .../Config/EnvParametersResourceTest.php | 106 + .../Tests/Config/FileLocatorTest.php | 47 + .../Controller/ControllerResolverTest.php | 242 + .../DataCollector/ConfigDataCollectorTest.php | 81 + .../DataCollector/DumpDataCollectorTest.php | 138 + .../ExceptionDataCollectorTest.php | 39 + .../DataCollector/LoggerDataCollectorTest.php | 95 + .../DataCollector/MemoryDataCollectorTest.php | 58 + .../RequestDataCollectorTest.php | 222 + .../DataCollector/TimeDataCollectorTest.php | 51 + .../DataCollector/Util/ValueExporterTest.php | 42 + .../Debug/TraceableEventDispatcherTest.php | 117 + .../ContainerAwareHttpKernelTest.php | 168 + .../FragmentRendererPassTest.php | 160 + .../LazyLoadingFragmentHandlerTest.php | 40 + .../MergeExtensionConfigurationPassTest.php | 57 + .../AddRequestFormatsListenerTest.php | 83 + .../DebugHandlersListenerTest.php | 106 + .../Tests/EventListener/DumpListenerTest.php | 82 + .../EventListener/ExceptionListenerTest.php | 146 + .../EventListener/FragmentListenerTest.php | 96 + .../EventListener/LocaleListenerTest.php | 103 + .../EventListener/ProfilerListenerTest.php | 105 + .../EventListener/ResponseListenerTest.php | 94 + .../EventListener/RouterListenerTest.php | 161 + .../EventListener/SurrogateListenerTest.php | 66 + .../EventListener/TestSessionListenerTest.php | 132 + .../EventListener/TranslatorListenerTest.php | 117 + .../Fixtures/BaseBundle/Resources/foo.txt | 0 .../Fixtures/BaseBundle/Resources/hide.txt | 0 .../Fixtures/Bundle1Bundle/Resources/foo.txt | 0 .../Tests/Fixtures/Bundle1Bundle/bar.txt | 0 .../Tests/Fixtures/Bundle1Bundle/foo.txt | 0 .../Tests/Fixtures/Bundle2Bundle/foo.txt | 0 .../Fixtures/ChildBundle/Resources/foo.txt | 0 .../Fixtures/ChildBundle/Resources/hide.txt | 0 .../ExtensionAbsentBundle.php | 18 + .../ExtensionLoadedExtension.php | 22 + .../ExtensionLoadedBundle.php | 18 + .../ExtensionNotValidExtension.php | 20 + .../ExtensionNotValidBundle.php | 18 + .../Command/BarCommand.php | 18 + .../Command/FooCommand.php | 22 + .../ExtensionPresentExtension.php | 22 + .../ExtensionPresentBundle.php | 18 + .../Tests/Fixtures/FooBarBundle.php | 19 + .../Tests/Fixtures/KernelForOverrideName.php | 28 + .../Tests/Fixtures/KernelForTest.php | 37 + .../Fixtures/Resources/BaseBundle/hide.txt | 0 .../Fixtures/Resources/Bundle1Bundle/foo.txt | 0 .../Fixtures/Resources/ChildBundle/foo.txt | 0 .../Fixtures/Resources/FooBundle/foo.txt | 0 .../http-kernel/Tests/Fixtures/TestClient.php | 31 + .../Tests/Fixtures/TestEventDispatcher.php | 28 + .../Fragment/EsiFragmentRendererTest.php | 97 + .../Tests/Fragment/FragmentHandlerTest.php | 95 + .../Fragment/HIncludeFragmentRendererTest.php | 88 + .../Fragment/InlineFragmentRendererTest.php | 210 + .../Fragment/RoutableFragmentRendererTest.php | 93 + .../http-kernel/Tests/HttpCache/EsiTest.php | 247 + .../Tests/HttpCache/HttpCacheTest.php | 1230 ++ .../Tests/HttpCache/HttpCacheTestCase.php | 181 + .../http-kernel/Tests/HttpCache/SsiTest.php | 214 + .../http-kernel/Tests/HttpCache/StoreTest.php | 269 + .../Tests/HttpCache/TestHttpKernel.php | 91 + .../HttpCache/TestMultipleHttpKernel.php | 80 + .../http-kernel/Tests/HttpKernelTest.php | 319 + .../symfony/http-kernel/Tests/KernelTest.php | 849 + vendor/symfony/http-kernel/Tests/Logger.php | 128 + .../Profiler/AbstractProfilerStorageTest.php | 270 + .../Profiler/FileProfilerStorageTest.php | 100 + .../Profiler/MemcacheProfilerStorageTest.php | 49 + .../Profiler/MemcachedProfilerStorageTest.php | 49 + .../Tests/Profiler/Mock/MemcacheMock.php | 254 + .../Tests/Profiler/Mock/MemcachedMock.php | 219 + .../Tests/Profiler/Mock/RedisMock.php | 247 + .../Profiler/MongoDbProfilerStorageTest.php | 166 + .../Tests/Profiler/ProfilerTest.php | 82 + .../Profiler/RedisProfilerStorageTest.php | 49 + .../Profiler/SqliteProfilerStorageTest.php | 50 + .../http-kernel/Tests/TestHttpKernel.php | 41 + .../http-kernel/Tests/UriSignerTest.php | 51 + vendor/symfony/http-kernel/UriSigner.php | 109 + vendor/symfony/http-kernel/composer.json | 63 + vendor/symfony/http-kernel/phpunit.xml.dist | 28 + vendor/symfony/process/.gitignore | 3 + vendor/symfony/process/CHANGELOG.md | 40 + .../process/Exception/ExceptionInterface.php | 21 + .../Exception/InvalidArgumentException.php | 21 + .../process/Exception/LogicException.php | 21 + .../Exception/ProcessFailedException.php | 53 + .../Exception/ProcessTimedOutException.php | 69 + .../process/Exception/RuntimeException.php | 21 + vendor/symfony/process/ExecutableFinder.php | 90 + vendor/symfony/process/LICENSE | 19 + .../symfony/process/PhpExecutableFinder.php | 86 + vendor/symfony/process/PhpProcess.php | 65 + .../symfony/process/Pipes/AbstractPipes.php | 74 + .../symfony/process/Pipes/PipesInterface.php | 60 + vendor/symfony/process/Pipes/UnixPipes.php | 214 + vendor/symfony/process/Pipes/WindowsPipes.php | 253 + vendor/symfony/process/Process.php | 1504 ++ vendor/symfony/process/ProcessBuilder.php | 287 + vendor/symfony/process/ProcessUtils.php | 115 + vendor/symfony/process/README.md | 65 + .../process/Tests/AbstractProcessTest.php | 1208 ++ .../process/Tests/ExecutableFinderTest.php | 144 + .../process/Tests/NonStopableProcess.php | 45 + .../process/Tests/PhpExecutableFinderTest.php | 97 + .../symfony/process/Tests/PhpProcessTest.php | 49 + .../PipeStdinInStdoutStdErrStreamSelect.php | 72 + .../process/Tests/ProcessBuilderTest.php | 225 + .../Tests/ProcessFailedExceptionTest.php | 136 + .../Tests/ProcessInSigchildEnvironment.php | 22 + .../process/Tests/ProcessUtilsTest.php | 48 + .../Tests/SigchildDisabledProcessTest.php | 263 + .../Tests/SigchildEnabledProcessTest.php | 148 + .../symfony/process/Tests/SignalListener.php | 25 + .../process/Tests/SimpleProcessTest.php | 225 + vendor/symfony/process/composer.json | 30 + vendor/symfony/process/phpunit.xml.dist | 27 + vendor/symfony/security-core/.gitignore | 3 + .../AuthenticationManagerInterface.php | 35 + .../AuthenticationProviderManager.php | 118 + .../AuthenticationTrustResolver.php | 73 + .../AuthenticationTrustResolverInterface.php | 53 + .../AnonymousAuthenticationProvider.php | 60 + .../AuthenticationProviderInterface.php | 35 + .../Provider/DaoAuthenticationProvider.php | 99 + ...PreAuthenticatedAuthenticationProvider.php | 80 + .../RememberMeAuthenticationProvider.php | 68 + .../Provider/SimpleAuthenticationProvider.php | 50 + .../Provider/UserAuthenticationProvider.php | 155 + .../RememberMe/InMemoryTokenProvider.php | 71 + .../RememberMe/PersistentToken.php | 99 + .../RememberMe/PersistentTokenInterface.php | 56 + .../RememberMe/TokenProviderInterface.php | 58 + .../SimpleAuthenticatorInterface.php | 25 + .../SimpleFormAuthenticatorInterface.php | 22 + .../SimplePreAuthenticatorInterface.php | 22 + .../Authentication/Token/AbstractToken.php | 288 + .../Authentication/Token/AnonymousToken.php | 75 + .../Token/PreAuthenticatedToken.php | 95 + .../Authentication/Token/RememberMeToken.php | 114 + .../Token/Storage/TokenStorage.php | 43 + .../Token/Storage/TokenStorageInterface.php | 36 + .../Authentication/Token/TokenInterface.php | 131 + .../Token/UsernamePasswordToken.php | 107 + .../security-core/AuthenticationEvents.php | 38 + .../Authorization/AccessDecisionManager.php | 219 + .../AccessDecisionManagerInterface.php | 51 + .../Authorization/AuthorizationChecker.php | 70 + .../AuthorizationCheckerInterface.php | 30 + .../Authorization/ExpressionLanguage.php | 33 + .../ExpressionLanguageProvider.php | 58 + .../Authorization/Voter/AbstractVoter.php | 113 + .../Voter/AuthenticatedVoter.php | 94 + .../Authorization/Voter/ExpressionVoter.php | 118 + .../Voter/RoleHierarchyVoter.php | 41 + .../Authorization/Voter/RoleVoter.php | 79 + .../Authorization/Voter/VoterInterface.php | 58 + .../Encoder/BCryptPasswordEncoder.php | 91 + .../Encoder/BasePasswordEncoder.php | 100 + .../Encoder/EncoderAwareInterface.php | 28 + .../security-core/Encoder/EncoderFactory.php | 83 + .../Encoder/EncoderFactoryInterface.php | 33 + .../Encoder/MessageDigestPasswordEncoder.php | 72 + .../Encoder/PasswordEncoderInterface.php | 41 + .../Encoder/Pbkdf2PasswordEncoder.php | 103 + .../Encoder/PlaintextPasswordEncoder.php | 64 + .../Encoder/UserPasswordEncoder.php | 55 + .../Encoder/UserPasswordEncoderInterface.php | 40 + .../Event/AuthenticationEvent.php | 35 + .../Event/AuthenticationFailureEvent.php | 37 + .../Exception/AccessDeniedException.php | 25 + .../Exception/AccountExpiredException.php | 29 + .../Exception/AccountStatusException.php | 67 + ...enticationCredentialsNotFoundException.php | 30 + .../Exception/AuthenticationException.php | 87 + .../AuthenticationServiceException.php | 29 + .../Exception/BadCredentialsException.php | 29 + .../Exception/CookieTheftException.php | 30 + .../Exception/CredentialsExpiredException.php | 29 + .../Exception/DisabledException.php | 29 + .../Exception/ExceptionInterface.php | 21 + .../InsufficientAuthenticationException.php | 31 + .../Exception/InvalidArgumentException.php | 21 + .../Exception/InvalidCsrfTokenException.php | 29 + .../Exception/LockedException.php | 29 + .../Exception/LogoutException.php | 25 + .../Exception/NonceExpiredException.php | 30 + .../Exception/ProviderNotFoundException.php | 30 + .../Exception/RuntimeException.php | 21 + .../Exception/SessionUnavailableException.php | 35 + .../Exception/TokenNotFoundException.php | 29 + .../Exception/UnsupportedUserException.php | 22 + .../Exception/UsernameNotFoundException.php | 80 + vendor/symfony/security-core/LICENSE | 19 + vendor/symfony/security-core/README.md | 23 + .../Resources/translations/security.ar.xlf | 71 + .../Resources/translations/security.az.xlf | 71 + .../Resources/translations/security.bg.xlf | 71 + .../Resources/translations/security.ca.xlf | 71 + .../Resources/translations/security.cs.xlf | 71 + .../Resources/translations/security.da.xlf | 71 + .../Resources/translations/security.de.xlf | 71 + .../Resources/translations/security.el.xlf | 71 + .../Resources/translations/security.en.xlf | 71 + .../Resources/translations/security.es.xlf | 71 + .../Resources/translations/security.fa.xlf | 71 + .../Resources/translations/security.fr.xlf | 71 + .../Resources/translations/security.gl.xlf | 71 + .../Resources/translations/security.he.xlf | 71 + .../Resources/translations/security.hr.xlf | 71 + .../Resources/translations/security.hu.xlf | 71 + .../Resources/translations/security.id.xlf | 71 + .../Resources/translations/security.it.xlf | 71 + .../Resources/translations/security.ja.xlf | 71 + .../Resources/translations/security.lb.xlf | 71 + .../Resources/translations/security.lt.xlf | 71 + .../Resources/translations/security.nl.xlf | 71 + .../Resources/translations/security.no.xlf | 71 + .../Resources/translations/security.pl.xlf | 71 + .../Resources/translations/security.pt_BR.xlf | 71 + .../Resources/translations/security.pt_PT.xlf | 71 + .../Resources/translations/security.ro.xlf | 71 + .../Resources/translations/security.ru.xlf | 71 + .../Resources/translations/security.sk.xlf | 71 + .../Resources/translations/security.sl.xlf | 71 + .../translations/security.sr_Cyrl.xlf | 71 + .../translations/security.sr_Latn.xlf | 71 + .../Resources/translations/security.sv.xlf | 71 + .../Resources/translations/security.th.xlf | 71 + .../Resources/translations/security.tr.xlf | 71 + .../Resources/translations/security.ua.xlf | 71 + .../Resources/translations/security.vi.xlf | 71 + .../Resources/translations/security.zh_CN.xlf | 71 + vendor/symfony/security-core/Role/Role.php | 41 + .../security-core/Role/RoleHierarchy.php | 73 + .../Role/RoleHierarchyInterface.php | 32 + .../security-core/Role/RoleInterface.php | 35 + .../security-core/Role/SwitchUserRole.php | 48 + vendor/symfony/security-core/Security.php | 24 + .../symfony/security-core/SecurityContext.php | 104 + .../SecurityContextInterface.php | 29 + .../AuthenticationProviderManagerTest.php | 148 + .../AuthenticationTrustResolverTest.php | 70 + .../AnonymousAuthenticationProviderTest.php | 66 + .../DaoAuthenticationProviderTest.php | 300 + ...uthenticatedAuthenticationProviderTest.php | 134 + .../RememberMeAuthenticationProviderTest.php | 107 + .../UserAuthenticationProviderTest.php | 250 + .../RememberMe/InMemoryTokenProviderTest.php | 63 + .../RememberMe/PersistentTokenTest.php | 29 + .../Token/AbstractTokenTest.php | 287 + .../Token/AnonymousTokenTest.php | 45 + .../Token/PreAuthenticatedTokenTest.php | 48 + .../Token/RememberMeTokenTest.php | 66 + .../Token/Storage/TokenStorageTest.php | 26 + .../Token/UsernamePasswordTokenTest.php | 58 + .../AccessDecisionManagerTest.php | 198 + .../AuthorizationCheckerTest.php | 99 + .../Authorization/ExpressionLanguageTest.php | 79 + .../Authorization/Voter/AbstractVoterTest.php | 74 + .../Voter/AuthenticatedVoterTest.php | 78 + .../Voter/ExpressionVoterTest.php | 97 + .../Voter/RoleHierarchyVoterTest.php | 36 + .../Authorization/Voter/RoleVoterTest.php | 61 + .../Encoder/BCryptPasswordEncoderTest.php | 79 + .../Tests/Encoder/BasePasswordEncoderTest.php | 101 + .../Tests/Encoder/EncoderFactoryTest.php | 168 + .../MessageDigestPasswordEncoderTest.php | 62 + .../Encoder/Pbkdf2PasswordEncoderTest.php | 62 + .../Encoder/PlaintextPasswordEncoderTest.php | 56 + .../Tests/Encoder/UserPasswordEncoderTest.php | 70 + .../UsernameNotFoundExceptionTest.php | 25 + .../LegacySecurityContextInterfaceTest.php | 31 + .../Tests/LegacySecurityContextTest.php | 122 + .../Tests/Role/RoleHierarchyTest.php | 32 + .../security-core/Tests/Role/RoleTest.php | 24 + .../Tests/Role/SwitchUserRoleTest.php | 31 + .../Tests/User/ChainUserProviderTest.php | 183 + .../Tests/User/InMemoryUserProviderTest.php | 83 + .../Tests/User/UserCheckerTest.php | 108 + .../security-core/Tests/User/UserTest.php | 135 + .../Tests/Util/ClassUtilsTest.php | 50 + .../Tests/Util/SecureRandomTest.php | 201 + .../Tests/Util/StringUtilsTest.php | 61 + .../LegacyUserPasswordValidatorTest.php | 28 + .../Constraints/UserPasswordValidatorTest.php | 169 + .../User/AdvancedUserInterface.php | 87 + .../security-core/User/ChainUserProvider.php | 100 + .../security-core/User/EquatableInterface.php | 37 + .../User/InMemoryUserProvider.php | 117 + vendor/symfony/security-core/User/User.php | 120 + .../security-core/User/UserChecker.php | 69 + .../User/UserCheckerInterface.php | 36 + .../security-core/User/UserInterface.php | 87 + .../User/UserProviderInterface.php | 76 + .../symfony/security-core/Util/ClassUtils.php | 65 + .../security-core/Util/SecureRandom.php | 116 + .../Util/SecureRandomInterface.php | 29 + .../security-core/Util/StringUtils.php | 93 + .../Validator/Constraints/UserPassword.php | 32 + .../Constraints/UserPasswordValidator.php | 54 + vendor/symfony/security-core/composer.json | 46 + vendor/symfony/security-core/phpunit.xml.dist | 33 + vendor/symfony/translation/.gitignore | 3 + vendor/symfony/translation/CHANGELOG.md | 47 + .../Catalogue/AbstractOperation.php | 146 + .../translation/Catalogue/DiffOperation.php | 55 + .../translation/Catalogue/MergeOperation.php | 51 + .../Catalogue/OperationInterface.php | 63 + .../TranslationDataCollector.php | 145 + .../translation/DataCollectorTranslator.php | 148 + .../translation/Dumper/CsvFileDumper.php | 63 + .../translation/Dumper/DumperInterface.php | 31 + .../symfony/translation/Dumper/FileDumper.php | 122 + .../translation/Dumper/IcuResFileDumper.php | 112 + .../translation/Dumper/IniFileDumper.php | 45 + .../translation/Dumper/JsonFileDumper.php | 38 + .../translation/Dumper/MoFileDumper.php | 82 + .../translation/Dumper/PhpFileDumper.php | 40 + .../translation/Dumper/PoFileDumper.php | 61 + .../translation/Dumper/QtFileDumper.php | 50 + .../translation/Dumper/XliffFileDumper.php | 109 + .../translation/Dumper/YamlFileDumper.php | 43 + .../Exception/ExceptionInterface.php | 21 + .../Exception/InvalidResourceException.php | 21 + .../Exception/NotFoundResourceException.php | 21 + .../Extractor/AbstractFileExtractor.php | 83 + .../translation/Extractor/ChainExtractor.php | 60 + .../Extractor/ExtractorInterface.php | 38 + .../translation/IdentityTranslator.php | 65 + vendor/symfony/translation/Interval.php | 107 + vendor/symfony/translation/LICENSE | 19 + .../translation/Loader/ArrayLoader.php | 66 + .../translation/Loader/CsvFileLoader.php | 81 + .../translation/Loader/IcuDatFileLoader.php | 62 + .../translation/Loader/IcuResFileLoader.php | 92 + .../translation/Loader/IniFileLoader.php | 48 + .../translation/Loader/JsonFileLoader.php | 81 + .../translation/Loader/LoaderInterface.php | 38 + .../translation/Loader/MoFileLoader.php | 191 + .../translation/Loader/PhpFileLoader.php | 48 + .../translation/Loader/PoFileLoader.php | 180 + .../translation/Loader/QtFileLoader.php | 77 + .../translation/Loader/XliffFileLoader.php | 184 + .../translation/Loader/YamlFileLoader.php | 74 + .../dic/xliff-core/xliff-core-1.2-strict.xsd | 2223 +++ .../Loader/schema/dic/xliff-core/xml.xsd | 309 + .../symfony/translation/LoggingTranslator.php | 124 + .../symfony/translation/MessageCatalogue.php | 270 + .../translation/MessageCatalogueInterface.php | 142 + .../symfony/translation/MessageSelector.php | 86 + .../translation/MetadataAwareInterface.php | 54 + .../translation/PluralizationRules.php | 214 + vendor/symfony/translation/README.md | 37 + .../Tests/Catalogue/AbstractOperationTest.php | 73 + .../Tests/Catalogue/DiffOperationTest.php | 82 + .../Tests/Catalogue/MergeOperationTest.php | 83 + .../TranslationDataCollectorTest.php | 121 + .../Tests/DataCollectorTranslatorTest.php | 75 + .../Tests/Dumper/CsvFileDumperTest.php | 33 + .../Tests/Dumper/FileDumperTest.php | 70 + .../Tests/Dumper/IcuResFileDumperTest.php | 37 + .../Tests/Dumper/IniFileDumperTest.php | 32 + .../Tests/Dumper/JsonFileDumperTest.php | 36 + .../Tests/Dumper/MoFileDumperTest.php | 31 + .../Tests/Dumper/PhpFileDumperTest.php | 32 + .../Tests/Dumper/PoFileDumperTest.php | 31 + .../Tests/Dumper/QtFileDumperTest.php | 32 + .../Tests/Dumper/XliffFileDumperTest.php | 41 + .../Tests/Dumper/YamlFileDumperTest.php | 32 + .../Tests/IdentityTranslatorTest.php | 95 + .../translation/Tests/IntervalTest.php | 48 + .../Tests/Loader/CsvFileLoaderTest.php | 60 + .../Tests/Loader/IcuDatFileLoaderTest.php | 64 + .../Tests/Loader/IcuResFileLoaderTest.php | 51 + .../Tests/Loader/IniFileLoaderTest.php | 50 + .../Tests/Loader/JsonFileLoaderTest.php | 61 + .../Tests/Loader/LocalizedTestCase.php | 22 + .../Tests/Loader/MoFileLoaderTest.php | 71 + .../Tests/Loader/PhpFileLoaderTest.php | 49 + .../Tests/Loader/PoFileLoaderTest.php | 96 + .../Tests/Loader/QtFileLoaderTest.php | 67 + .../Tests/Loader/XliffFileLoaderTest.php | 142 + .../Tests/Loader/YamlFileLoaderTest.php | 70 + .../Tests/LoggingTranslatorTest.php | 49 + .../Tests/MessageCatalogueTest.php | 214 + .../translation/Tests/MessageSelectorTest.php | 130 + .../Tests/PluralizationRulesTest.php | 123 + .../translation/Tests/TranslatorCacheTest.php | 299 + .../translation/Tests/TranslatorTest.php | 627 + .../Tests/fixtures/empty-translation.mo | Bin 0 -> 49 bytes .../Tests/fixtures/empty-translation.po | 3 + .../translation/Tests/fixtures/empty.csv | 0 .../translation/Tests/fixtures/empty.ini | 0 .../translation/Tests/fixtures/empty.json | 0 .../translation/Tests/fixtures/empty.mo | 0 .../translation/Tests/fixtures/empty.po | 0 .../translation/Tests/fixtures/empty.xlf | 0 .../translation/Tests/fixtures/empty.yml | 0 .../translation/Tests/fixtures/encoding.xlf | 16 + .../Tests/fixtures/escaped-id-plurals.po | 10 + .../translation/Tests/fixtures/escaped-id.po | 8 + .../Tests/fixtures/invalid-xml-resources.xlf | 23 + .../translation/Tests/fixtures/malformed.json | 3 + .../translation/Tests/fixtures/non-valid.xlf | 11 + .../translation/Tests/fixtures/non-valid.yml | 1 + .../translation/Tests/fixtures/plurals.mo | Bin 0 -> 74 bytes .../translation/Tests/fixtures/plurals.po | 5 + .../translation/Tests/fixtures/resname.xlf | 19 + .../resourcebundle/corrupted/resources.dat | 1 + .../Tests/fixtures/resourcebundle/dat/en.res | Bin 0 -> 120 bytes .../Tests/fixtures/resourcebundle/dat/en.txt | 3 + .../Tests/fixtures/resourcebundle/dat/fr.res | Bin 0 -> 124 bytes .../Tests/fixtures/resourcebundle/dat/fr.txt | 3 + .../resourcebundle/dat/packagelist.txt | 2 + .../fixtures/resourcebundle/dat/resources.dat | Bin 0 -> 352 bytes .../Tests/fixtures/resourcebundle/res/en.res | Bin 0 -> 84 bytes .../Tests/fixtures/resources-clean.xlf | 22 + .../translation/Tests/fixtures/resources.csv | 4 + .../translation/Tests/fixtures/resources.ini | 1 + .../translation/Tests/fixtures/resources.json | 3 + .../translation/Tests/fixtures/resources.mo | Bin 0 -> 52 bytes .../translation/Tests/fixtures/resources.php | 5 + .../translation/Tests/fixtures/resources.po | 8 + .../translation/Tests/fixtures/resources.ts | 10 + .../translation/Tests/fixtures/resources.xlf | 23 + .../translation/Tests/fixtures/resources.yml | 1 + .../translation/Tests/fixtures/valid.csv | 4 + .../Tests/fixtures/withdoctype.xlf | 12 + .../translation/Tests/fixtures/withnote.xlf | 22 + vendor/symfony/translation/Translator.php | 478 + .../translation/TranslatorBagInterface.php | 31 + .../translation/TranslatorInterface.php | 65 + .../translation/Writer/TranslationWriter.php | 87 + vendor/symfony/translation/composer.json | 44 + vendor/symfony/translation/phpunit.xml.dist | 28 + vendor/symfony/var-dumper/.gitignore | 3 + vendor/symfony/var-dumper/CHANGELOG.md | 7 + .../symfony/var-dumper/Caster/AmqpCaster.php | 164 + vendor/symfony/var-dumper/Caster/Caster.php | 116 + .../symfony/var-dumper/Caster/ConstStub.php | 28 + vendor/symfony/var-dumper/Caster/CutStub.php | 56 + .../symfony/var-dumper/Caster/DOMCaster.php | 302 + .../var-dumper/Caster/DoctrineCaster.php | 60 + .../var-dumper/Caster/ExceptionCaster.php | 137 + .../symfony/var-dumper/Caster/MongoCaster.php | 34 + .../symfony/var-dumper/Caster/PdoCaster.php | 114 + .../var-dumper/Caster/ReflectionCaster.php | 244 + .../var-dumper/Caster/ResourceCaster.php | 67 + .../symfony/var-dumper/Caster/SplCaster.php | 102 + .../symfony/var-dumper/Caster/StubCaster.php | 46 + .../var-dumper/Caster/XmlResourceCaster.php | 61 + .../var-dumper/Cloner/AbstractCloner.php | 305 + .../var-dumper/Cloner/ClonerInterface.php | 27 + vendor/symfony/var-dumper/Cloner/Cursor.php | 41 + vendor/symfony/var-dumper/Cloner/Data.php | 241 + .../var-dumper/Cloner/DumperInterface.php | 60 + vendor/symfony/var-dumper/Cloner/Stub.php | 40 + .../symfony/var-dumper/Cloner/VarCloner.php | 300 + .../var-dumper/Dumper/AbstractDumper.php | 222 + .../symfony/var-dumper/Dumper/CliDumper.php | 473 + .../var-dumper/Dumper/DataDumperInterface.php | 29 + .../symfony/var-dumper/Dumper/HtmlDumper.php | 475 + .../Exception/ThrowingCasterException.php | 27 + vendor/symfony/var-dumper/LICENSE | 19 + vendor/symfony/var-dumper/README.md | 14 + .../var-dumper/Resources/functions/dump.php | 24 + .../var-dumper/Test/VarDumperTestCase.php | 44 + .../var-dumper/Test/VarDumperTestTrait.php | 45 + .../var-dumper/Tests/Caster/CasterTest.php | 178 + .../var-dumper/Tests/Caster/PdoCasterTest.php | 55 + .../Tests/Caster/ReflectionCasterTest.php | 84 + .../var-dumper/Tests/CliDumperTest.php | 386 + .../var-dumper/Tests/Fixtures/dumb-var.php | 40 + .../var-dumper/Tests/HtmlDumperTest.php | 152 + .../Tests/Test/VarDumpTestTraitRequire54.php | 41 + .../Tests/Test/VarDumpTestTraitTest.php | 16 + .../var-dumper/Tests/VarClonerTest.php | 187 + vendor/symfony/var-dumper/VarDumper.php | 52 + vendor/symfony/var-dumper/composer.json | 34 + vendor/symfony/var-dumper/phpunit.xml.dist | 29 + vendor/symfony/yaml/.gitignore | 3 + vendor/symfony/yaml/CHANGELOG.md | 8 + vendor/symfony/yaml/Dumper.php | 73 + vendor/symfony/yaml/Escaper.php | 97 + .../symfony/yaml/Exception/DumpException.php | 21 + .../yaml/Exception/ExceptionInterface.php | 21 + .../symfony/yaml/Exception/ParseException.php | 146 + .../yaml/Exception/RuntimeException.php | 21 + vendor/symfony/yaml/Inline.php | 546 + vendor/symfony/yaml/LICENSE | 19 + vendor/symfony/yaml/Parser.php | 712 + vendor/symfony/yaml/README.md | 21 + vendor/symfony/yaml/Tests/DumperTest.php | 236 + .../yaml/Tests/Fixtures/YtsAnchorAlias.yml | 31 + .../yaml/Tests/Fixtures/YtsBasicTests.yml | 202 + .../yaml/Tests/Fixtures/YtsBlockMapping.yml | 51 + .../Tests/Fixtures/YtsDocumentSeparator.yml | 85 + .../yaml/Tests/Fixtures/YtsErrorTests.yml | 25 + .../Tests/Fixtures/YtsFlowCollections.yml | 60 + .../yaml/Tests/Fixtures/YtsFoldedScalars.yml | 176 + .../Tests/Fixtures/YtsNullsAndEmpties.yml | 45 + .../Fixtures/YtsSpecificationExamples.yml | 1697 ++ .../yaml/Tests/Fixtures/YtsTypeTransfers.yml | 244 + .../yaml/Tests/Fixtures/embededPhp.yml | 1 + .../yaml/Tests/Fixtures/escapedCharacters.yml | 147 + vendor/symfony/yaml/Tests/Fixtures/index.yml | 18 + .../yaml/Tests/Fixtures/sfComments.yml | 76 + .../symfony/yaml/Tests/Fixtures/sfCompact.yml | 159 + .../yaml/Tests/Fixtures/sfMergeKey.yml | 58 + .../symfony/yaml/Tests/Fixtures/sfObjects.yml | 11 + .../symfony/yaml/Tests/Fixtures/sfQuotes.yml | 33 + .../symfony/yaml/Tests/Fixtures/sfTests.yml | 149 + .../Tests/Fixtures/unindentedCollections.yml | 82 + vendor/symfony/yaml/Tests/InlineTest.php | 384 + .../symfony/yaml/Tests/ParseExceptionTest.php | 41 + vendor/symfony/yaml/Tests/ParserTest.php | 796 + vendor/symfony/yaml/Tests/YamlTest.php | 37 + vendor/symfony/yaml/Unescaper.php | 147 + vendor/symfony/yaml/Yaml.php | 99 + vendor/symfony/yaml/composer.json | 30 + vendor/symfony/yaml/phpunit.xml.dist | 28 + vendor/twig/twig/.editorconfig | 18 + vendor/twig/twig/.gitignore | 5 + vendor/twig/twig/.travis.yml | 39 + vendor/twig/twig/CHANGELOG | 806 + vendor/twig/twig/LICENSE | 31 + vendor/twig/twig/README.rst | 15 + vendor/twig/twig/composer.json | 46 + vendor/twig/twig/doc/advanced.rst | 872 + vendor/twig/twig/doc/advanced_legacy.rst | 887 + vendor/twig/twig/doc/api.rst | 552 + vendor/twig/twig/doc/coding_standards.rst | 101 + vendor/twig/twig/doc/deprecated.rst | 160 + vendor/twig/twig/doc/filters/abs.rst | 18 + vendor/twig/twig/doc/filters/batch.rst | 51 + vendor/twig/twig/doc/filters/capitalize.rst | 11 + .../twig/doc/filters/convert_encoding.rst | 28 + vendor/twig/twig/doc/filters/date.rst | 94 + vendor/twig/twig/doc/filters/date_modify.rst | 23 + vendor/twig/twig/doc/filters/default.rst | 33 + vendor/twig/twig/doc/filters/escape.rst | 116 + vendor/twig/twig/doc/filters/first.rst | 25 + vendor/twig/twig/doc/filters/format.rst | 16 + vendor/twig/twig/doc/filters/index.rst | 37 + vendor/twig/twig/doc/filters/join.rst | 23 + vendor/twig/twig/doc/filters/json_encode.rst | 21 + vendor/twig/twig/doc/filters/keys.rst | 11 + vendor/twig/twig/doc/filters/last.rst | 25 + vendor/twig/twig/doc/filters/length.rst | 11 + vendor/twig/twig/doc/filters/lower.rst | 10 + vendor/twig/twig/doc/filters/merge.rst | 48 + vendor/twig/twig/doc/filters/nl2br.rst | 22 + .../twig/twig/doc/filters/number_format.rst | 45 + vendor/twig/twig/doc/filters/raw.rst | 36 + vendor/twig/twig/doc/filters/replace.rst | 19 + vendor/twig/twig/doc/filters/reverse.rst | 47 + vendor/twig/twig/doc/filters/round.rst | 37 + vendor/twig/twig/doc/filters/slice.rst | 71 + vendor/twig/twig/doc/filters/sort.rst | 18 + vendor/twig/twig/doc/filters/split.rst | 53 + vendor/twig/twig/doc/filters/striptags.rst | 15 + vendor/twig/twig/doc/filters/title.rst | 11 + vendor/twig/twig/doc/filters/trim.rst | 29 + vendor/twig/twig/doc/filters/upper.rst | 10 + vendor/twig/twig/doc/filters/url_encode.rst | 34 + vendor/twig/twig/doc/functions/attribute.rst | 26 + vendor/twig/twig/doc/functions/block.rst | 15 + vendor/twig/twig/doc/functions/constant.rst | 18 + vendor/twig/twig/doc/functions/cycle.rst | 28 + vendor/twig/twig/doc/functions/date.rst | 52 + vendor/twig/twig/doc/functions/dump.rst | 69 + vendor/twig/twig/doc/functions/include.rst | 80 + vendor/twig/twig/doc/functions/index.rst | 20 + vendor/twig/twig/doc/functions/max.rst | 20 + vendor/twig/twig/doc/functions/min.rst | 20 + vendor/twig/twig/doc/functions/parent.rst | 20 + vendor/twig/twig/doc/functions/random.rst | 29 + vendor/twig/twig/doc/functions/range.rst | 45 + vendor/twig/twig/doc/functions/source.rst | 32 + .../doc/functions/template_from_string.rst | 32 + vendor/twig/twig/doc/index.rst | 19 + vendor/twig/twig/doc/installation.rst | 116 + vendor/twig/twig/doc/internals.rst | 138 + vendor/twig/twig/doc/intro.rst | 85 + vendor/twig/twig/doc/recipes.rst | 518 + vendor/twig/twig/doc/tags/autoescape.rst | 83 + vendor/twig/twig/doc/tags/block.rst | 11 + vendor/twig/twig/doc/tags/do.rst | 12 + vendor/twig/twig/doc/tags/embed.rst | 178 + vendor/twig/twig/doc/tags/extends.rst | 268 + vendor/twig/twig/doc/tags/filter.rst | 21 + vendor/twig/twig/doc/tags/flush.rst | 17 + vendor/twig/twig/doc/tags/for.rst | 172 + vendor/twig/twig/doc/tags/from.rst | 8 + vendor/twig/twig/doc/tags/if.rst | 76 + vendor/twig/twig/doc/tags/import.rst | 57 + vendor/twig/twig/doc/tags/include.rst | 86 + vendor/twig/twig/doc/tags/index.rst | 24 + vendor/twig/twig/doc/tags/macro.rst | 86 + vendor/twig/twig/doc/tags/sandbox.rst | 30 + vendor/twig/twig/doc/tags/set.rst | 78 + vendor/twig/twig/doc/tags/spaceless.rst | 37 + vendor/twig/twig/doc/tags/use.rst | 124 + vendor/twig/twig/doc/tags/verbatim.rst | 24 + vendor/twig/twig/doc/templates.rst | 900 + vendor/twig/twig/doc/tests/constant.rst | 22 + vendor/twig/twig/doc/tests/defined.rst | 30 + vendor/twig/twig/doc/tests/divisibleby.rst | 14 + vendor/twig/twig/doc/tests/empty.rst | 11 + vendor/twig/twig/doc/tests/even.rst | 10 + vendor/twig/twig/doc/tests/index.rst | 15 + vendor/twig/twig/doc/tests/iterable.rst | 19 + vendor/twig/twig/doc/tests/null.rst | 12 + vendor/twig/twig/doc/tests/odd.rst | 10 + vendor/twig/twig/doc/tests/sameas.rst | 14 + vendor/twig/twig/ext/twig/.gitignore | 30 + vendor/twig/twig/ext/twig/config.m4 | 8 + vendor/twig/twig/ext/twig/config.w32 | 8 + vendor/twig/twig/ext/twig/php_twig.h | 35 + vendor/twig/twig/ext/twig/twig.c | 1127 ++ vendor/twig/twig/lib/Twig/Autoloader.php | 54 + vendor/twig/twig/lib/Twig/BaseNodeVisitor.php | 62 + .../twig/twig/lib/Twig/Cache/Filesystem.php | 96 + vendor/twig/twig/lib/Twig/Cache/Null.php | 48 + vendor/twig/twig/lib/Twig/CacheInterface.php | 56 + vendor/twig/twig/lib/Twig/Compiler.php | 277 + .../twig/twig/lib/Twig/CompilerInterface.php | 36 + vendor/twig/twig/lib/Twig/Environment.php | 1381 ++ vendor/twig/twig/lib/Twig/Error.php | 272 + vendor/twig/twig/lib/Twig/Error/Loader.php | 31 + vendor/twig/twig/lib/Twig/Error/Runtime.php | 20 + vendor/twig/twig/lib/Twig/Error/Syntax.php | 53 + .../twig/lib/Twig/ExistsLoaderInterface.php | 29 + .../twig/twig/lib/Twig/ExpressionParser.php | 641 + vendor/twig/twig/lib/Twig/Extension.php | 79 + vendor/twig/twig/lib/Twig/Extension/Core.php | 1542 ++ vendor/twig/twig/lib/Twig/Extension/Debug.php | 61 + .../twig/twig/lib/Twig/Extension/Escaper.php | 102 + .../lib/Twig/Extension/GlobalsInterface.php | 22 + .../Twig/Extension/InitRuntimeInterface.php | 22 + .../twig/lib/Twig/Extension/Optimizer.php | 29 + .../twig/twig/lib/Twig/Extension/Profiler.php | 46 + .../twig/twig/lib/Twig/Extension/Sandbox.php | 97 + .../twig/twig/lib/Twig/Extension/Staging.php | 94 + .../twig/lib/Twig/Extension/StringLoader.php | 41 + .../twig/twig/lib/Twig/ExtensionInterface.php | 87 + .../Twig/FileExtensionEscapingStrategy.php | 58 + vendor/twig/twig/lib/Twig/Filter.php | 84 + vendor/twig/twig/lib/Twig/Filter/Function.php | 40 + vendor/twig/twig/lib/Twig/Filter/Method.php | 42 + vendor/twig/twig/lib/Twig/Filter/Node.php | 42 + .../twig/lib/Twig/FilterCallableInterface.php | 24 + vendor/twig/twig/lib/Twig/FilterInterface.php | 43 + vendor/twig/twig/lib/Twig/Function.php | 74 + .../twig/twig/lib/Twig/Function/Function.php | 41 + vendor/twig/twig/lib/Twig/Function/Method.php | 43 + vendor/twig/twig/lib/Twig/Function/Node.php | 42 + .../lib/Twig/FunctionCallableInterface.php | 24 + .../twig/twig/lib/Twig/FunctionInterface.php | 40 + vendor/twig/twig/lib/Twig/Lexer.php | 411 + vendor/twig/twig/lib/Twig/LexerInterface.php | 32 + vendor/twig/twig/lib/Twig/Loader/Array.php | 95 + vendor/twig/twig/lib/Twig/Loader/Chain.php | 138 + .../twig/twig/lib/Twig/Loader/Filesystem.php | 260 + vendor/twig/twig/lib/Twig/Loader/String.php | 63 + vendor/twig/twig/lib/Twig/LoaderInterface.php | 53 + vendor/twig/twig/lib/Twig/Markup.php | 37 + vendor/twig/twig/lib/Twig/Node.php | 231 + vendor/twig/twig/lib/Twig/Node/AutoEscape.php | 34 + vendor/twig/twig/lib/Twig/Node/Block.php | 39 + .../twig/lib/Twig/Node/BlockReference.php | 32 + vendor/twig/twig/lib/Twig/Node/Body.php | 19 + .../twig/twig/lib/Twig/Node/CheckSecurity.php | 78 + vendor/twig/twig/lib/Twig/Node/Do.php | 33 + vendor/twig/twig/lib/Twig/Node/Embed.php | 42 + vendor/twig/twig/lib/Twig/Node/Expression.php | 20 + .../twig/lib/Twig/Node/Expression/Array.php | 81 + .../lib/Twig/Node/Expression/AssignName.php | 23 + .../twig/lib/Twig/Node/Expression/Binary.php | 35 + .../lib/Twig/Node/Expression/Binary/Add.php | 18 + .../lib/Twig/Node/Expression/Binary/And.php | 18 + .../Node/Expression/Binary/BitwiseAnd.php | 18 + .../Twig/Node/Expression/Binary/BitwiseOr.php | 18 + .../Node/Expression/Binary/BitwiseXor.php | 18 + .../Twig/Node/Expression/Binary/Concat.php | 18 + .../lib/Twig/Node/Expression/Binary/Div.php | 18 + .../Twig/Node/Expression/Binary/EndsWith.php | 30 + .../lib/Twig/Node/Expression/Binary/Equal.php | 17 + .../Twig/Node/Expression/Binary/FloorDiv.php | 24 + .../Twig/Node/Expression/Binary/Greater.php | 17 + .../Node/Expression/Binary/GreaterEqual.php | 17 + .../lib/Twig/Node/Expression/Binary/In.php | 28 + .../lib/Twig/Node/Expression/Binary/Less.php | 17 + .../Twig/Node/Expression/Binary/LessEqual.php | 17 + .../Twig/Node/Expression/Binary/Matches.php | 28 + .../lib/Twig/Node/Expression/Binary/Mod.php | 18 + .../lib/Twig/Node/Expression/Binary/Mul.php | 18 + .../Twig/Node/Expression/Binary/NotEqual.php | 17 + .../lib/Twig/Node/Expression/Binary/NotIn.php | 28 + .../lib/Twig/Node/Expression/Binary/Or.php | 18 + .../lib/Twig/Node/Expression/Binary/Power.php | 28 + .../lib/Twig/Node/Expression/Binary/Range.php | 28 + .../Node/Expression/Binary/StartsWith.php | 30 + .../lib/Twig/Node/Expression/Binary/Sub.php | 18 + .../Twig/Node/Expression/BlockReference.php | 46 + .../twig/lib/Twig/Node/Expression/Call.php | 247 + .../lib/Twig/Node/Expression/Conditional.php | 31 + .../lib/Twig/Node/Expression/Constant.php | 23 + .../Node/Expression/ExtensionReference.php | 28 + .../twig/lib/Twig/Node/Expression/Filter.php | 39 + .../Twig/Node/Expression/Filter/Default.php | 43 + .../lib/Twig/Node/Expression/Function.php | 38 + .../twig/lib/Twig/Node/Expression/GetAttr.php | 63 + .../lib/Twig/Node/Expression/MethodCall.php | 41 + .../twig/lib/Twig/Node/Expression/Name.php | 98 + .../twig/lib/Twig/Node/Expression/Parent.php | 42 + .../lib/Twig/Node/Expression/TempName.php | 26 + .../twig/lib/Twig/Node/Expression/Test.php | 35 + .../Twig/Node/Expression/Test/Constant.php | 46 + .../lib/Twig/Node/Expression/Test/Defined.php | 54 + .../Twig/Node/Expression/Test/Divisibleby.php | 33 + .../lib/Twig/Node/Expression/Test/Even.php | 32 + .../lib/Twig/Node/Expression/Test/Null.php | 31 + .../lib/Twig/Node/Expression/Test/Odd.php | 32 + .../lib/Twig/Node/Expression/Test/Sameas.php | 29 + .../twig/lib/Twig/Node/Expression/Unary.php | 27 + .../lib/Twig/Node/Expression/Unary/Neg.php | 18 + .../lib/Twig/Node/Expression/Unary/Not.php | 18 + .../lib/Twig/Node/Expression/Unary/Pos.php | 18 + vendor/twig/twig/lib/Twig/Node/Flush.php | 31 + vendor/twig/twig/lib/Twig/Node/For.php | 106 + vendor/twig/twig/lib/Twig/Node/ForLoop.php | 50 + vendor/twig/twig/lib/Twig/Node/If.php | 61 + vendor/twig/twig/lib/Twig/Node/Import.php | 49 + vendor/twig/twig/lib/Twig/Node/Include.php | 83 + vendor/twig/twig/lib/Twig/Node/Macro.php | 118 + vendor/twig/twig/lib/Twig/Node/Module.php | 403 + vendor/twig/twig/lib/Twig/Node/Print.php | 34 + vendor/twig/twig/lib/Twig/Node/Sandbox.php | 42 + .../twig/lib/Twig/Node/SandboxedPrint.php | 56 + vendor/twig/twig/lib/Twig/Node/Set.php | 96 + vendor/twig/twig/lib/Twig/Node/SetTemp.php | 35 + vendor/twig/twig/lib/Twig/Node/Spaceless.php | 35 + vendor/twig/twig/lib/Twig/Node/Text.php | 34 + vendor/twig/twig/lib/Twig/NodeInterface.php | 31 + .../twig/lib/Twig/NodeOutputInterface.php | 19 + vendor/twig/twig/lib/Twig/NodeTraverser.php | 89 + .../twig/lib/Twig/NodeVisitor/Escaper.php | 157 + .../twig/lib/Twig/NodeVisitor/Optimizer.php | 271 + .../lib/Twig/NodeVisitor/SafeAnalysis.php | 154 + .../twig/lib/Twig/NodeVisitor/Sandbox.php | 82 + .../twig/lib/Twig/NodeVisitorInterface.php | 47 + vendor/twig/twig/lib/Twig/Parser.php | 396 + vendor/twig/twig/lib/Twig/ParserInterface.php | 31 + .../lib/Twig/Profiler/Dumper/Blackfire.php | 68 + .../twig/lib/Twig/Profiler/Dumper/Html.php | 43 + .../twig/lib/Twig/Profiler/Dumper/Text.php | 68 + .../lib/Twig/Profiler/Node/EnterProfile.php | 40 + .../lib/Twig/Profiler/Node/LeaveProfile.php | 34 + .../Twig/Profiler/NodeVisitor/Profiler.php | 72 + .../twig/twig/lib/Twig/Profiler/Profile.php | 160 + .../twig/lib/Twig/Sandbox/SecurityError.php | 19 + .../Sandbox/SecurityNotAllowedFilterError.php | 31 + .../SecurityNotAllowedFunctionError.php | 31 + .../Sandbox/SecurityNotAllowedTagError.php | 31 + .../twig/lib/Twig/Sandbox/SecurityPolicy.php | 119 + .../Twig/Sandbox/SecurityPolicyInterface.php | 24 + vendor/twig/twig/lib/Twig/SimpleFilter.php | 112 + vendor/twig/twig/lib/Twig/SimpleFunction.php | 102 + vendor/twig/twig/lib/Twig/SimpleTest.php | 64 + vendor/twig/twig/lib/Twig/Template.php | 614 + .../twig/twig/lib/Twig/TemplateInterface.php | 48 + vendor/twig/twig/lib/Twig/Test.php | 37 + vendor/twig/twig/lib/Twig/Test/Function.php | 38 + .../lib/Twig/Test/IntegrationTestCase.php | 230 + vendor/twig/twig/lib/Twig/Test/Method.php | 40 + vendor/twig/twig/lib/Twig/Test/Node.php | 40 + .../twig/twig/lib/Twig/Test/NodeTestCase.php | 60 + .../twig/lib/Twig/TestCallableInterface.php | 22 + vendor/twig/twig/lib/Twig/TestInterface.php | 27 + vendor/twig/twig/lib/Twig/Token.php | 216 + vendor/twig/twig/lib/Twig/TokenParser.php | 33 + .../twig/lib/Twig/TokenParser/AutoEscape.php | 79 + .../twig/twig/lib/Twig/TokenParser/Block.php | 69 + vendor/twig/twig/lib/Twig/TokenParser/Do.php | 30 + .../twig/twig/lib/Twig/TokenParser/Embed.php | 54 + .../twig/lib/Twig/TokenParser/Extends.php | 40 + .../twig/twig/lib/Twig/TokenParser/Filter.php | 49 + .../twig/twig/lib/Twig/TokenParser/Flush.php | 30 + vendor/twig/twig/lib/Twig/TokenParser/For.php | 123 + .../twig/twig/lib/Twig/TokenParser/From.php | 62 + vendor/twig/twig/lib/Twig/TokenParser/If.php | 82 + .../twig/twig/lib/Twig/TokenParser/Import.php | 37 + .../twig/lib/Twig/TokenParser/Include.php | 63 + .../twig/twig/lib/Twig/TokenParser/Macro.php | 56 + .../twig/lib/Twig/TokenParser/Sandbox.php | 56 + vendor/twig/twig/lib/Twig/TokenParser/Set.php | 71 + .../twig/lib/Twig/TokenParser/Spaceless.php | 47 + vendor/twig/twig/lib/Twig/TokenParser/Use.php | 64 + .../twig/twig/lib/Twig/TokenParserBroker.php | 141 + .../lib/Twig/TokenParserBrokerInterface.php | 46 + .../twig/lib/Twig/TokenParserInterface.php | 43 + vendor/twig/twig/lib/Twig/TokenStream.php | 155 + .../lib/Twig/Util/DeprecationCollector.php | 82 + .../lib/Twig/Util/TemplateDirIterator.php | 26 + vendor/twig/twig/phpunit.xml.dist | 25 + .../twig/test/Twig/Tests/AutoloaderTest.php | 24 + .../test/Twig/Tests/Cache/FilesystemTest.php | 169 + .../twig/test/Twig/Tests/CompilerTest.php | 33 + .../twig/test/Twig/Tests/EnvironmentTest.php | 525 + .../twig/twig/test/Twig/Tests/ErrorTest.php | 144 + .../test/Twig/Tests/ExpressionParserTest.php | 368 + .../test/Twig/Tests/Extension/CoreTest.php | 158 + .../test/Twig/Tests/Extension/SandboxTest.php | 220 + .../twig/test/Twig/Tests/FileCachingTest.php | 85 + .../FileExtensionEscapingStrategyTest.php | 51 + .../Tests/Fixtures/autoescape/filename.test | 18 + .../test/Twig/Tests/Fixtures/errors/base.html | 1 + .../Twig/Tests/Fixtures/errors/index.html | 7 + ...ltiline_array_with_undefined_variable.test | 18 + ...e_array_with_undefined_variable_again.test | 18 + ...line_function_with_undefined_variable.test | 12 + ...tiline_function_with_unknown_argument.test | 9 + ...multiline_tag_with_undefined_variable.test | 12 + .../syntax_error_in_reused_template.test | 10 + .../Fixtures/exceptions/unclosed_tag.test | 20 + .../Fixtures/exceptions/undefined_parent.test | 8 + .../undefined_template_in_child_template.test | 15 + .../Fixtures/exceptions/undefined_trait.test | 9 + .../Tests/Fixtures/expressions/array.test | 61 + .../Fixtures/expressions/array_call.test | 14 + .../Tests/Fixtures/expressions/binary.test | 46 + .../Tests/Fixtures/expressions/bitwise.test | 14 + .../Fixtures/expressions/comparison.test | 14 + .../Fixtures/expressions/divisibleby.test | 17 + .../Tests/Fixtures/expressions/dotdot.test | 20 + .../Tests/Fixtures/expressions/ends_with.test | 26 + .../Tests/Fixtures/expressions/grouping.test | 8 + .../Tests/Fixtures/expressions/literals.test | 22 + .../Fixtures/expressions/magic_call.test | 27 + .../Tests/Fixtures/expressions/matches.test | 12 + .../Fixtures/expressions/method_call.test | 28 + .../expressions/negative_numbers.test | 18 + .../expressions/operators_as_variables.test | 16 + .../Tests/Fixtures/expressions/postfix.test | 22 + .../Tests/Fixtures/expressions/sameas.test | 21 + .../Fixtures/expressions/starts_with.test | 27 + .../Tests/Fixtures/expressions/strings.test | 10 + .../expressions/ternary_operator.test | 18 + .../expressions/ternary_operator_noelse.test | 10 + .../expressions/ternary_operator_nothen.test | 10 + .../two_word_operators_as_variables.test | 8 + .../Tests/Fixtures/expressions/unary.test | 12 + .../expressions/unary_macro_arguments.test | 22 + .../expressions/unary_precedence.test | 14 + .../test/Twig/Tests/Fixtures/filters/abs.test | 30 + .../Twig/Tests/Fixtures/filters/batch.test | 31 + .../Tests/Fixtures/filters/batch_float.test | 29 + .../filters/batch_with_empty_fill.test | 37 + .../filters/batch_with_exact_elements.test | 33 + .../Fixtures/filters/batch_with_fill.test | 37 + .../Fixtures/filters/batch_with_keys.test | 10 + .../filters/batch_with_zero_elements.test | 10 + .../Fixtures/filters/convert_encoding.test | 10 + .../Twig/Tests/Fixtures/filters/date.test | 90 + .../Fixtures/filters/date_default_format.test | 14 + .../filters/date_default_format_interval.test | 16 + .../Fixtures/filters/date_immutable.test | 37 + .../Tests/Fixtures/filters/date_interval.test | 19 + .../Tests/Fixtures/filters/date_modify.test | 14 + .../Fixtures/filters/date_namedargs.test | 13 + .../Twig/Tests/Fixtures/filters/default.test | 150 + .../Fixtures/filters/dynamic_filter.test | 10 + .../Twig/Tests/Fixtures/filters/escape.test | 8 + .../Fixtures/filters/escape_html_attr.test | 8 + .../filters/escape_non_supported_charset.test | 8 + .../Twig/Tests/Fixtures/filters/first.test | 17 + .../Tests/Fixtures/filters/force_escape.test | 18 + .../Twig/Tests/Fixtures/filters/format.test | 8 + .../Twig/Tests/Fixtures/filters/join.test | 12 + .../Tests/Fixtures/filters/json_encode.test | 12 + .../Twig/Tests/Fixtures/filters/last.test | 17 + .../Twig/Tests/Fixtures/filters/length.test | 14 + .../Tests/Fixtures/filters/length_utf8.test | 12 + .../Twig/Tests/Fixtures/filters/merge.test | 18 + .../Twig/Tests/Fixtures/filters/nl2br.test | 14 + .../Tests/Fixtures/filters/number_format.test | 18 + .../filters/number_format_default.test | 21 + .../Twig/Tests/Fixtures/filters/replace.test | 12 + .../Fixtures/filters/replace_invalid_arg.test | 8 + .../Twig/Tests/Fixtures/filters/reverse.test | 18 + .../Twig/Tests/Fixtures/filters/round.test | 22 + .../Twig/Tests/Fixtures/filters/slice.test | 54 + .../Twig/Tests/Fixtures/filters/sort.test | 12 + .../Tests/Fixtures/filters/special_chars.test | 8 + .../Twig/Tests/Fixtures/filters/split.test | 20 + .../Tests/Fixtures/filters/split_utf8.test | 24 + .../Twig/Tests/Fixtures/filters/trim.test | 12 + .../Tests/Fixtures/filters/urlencode.test | 16 + .../filters/urlencode_deprecated.test | 16 + .../Tests/Fixtures/functions/attribute.test | 18 + .../Twig/Tests/Fixtures/functions/block.test | 12 + .../Tests/Fixtures/functions/constant.test | 10 + .../Twig/Tests/Fixtures/functions/cycle.test | 16 + .../Twig/Tests/Fixtures/functions/date.test | 25 + .../Fixtures/functions/date_namedargs.test | 11 + .../Twig/Tests/Fixtures/functions/dump.test | 16 + .../Tests/Fixtures/functions/dump_array.test | 19 + .../Fixtures/functions/dynamic_function.test | 10 + .../functions/include/assignment.test | 13 + .../functions/include/autoescaping.test | 10 + .../Fixtures/functions/include/basic.test | 17 + .../functions/include/expression.test | 17 + .../functions/include/ignore_missing.test | 10 + .../Fixtures/functions/include/missing.test | 8 + .../functions/include/missing_nested.test | 16 + .../Fixtures/functions/include/sandbox.test | 13 + .../functions/include/sandbox_disabling.test | 16 + .../sandbox_disabling_ignore_missing.test | 13 + .../functions/include/template_instance.test | 10 + .../functions/include/templates_as_array.test | 12 + .../functions/include/with_context.test | 16 + .../functions/include/with_variables.test | 12 + .../Twig/Tests/Fixtures/functions/max.test | 12 + .../Twig/Tests/Fixtures/functions/min.test | 12 + .../Twig/Tests/Fixtures/functions/range.test | 8 + .../recursive_block_with_inheritance.test | 21 + .../Twig/Tests/Fixtures/functions/source.test | 17 + .../Fixtures/functions/special_chars.test | 8 + .../functions/template_from_string.test | 15 + .../Tests/Fixtures/macros/default_values.test | 16 + .../Tests/Fixtures/macros/nested_calls.test | 18 + .../Fixtures/macros/reserved_variables.test | 14 + .../Twig/Tests/Fixtures/macros/simple.test | 22 + .../Twig/Tests/Fixtures/macros/varargs.test | 21 + .../Fixtures/macros/varargs_argument.test | 8 + .../Tests/Fixtures/macros/with_filters.test | 14 + .../regression/combined_debug_info.test | 15 + .../Fixtures/regression/empty_token.test | 8 + .../Tests/Fixtures/regression/issue_1143.test | 23 + .../Fixtures/regression/multi_word_tests.test | 10 + .../regression/simple_xml_element.test | 19 + .../regression/strings_like_numbers.test | 8 + .../Tests/Fixtures/tags/autoescape/basic.test | 26 + .../Fixtures/tags/autoescape/blocks.test | 12 + .../tags/autoescape/double_escaping.test | 10 + .../Fixtures/tags/autoescape/functions.test | 83 + .../Fixtures/tags/autoescape/literal.test | 45 + .../Fixtures/tags/autoescape/nested.test | 26 + .../Fixtures/tags/autoescape/objects.test | 26 + .../Tests/Fixtures/tags/autoescape/raw.test | 10 + .../tags/autoescape/strategy.legacy.test | 11 + .../Fixtures/tags/autoescape/strategy.test | 11 + .../Tests/Fixtures/tags/autoescape/type.test | 69 + .../tags/autoescape/with_filters.test | 131 + .../autoescape/with_filters_arguments.test | 23 + .../autoescape/with_pre_escape_filters.test | 68 + .../with_preserves_safety_filters.test | 50 + .../Twig/Tests/Fixtures/tags/block/basic.test | 11 + .../tags/block/block_unique_name.test | 11 + .../Fixtures/tags/block/special_chars.test | 10 + .../Twig/Tests/Fixtures/tags/embed/basic.test | 35 + .../Tests/Fixtures/tags/embed/error_line.test | 16 + .../Tests/Fixtures/tags/embed/multiple.test | 50 + .../Tests/Fixtures/tags/embed/nested.test | 42 + .../Fixtures/tags/embed/with_extends.test | 57 + .../Tests/Fixtures/tags/filter/basic.test | 10 + .../Fixtures/tags/filter/json_encode.test | 8 + .../Tests/Fixtures/tags/filter/multiple.test | 10 + .../Tests/Fixtures/tags/filter/nested.test | 16 + .../Fixtures/tags/filter/with_for_tag.test | 13 + .../Fixtures/tags/filter/with_if_tag.test | 29 + .../Tests/Fixtures/tags/for/condition.test | 14 + .../Twig/Tests/Fixtures/tags/for/context.test | 18 + .../Twig/Tests/Fixtures/tags/for/else.test | 23 + .../Fixtures/tags/for/inner_variables.test | 17 + .../Twig/Tests/Fixtures/tags/for/keys.test | 11 + .../Fixtures/tags/for/keys_and_values.test | 11 + .../Tests/Fixtures/tags/for/loop_context.test | 19 + .../Fixtures/tags/for/loop_context_local.test | 10 + .../Fixtures/tags/for/loop_not_defined.test | 10 + .../tags/for/loop_not_defined_cond.test | 9 + .../Tests/Fixtures/tags/for/nested_else.test | 17 + .../Twig/Tests/Fixtures/tags/for/objects.test | 43 + .../Fixtures/tags/for/objects_countable.test | 47 + .../Tests/Fixtures/tags/for/recursive.test | 18 + .../Twig/Tests/Fixtures/tags/for/values.test | 11 + .../test/Twig/Tests/Fixtures/tags/from.test | 14 + .../Twig/Tests/Fixtures/tags/if/basic.test | 22 + .../Tests/Fixtures/tags/if/expression.test | 22 + .../Tests/Fixtures/tags/include/basic.test | 16 + .../Fixtures/tags/include/expression.test | 16 + .../Fixtures/tags/include/ignore_missing.test | 10 + .../Tests/Fixtures/tags/include/missing.test | 8 + .../Fixtures/tags/include/missing_nested.test | 16 + .../Tests/Fixtures/tags/include/only.test | 16 + .../tags/include/template_instance.test | 10 + .../tags/include/templates_as_array.test | 12 + .../Fixtures/tags/include/with_variables.test | 12 + .../Fixtures/tags/inheritance/basic.test | 14 + .../Fixtures/tags/inheritance/block_expr.test | 32 + .../tags/inheritance/block_expr2.test | 34 + .../tags/inheritance/conditional.test | 14 + .../Fixtures/tags/inheritance/dynamic.test | 14 + .../Fixtures/tags/inheritance/empty.test | 10 + .../tags/inheritance/extends_as_array.test | 12 + .../extends_as_array_with_empty_name.test | 12 + .../extends_as_array_with_null_name.test | 12 + .../Fixtures/tags/inheritance/multiple.test | 12 + .../tags/inheritance/multiple_dynamic.test | 22 + .../tags/inheritance/nested_blocks.test | 22 + .../nested_blocks_parent_only.test | 15 + .../tags/inheritance/nested_inheritance.test | 16 + .../Fixtures/tags/inheritance/parent.test | 12 + .../tags/inheritance/parent_change.test | 16 + .../tags/inheritance/parent_in_a_block.test | 8 + .../tags/inheritance/parent_isolation.test | 20 + .../tags/inheritance/parent_nested.test | 28 + .../inheritance/parent_without_extends.test | 8 + .../parent_without_extends_but_traits.test | 14 + .../tags/inheritance/template_instance.test | 14 + .../Tests/Fixtures/tags/inheritance/use.test | 44 + .../Twig/Tests/Fixtures/tags/macro/basic.test | 17 + .../Fixtures/tags/macro/endmacro_name.test | 16 + .../Tests/Fixtures/tags/macro/external.test | 17 + .../Twig/Tests/Fixtures/tags/macro/from.test | 18 + .../tags/macro/from_with_reserved_name.test | 9 + .../Tests/Fixtures/tags/macro/global.test | 14 + .../tags/macro/import_with_reserved_nam.test | 11 + .../Fixtures/tags/macro/reserved_name.test | 10 + .../Fixtures/tags/macro/self_import.test | 17 + .../Fixtures/tags/macro/special_chars.test | 14 + .../Fixtures/tags/macro/super_globals.test | 14 + .../Tests/Fixtures/tags/raw/basic.legacy.test | 10 + .../tags/raw/mixed_usage_with_raw.legacy.test | 10 + .../tags/raw/whitespace_control.legacy.test | 56 + .../Fixtures/tags/sandbox/not_valid1.test | 11 + .../Fixtures/tags/sandbox/not_valid2.test | 14 + .../Tests/Fixtures/tags/sandbox/simple.test | 22 + .../Twig/Tests/Fixtures/tags/set/basic.test | 20 + .../Fixtures/tags/set/capture-empty.test | 9 + .../Twig/Tests/Fixtures/tags/set/capture.test | 10 + .../Tests/Fixtures/tags/set/expression.test | 12 + .../Tests/Fixtures/tags/spaceless/simple.test | 12 + .../Tests/Fixtures/tags/special_chars.test | 8 + .../Twig/Tests/Fixtures/tags/trim_block.test | 74 + .../Twig/Tests/Fixtures/tags/use/aliases.test | 12 + .../Twig/Tests/Fixtures/tags/use/basic.test | 12 + .../Twig/Tests/Fixtures/tags/use/deep.test | 22 + .../Tests/Fixtures/tags/use/deep_empty.test | 10 + .../Tests/Fixtures/tags/use/inheritance.test | 25 + .../Tests/Fixtures/tags/use/inheritance2.test | 24 + .../Tests/Fixtures/tags/use/multiple.test | 21 + .../Fixtures/tags/use/multiple_aliases.test | 23 + .../Tests/Fixtures/tags/use/parent_block.test | 24 + .../Fixtures/tags/use/parent_block2.test | 24 + .../Fixtures/tags/use/parent_block3.test | 38 + .../Tests/Fixtures/tags/verbatim/basic.test | 10 + .../tags/verbatim/mixed_usage_with_raw.test | 10 + .../tags/verbatim/whitespace_control.test | 56 + .../test/Twig/Tests/Fixtures/tests/array.test | 24 + .../Twig/Tests/Fixtures/tests/constant.test | 14 + .../Twig/Tests/Fixtures/tests/defined.test | 108 + .../test/Twig/Tests/Fixtures/tests/empty.test | 45 + .../test/Twig/Tests/Fixtures/tests/even.test | 14 + .../test/Twig/Tests/Fixtures/tests/in.test | 128 + .../Tests/Fixtures/tests/in_with_objects.test | 19 + .../Twig/Tests/Fixtures/tests/iterable.test | 19 + .../test/Twig/Tests/Fixtures/tests/odd.test | 10 + .../twig/test/Twig/Tests/IntegrationTest.php | 229 + .../Tests/LegacyFixtures/test.legacy.test | 8 + .../test/Twig/Tests/LegacyIntegrationTest.php | 54 + .../twig/twig/test/Twig/Tests/LexerTest.php | 300 + .../twig/test/Twig/Tests/Loader/ArrayTest.php | 97 + .../twig/test/Twig/Tests/Loader/ChainTest.php | 79 + .../test/Twig/Tests/Loader/FilesystemTest.php | 175 + .../array_inheritance_empty_parent.html.twig | 3 + ...y_inheritance_nonexistent_parent.html.twig | 3 + .../array_inheritance_null_parent.html.twig | 3 + .../array_inheritance_valid_parent.html.twig | 3 + .../Fixtures/inheritance/parent.html.twig | 1 + .../inheritance/spare_parent.html.twig | 1 + .../Tests/Loader/Fixtures/named/index.html | 1 + .../Loader/Fixtures/named_bis/index.html | 1 + .../Loader/Fixtures/named_final/index.html | 1 + .../Fixtures/named_quater/named_absolute.html | 1 + .../Loader/Fixtures/named_ter/index.html | 1 + .../Tests/Loader/Fixtures/normal/index.html | 1 + .../Loader/Fixtures/normal_bis/index.html | 1 + .../Loader/Fixtures/normal_final/index.html | 1 + .../Loader/Fixtures/normal_ter/index.html | 1 + .../Fixtures/themes/theme1/blocks.html.twig | 3 + .../Fixtures/themes/theme2/blocks.html.twig | 3 + .../test/Twig/Tests/NativeExtensionTest.php | 33 + .../test/Twig/Tests/Node/AutoEscapeTest.php | 32 + .../Twig/Tests/Node/BlockReferenceTest.php | 31 + .../twig/test/Twig/Tests/Node/BlockTest.php | 39 + .../twig/twig/test/Twig/Tests/Node/DoTest.php | 32 + .../Twig/Tests/Node/Expression/ArrayTest.php | 37 + .../Tests/Node/Expression/AssignNameTest.php | 29 + .../Tests/Node/Expression/Binary/AddTest.php | 34 + .../Tests/Node/Expression/Binary/AndTest.php | 34 + .../Node/Expression/Binary/ConcatTest.php | 34 + .../Tests/Node/Expression/Binary/DivTest.php | 34 + .../Node/Expression/Binary/FloorDivTest.php | 34 + .../Tests/Node/Expression/Binary/ModTest.php | 34 + .../Tests/Node/Expression/Binary/MulTest.php | 34 + .../Tests/Node/Expression/Binary/OrTest.php | 34 + .../Tests/Node/Expression/Binary/SubTest.php | 34 + .../Twig/Tests/Node/Expression/CallTest.php | 116 + .../Tests/Node/Expression/ConditionalTest.php | 38 + .../Tests/Node/Expression/ConstantTest.php | 30 + .../Twig/Tests/Node/Expression/FilterTest.php | 154 + .../Tests/Node/Expression/FunctionTest.php | 110 + .../Tests/Node/Expression/GetAttrTest.php | 50 + .../Twig/Tests/Node/Expression/NameTest.php | 35 + .../Node/Expression/PHP53/FilterInclude.php | 6 + .../Node/Expression/PHP53/FunctionInclude.php | 6 + .../Node/Expression/PHP53/TestInclude.php | 6 + .../Twig/Tests/Node/Expression/ParentTest.php | 28 + .../Twig/Tests/Node/Expression/TestTest.php | 82 + .../Tests/Node/Expression/Unary/NegTest.php | 32 + .../Tests/Node/Expression/Unary/NotTest.php | 31 + .../Tests/Node/Expression/Unary/PosTest.php | 31 + .../twig/test/Twig/Tests/Node/ForTest.php | 191 + .../twig/twig/test/Twig/Tests/Node/IfTest.php | 88 + .../twig/test/Twig/Tests/Node/ImportTest.php | 40 + .../twig/test/Twig/Tests/Node/IncludeTest.php | 83 + .../twig/test/Twig/Tests/Node/MacroTest.php | 70 + .../twig/test/Twig/Tests/Node/ModuleTest.php | 183 + .../twig/test/Twig/Tests/Node/PrintTest.php | 29 + .../twig/test/Twig/Tests/Node/SandboxTest.php | 44 + .../Twig/Tests/Node/SandboxedPrintTest.php | 33 + .../twig/test/Twig/Tests/Node/SetTest.php | 69 + .../test/Twig/Tests/Node/SpacelessTest.php | 37 + .../twig/test/Twig/Tests/Node/TextTest.php | 28 + .../Twig/Tests/NodeVisitor/OptimizerTest.php | 124 + .../twig/twig/test/Twig/Tests/ParserTest.php | 196 + .../Tests/Profiler/Dumper/AbstractTest.php | 101 + .../Tests/Profiler/Dumper/BlackfireTest.php | 32 + .../Twig/Tests/Profiler/Dumper/HtmlTest.php | 30 + .../Twig/Tests/Profiler/Dumper/TextTest.php | 30 + .../test/Twig/Tests/Profiler/ProfileTest.php | 100 + .../twig/test/Twig/Tests/TemplateTest.php | 693 + .../twig/test/Twig/Tests/TokenStreamTest.php | 70 + .../twig/test/Twig/Tests/escapingTest.php | 320 + vendor/twig/twig/test/bootstrap.php | 13 + vendor/vlucas/phpdotenv/LICENSE.txt | 32 + vendor/vlucas/phpdotenv/README.md | 199 + vendor/vlucas/phpdotenv/composer.json | 26 + vendor/vlucas/phpdotenv/src/Dotenv.php | 307 + 4172 files changed, 459811 insertions(+), 5 deletions(-) create mode 100644 vendor/autoload.php create mode 120000 vendor/bin/phpunit create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_files.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/danielstjules/stringy/.gitignore create mode 100644 vendor/danielstjules/stringy/.travis.yml create mode 100644 vendor/danielstjules/stringy/CHANGELOG.md create mode 100644 vendor/danielstjules/stringy/LICENSE.txt create mode 100644 vendor/danielstjules/stringy/README.md create mode 100644 vendor/danielstjules/stringy/composer.json create mode 100644 vendor/danielstjules/stringy/phpunit.xml.dist create mode 100644 vendor/danielstjules/stringy/src/Create.php create mode 100644 vendor/danielstjules/stringy/src/StaticStringy.php create mode 100644 vendor/danielstjules/stringy/src/Stringy.php create mode 100644 vendor/danielstjules/stringy/tests/CommonTest.php create mode 100644 vendor/danielstjules/stringy/tests/CreateTest.php create mode 100644 vendor/danielstjules/stringy/tests/StaticStringyTest.php create mode 100644 vendor/danielstjules/stringy/tests/StringyTest.php create mode 100644 vendor/doctrine/inflector/.gitignore create mode 100644 vendor/doctrine/inflector/.travis.yml create mode 100644 vendor/doctrine/inflector/LICENSE create mode 100644 vendor/doctrine/inflector/README.md create mode 100644 vendor/doctrine/inflector/composer.json create mode 100644 vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php create mode 100644 vendor/doctrine/inflector/phpunit.xml.dist create mode 100644 vendor/doctrine/inflector/tests/Doctrine/Tests/Common/Inflector/InflectorTest.php create mode 100644 vendor/doctrine/inflector/tests/Doctrine/Tests/DoctrineTestCase.php create mode 100644 vendor/doctrine/inflector/tests/Doctrine/Tests/TestInit.php create mode 100644 vendor/doctrine/instantiator/.gitignore create mode 100644 vendor/doctrine/instantiator/.scrutinizer.yml create mode 100755 vendor/doctrine/instantiator/.travis.install.sh create mode 100644 vendor/doctrine/instantiator/.travis.yml create mode 100644 vendor/doctrine/instantiator/CONTRIBUTING.md create mode 100644 vendor/doctrine/instantiator/LICENSE create mode 100644 vendor/doctrine/instantiator/README.md create mode 100644 vendor/doctrine/instantiator/composer.json create mode 100644 vendor/doctrine/instantiator/phpmd.xml.dist create mode 100644 vendor/doctrine/instantiator/phpunit.xml.dist create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorPerformance/InstantiatorPerformanceEvent.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ArrayObjectAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/FinalExceptionAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharExceptionAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SerializableArrayObjectAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleTraitAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnCloneableAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php create mode 100644 vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php create mode 100644 vendor/fzaninotto/faker/.gitignore create mode 100644 vendor/fzaninotto/faker/.travis.yml create mode 100644 vendor/fzaninotto/faker/CHANGELOG.md create mode 100644 vendor/fzaninotto/faker/CONTRIBUTING.md create mode 100644 vendor/fzaninotto/faker/LICENSE create mode 100644 vendor/fzaninotto/faker/Makefile create mode 100644 vendor/fzaninotto/faker/composer.json create mode 100644 vendor/fzaninotto/faker/phpunit.xml.dist create mode 100644 vendor/fzaninotto/faker/readme.md create mode 100644 vendor/fzaninotto/faker/src/Faker/Calculator/Luhn.php create mode 100644 vendor/fzaninotto/faker/src/Faker/DefaultGenerator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Documentor.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Factory.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Generator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Guesser/Name.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/ColumnTypeGuesser.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/EntityPopulator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/Populator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/ColumnTypeGuesser.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/EntityPopulator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/Populator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Mandango/ColumnTypeGuesser.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Mandango/EntityPopulator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Mandango/Populator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Propel/ColumnTypeGuesser.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Propel/EntityPopulator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/ORM/Propel/Populator.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Barcode.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Base.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Biased.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Color.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/DateTime.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/File.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Image.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Lorem.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Miscellaneous.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/UserAgent.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/Uuid.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/at_AT/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/be_BE/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bg_BG/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bg_BG/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bg_BG/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bg_BG/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bn_BD/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bn_BD/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bn_BD/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bn_BD/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/bn_BD/Utils.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/DateTime.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/da_DK/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_AT/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_AT/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_AT/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_AT/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_AT/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_AT/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_DE/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_DE/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_DE/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_DE/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_DE/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_DE/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/de_DE/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/el_GR/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/el_GR/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/el_GR/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/el_GR/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_AU/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_AU/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_AU/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_CA/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_CA/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_GB/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_GB/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_GB/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_GB/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_GB/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_NZ/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_NZ/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_NZ/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_PH/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_UG/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_UG/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_UG/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_UG/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_US/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_US/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_US/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_US/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_US/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_ZA/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_ZA/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_ZA/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/en_ZA/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_AR/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_AR/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_AR/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_AR/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_ES/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_ES/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_ES/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_ES/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_ES/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_ES/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_PE/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_PE/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_PE/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_PE/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_VE/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_VE/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_VE/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_VE/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/es_VE/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fa_IR/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fa_IR/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fa_IR/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fi_FI/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fi_FI/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fi_FI/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fi_FI/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fi_FI/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_BE/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_BE/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_BE/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_BE/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_BE/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_BE/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_CA/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_CA/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hu_HU/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hu_HU/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hu_HU/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hu_HU/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hu_HU/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hy_AM/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hy_AM/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hy_AM/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hy_AM/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/hy_AM/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/id_ID/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/id_ID/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/id_ID/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/id_ID/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/id_ID/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/is_IS/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/it_IT/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ka_GE/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ka_GE/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Color.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ko_KR/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ko_KR/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ko_KR/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ko_KR/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ko_KR/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/me_ME/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/me_ME/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/me_ME/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/me_ME/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/me_ME/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ne_NP/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ne_NP/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ne_NP/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ne_NP/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_BE/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_BE/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_BE/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_BE/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_BE/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_BE/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_NL/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_NL/Color.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_NL/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_NL/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_NL/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_NL/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/nl_NL/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/no_NO/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/no_NO/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/no_NO/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/no_NO/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/check_digit.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ro_MD/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ro_MD/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ro_MD/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Color.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/PhoneNumber.php create mode 100755 vendor/fzaninotto/faker/src/Faker/Provider/sl_SI/Address.php create mode 100755 vendor/fzaninotto/faker/src/Faker/Provider/sl_SI/Internet.php create mode 100755 vendor/fzaninotto/faker/src/Faker/Provider/sl_SI/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sl_SI/Person.php create mode 100755 vendor/fzaninotto/faker/src/Faker/Provider/sl_SI/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_Cyrl_RS/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_Cyrl_RS/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_Cyrl_RS/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_Latn_RS/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_Latn_RS/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_Latn_RS/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_RS/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_RS/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sr_RS/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sv_SE/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sv_SE/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sv_SE/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/sv_SE/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/Color.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/DateTime.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Color.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/Color.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Address.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Color.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Company.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/DateTime.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Internet.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Payment.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Person.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/PhoneNumber.php create mode 100644 vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Text.php create mode 100644 vendor/fzaninotto/faker/src/Faker/UniqueGenerator.php create mode 100644 vendor/fzaninotto/faker/src/autoload.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Calculator/LuhnTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/DefaultGeneratorTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/GeneratorTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/AddressTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/BarcodeTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/BaseTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/BiasedTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/ColorTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/DateTimeTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/ImageTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/InternetTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/LocalizationTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/LoremTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/MiscellaneousTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/PaymentTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/PersonTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/ProviderOverrideTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/TextTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/UserAgentTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/UuidTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/at_AT/PaymentTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/be_BE/PaymentTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/bg_BG/PaymentTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/de_AT/InternetTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/de_AT/PhoneNumberTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/fr_FR/CompanyTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/id_ID/PersonTest.php create mode 100755 vendor/fzaninotto/faker/test/Faker/Provider/ja_JP/PersonTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/CompanyTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/PersonTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/AddressTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PersonTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PhoneNumberTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PersonTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PhoneNumberTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/sv_SE/PersonTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/AddressTest.php create mode 100644 vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/PhoneNumberTest.php create mode 100644 vendor/fzaninotto/faker/test/documentor.php create mode 100644 vendor/fzaninotto/faker/test/test.php create mode 100644 vendor/illuminate/auth/Access/Gate.php create mode 100644 vendor/illuminate/auth/Access/HandlesAuthorization.php create mode 100644 vendor/illuminate/auth/Access/Response.php create mode 100644 vendor/illuminate/auth/Access/UnauthorizedException.php create mode 100755 vendor/illuminate/auth/AuthManager.php create mode 100755 vendor/illuminate/auth/AuthServiceProvider.php create mode 100644 vendor/illuminate/auth/Authenticatable.php create mode 100644 vendor/illuminate/auth/Console/ClearResetsCommand.php create mode 100755 vendor/illuminate/auth/DatabaseUserProvider.php create mode 100755 vendor/illuminate/auth/EloquentUserProvider.php create mode 100644 vendor/illuminate/auth/GeneratorServiceProvider.php create mode 100755 vendor/illuminate/auth/GenericUser.php create mode 100755 vendor/illuminate/auth/Guard.php create mode 100644 vendor/illuminate/auth/Middleware/AuthenticateWithBasicAuth.php create mode 100644 vendor/illuminate/auth/Passwords/CanResetPassword.php create mode 100755 vendor/illuminate/auth/Passwords/DatabaseTokenRepository.php create mode 100755 vendor/illuminate/auth/Passwords/PasswordBroker.php create mode 100755 vendor/illuminate/auth/Passwords/PasswordResetServiceProvider.php create mode 100755 vendor/illuminate/auth/Passwords/TokenRepositoryInterface.php create mode 100755 vendor/illuminate/auth/composer.json create mode 100644 vendor/illuminate/broadcasting/BroadcastEvent.php create mode 100644 vendor/illuminate/broadcasting/BroadcastManager.php create mode 100644 vendor/illuminate/broadcasting/BroadcastServiceProvider.php create mode 100644 vendor/illuminate/broadcasting/Broadcasters/LogBroadcaster.php create mode 100644 vendor/illuminate/broadcasting/Broadcasters/PusherBroadcaster.php create mode 100644 vendor/illuminate/broadcasting/Broadcasters/RedisBroadcaster.php create mode 100644 vendor/illuminate/broadcasting/composer.json create mode 100644 vendor/illuminate/bus/BusServiceProvider.php create mode 100644 vendor/illuminate/bus/Dispatcher.php create mode 100644 vendor/illuminate/bus/MarshalException.php create mode 100644 vendor/illuminate/bus/Queueable.php create mode 100644 vendor/illuminate/bus/composer.json create mode 100755 vendor/illuminate/cache/ApcStore.php create mode 100755 vendor/illuminate/cache/ApcWrapper.php create mode 100755 vendor/illuminate/cache/ArrayStore.php create mode 100755 vendor/illuminate/cache/CacheManager.php create mode 100755 vendor/illuminate/cache/CacheServiceProvider.php create mode 100644 vendor/illuminate/cache/Console/CacheTableCommand.php create mode 100755 vendor/illuminate/cache/Console/ClearCommand.php create mode 100644 vendor/illuminate/cache/Console/stubs/cache.stub create mode 100755 vendor/illuminate/cache/DatabaseStore.php create mode 100755 vendor/illuminate/cache/FileStore.php create mode 100755 vendor/illuminate/cache/MemcachedConnector.php create mode 100755 vendor/illuminate/cache/MemcachedStore.php create mode 100755 vendor/illuminate/cache/NullStore.php create mode 100644 vendor/illuminate/cache/RateLimiter.php create mode 100755 vendor/illuminate/cache/RedisStore.php create mode 100644 vendor/illuminate/cache/RedisTaggedCache.php create mode 100755 vendor/illuminate/cache/Repository.php create mode 100644 vendor/illuminate/cache/TagSet.php create mode 100644 vendor/illuminate/cache/TaggableStore.php create mode 100644 vendor/illuminate/cache/TaggedCache.php create mode 100755 vendor/illuminate/cache/WinCacheStore.php create mode 100755 vendor/illuminate/cache/XCacheStore.php create mode 100755 vendor/illuminate/cache/composer.json create mode 100644 vendor/illuminate/config/Repository.php create mode 100755 vendor/illuminate/config/composer.json create mode 100644 vendor/illuminate/console/AppNamespaceDetectorTrait.php create mode 100755 vendor/illuminate/console/Application.php create mode 100755 vendor/illuminate/console/Command.php create mode 100644 vendor/illuminate/console/ConfirmableTrait.php create mode 100644 vendor/illuminate/console/GeneratorCommand.php create mode 100644 vendor/illuminate/console/OutputStyle.php create mode 100644 vendor/illuminate/console/Parser.php create mode 100644 vendor/illuminate/console/ScheduleServiceProvider.php create mode 100644 vendor/illuminate/console/Scheduling/CallbackEvent.php create mode 100644 vendor/illuminate/console/Scheduling/Event.php create mode 100644 vendor/illuminate/console/Scheduling/Schedule.php create mode 100644 vendor/illuminate/console/Scheduling/ScheduleRunCommand.php create mode 100755 vendor/illuminate/console/composer.json create mode 100644 vendor/illuminate/container/BindingResolutionException.php create mode 100755 vendor/illuminate/container/Container.php create mode 100644 vendor/illuminate/container/ContextualBindingBuilder.php create mode 100755 vendor/illuminate/container/composer.json create mode 100644 vendor/illuminate/contracts/Auth/Access/Authorizable.php create mode 100644 vendor/illuminate/contracts/Auth/Access/Gate.php create mode 100644 vendor/illuminate/contracts/Auth/Authenticatable.php create mode 100644 vendor/illuminate/contracts/Auth/CanResetPassword.php create mode 100644 vendor/illuminate/contracts/Auth/Guard.php create mode 100644 vendor/illuminate/contracts/Auth/PasswordBroker.php create mode 100644 vendor/illuminate/contracts/Auth/Registrar.php create mode 100644 vendor/illuminate/contracts/Auth/UserProvider.php create mode 100644 vendor/illuminate/contracts/Broadcasting/Broadcaster.php create mode 100644 vendor/illuminate/contracts/Broadcasting/Factory.php create mode 100644 vendor/illuminate/contracts/Broadcasting/ShouldBroadcast.php create mode 100644 vendor/illuminate/contracts/Broadcasting/ShouldBroadcastNow.php create mode 100644 vendor/illuminate/contracts/Bus/Dispatcher.php create mode 100644 vendor/illuminate/contracts/Bus/HandlerResolver.php create mode 100644 vendor/illuminate/contracts/Bus/QueueingDispatcher.php create mode 100644 vendor/illuminate/contracts/Bus/SelfHandling.php create mode 100644 vendor/illuminate/contracts/Cache/Factory.php create mode 100644 vendor/illuminate/contracts/Cache/Repository.php create mode 100644 vendor/illuminate/contracts/Cache/Store.php create mode 100644 vendor/illuminate/contracts/Config/Repository.php create mode 100644 vendor/illuminate/contracts/Console/Application.php create mode 100644 vendor/illuminate/contracts/Console/Kernel.php create mode 100644 vendor/illuminate/contracts/Container/BindingResolutionException.php create mode 100644 vendor/illuminate/contracts/Container/Container.php create mode 100644 vendor/illuminate/contracts/Container/ContextualBindingBuilder.php create mode 100644 vendor/illuminate/contracts/Cookie/Factory.php create mode 100644 vendor/illuminate/contracts/Cookie/QueueingFactory.php create mode 100644 vendor/illuminate/contracts/Database/ModelIdentifier.php create mode 100644 vendor/illuminate/contracts/Debug/ExceptionHandler.php create mode 100644 vendor/illuminate/contracts/Encryption/DecryptException.php create mode 100644 vendor/illuminate/contracts/Encryption/EncryptException.php create mode 100644 vendor/illuminate/contracts/Encryption/Encrypter.php create mode 100644 vendor/illuminate/contracts/Events/Dispatcher.php create mode 100644 vendor/illuminate/contracts/Filesystem/Cloud.php create mode 100644 vendor/illuminate/contracts/Filesystem/Factory.php create mode 100644 vendor/illuminate/contracts/Filesystem/FileNotFoundException.php create mode 100644 vendor/illuminate/contracts/Filesystem/Filesystem.php create mode 100644 vendor/illuminate/contracts/Foundation/Application.php create mode 100644 vendor/illuminate/contracts/Hashing/Hasher.php create mode 100644 vendor/illuminate/contracts/Http/Kernel.php create mode 100644 vendor/illuminate/contracts/Logging/Log.php create mode 100644 vendor/illuminate/contracts/Mail/MailQueue.php create mode 100644 vendor/illuminate/contracts/Mail/Mailer.php create mode 100644 vendor/illuminate/contracts/Pagination/LengthAwarePaginator.php create mode 100644 vendor/illuminate/contracts/Pagination/Paginator.php create mode 100644 vendor/illuminate/contracts/Pagination/Presenter.php create mode 100644 vendor/illuminate/contracts/Pipeline/Hub.php create mode 100644 vendor/illuminate/contracts/Pipeline/Pipeline.php create mode 100644 vendor/illuminate/contracts/Queue/EntityNotFoundException.php create mode 100644 vendor/illuminate/contracts/Queue/EntityResolver.php create mode 100644 vendor/illuminate/contracts/Queue/Factory.php create mode 100644 vendor/illuminate/contracts/Queue/Job.php create mode 100644 vendor/illuminate/contracts/Queue/Monitor.php create mode 100644 vendor/illuminate/contracts/Queue/Queue.php create mode 100644 vendor/illuminate/contracts/Queue/QueueableEntity.php create mode 100644 vendor/illuminate/contracts/Queue/ShouldBeQueued.php create mode 100644 vendor/illuminate/contracts/Queue/ShouldQueue.php create mode 100644 vendor/illuminate/contracts/Redis/Database.php create mode 100644 vendor/illuminate/contracts/Routing/Middleware.php create mode 100644 vendor/illuminate/contracts/Routing/Registrar.php create mode 100644 vendor/illuminate/contracts/Routing/ResponseFactory.php create mode 100644 vendor/illuminate/contracts/Routing/TerminableMiddleware.php create mode 100644 vendor/illuminate/contracts/Routing/UrlGenerator.php create mode 100644 vendor/illuminate/contracts/Routing/UrlRoutable.php create mode 100755 vendor/illuminate/contracts/Support/Arrayable.php create mode 100644 vendor/illuminate/contracts/Support/Htmlable.php create mode 100755 vendor/illuminate/contracts/Support/Jsonable.php create mode 100644 vendor/illuminate/contracts/Support/MessageBag.php create mode 100755 vendor/illuminate/contracts/Support/MessageProvider.php create mode 100755 vendor/illuminate/contracts/Support/Renderable.php create mode 100644 vendor/illuminate/contracts/Validation/Factory.php create mode 100644 vendor/illuminate/contracts/Validation/UnauthorizedException.php create mode 100644 vendor/illuminate/contracts/Validation/ValidatesWhenResolved.php create mode 100644 vendor/illuminate/contracts/Validation/ValidationException.php create mode 100644 vendor/illuminate/contracts/Validation/Validator.php create mode 100644 vendor/illuminate/contracts/View/Factory.php create mode 100644 vendor/illuminate/contracts/View/View.php create mode 100644 vendor/illuminate/contracts/composer.json create mode 100755 vendor/illuminate/cookie/CookieJar.php create mode 100755 vendor/illuminate/cookie/CookieServiceProvider.php create mode 100644 vendor/illuminate/cookie/Middleware/AddQueuedCookiesToResponse.php create mode 100644 vendor/illuminate/cookie/Middleware/EncryptCookies.php create mode 100755 vendor/illuminate/cookie/composer.json create mode 100755 vendor/illuminate/database/Capsule/Manager.php create mode 100755 vendor/illuminate/database/Connection.php create mode 100755 vendor/illuminate/database/ConnectionInterface.php create mode 100755 vendor/illuminate/database/ConnectionResolver.php create mode 100755 vendor/illuminate/database/ConnectionResolverInterface.php create mode 100755 vendor/illuminate/database/Connectors/ConnectionFactory.php create mode 100755 vendor/illuminate/database/Connectors/Connector.php create mode 100755 vendor/illuminate/database/Connectors/ConnectorInterface.php create mode 100755 vendor/illuminate/database/Connectors/MySqlConnector.php create mode 100755 vendor/illuminate/database/Connectors/PostgresConnector.php create mode 100755 vendor/illuminate/database/Connectors/SQLiteConnector.php create mode 100755 vendor/illuminate/database/Connectors/SqlServerConnector.php create mode 100755 vendor/illuminate/database/Console/Migrations/BaseCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/InstallCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/MigrateCommand.php create mode 100644 vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/RefreshCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/ResetCommand.php create mode 100755 vendor/illuminate/database/Console/Migrations/RollbackCommand.php create mode 100644 vendor/illuminate/database/Console/Migrations/StatusCommand.php create mode 100644 vendor/illuminate/database/Console/Seeds/SeedCommand.php create mode 100644 vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php create mode 100644 vendor/illuminate/database/Console/Seeds/stubs/seeder.stub create mode 100755 vendor/illuminate/database/DatabaseManager.php create mode 100755 vendor/illuminate/database/DatabaseServiceProvider.php create mode 100644 vendor/illuminate/database/DetectsLostConnections.php create mode 100755 vendor/illuminate/database/Eloquent/Builder.php create mode 100755 vendor/illuminate/database/Eloquent/Collection.php create mode 100644 vendor/illuminate/database/Eloquent/Factory.php create mode 100644 vendor/illuminate/database/Eloquent/FactoryBuilder.php create mode 100755 vendor/illuminate/database/Eloquent/MassAssignmentException.php create mode 100755 vendor/illuminate/database/Eloquent/Model.php create mode 100755 vendor/illuminate/database/Eloquent/ModelNotFoundException.php create mode 100644 vendor/illuminate/database/Eloquent/QueueEntityResolver.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/BelongsTo.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/HasMany.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/HasOne.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/MorphMany.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/MorphOne.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/MorphPivot.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/MorphTo.php create mode 100644 vendor/illuminate/database/Eloquent/Relations/MorphToMany.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/Pivot.php create mode 100755 vendor/illuminate/database/Eloquent/Relations/Relation.php create mode 100644 vendor/illuminate/database/Eloquent/ScopeInterface.php create mode 100644 vendor/illuminate/database/Eloquent/SoftDeletes.php create mode 100644 vendor/illuminate/database/Eloquent/SoftDeletingScope.php create mode 100755 vendor/illuminate/database/Grammar.php create mode 100755 vendor/illuminate/database/MigrationServiceProvider.php create mode 100755 vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php create mode 100755 vendor/illuminate/database/Migrations/Migration.php create mode 100755 vendor/illuminate/database/Migrations/MigrationCreator.php create mode 100755 vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php create mode 100755 vendor/illuminate/database/Migrations/Migrator.php create mode 100755 vendor/illuminate/database/Migrations/stubs/blank.stub create mode 100755 vendor/illuminate/database/Migrations/stubs/create.stub create mode 100755 vendor/illuminate/database/Migrations/stubs/update.stub create mode 100755 vendor/illuminate/database/MySqlConnection.php create mode 100755 vendor/illuminate/database/PostgresConnection.php create mode 100755 vendor/illuminate/database/Query/Builder.php create mode 100755 vendor/illuminate/database/Query/Expression.php create mode 100755 vendor/illuminate/database/Query/Grammars/Grammar.php create mode 100755 vendor/illuminate/database/Query/Grammars/MySqlGrammar.php create mode 100755 vendor/illuminate/database/Query/Grammars/PostgresGrammar.php create mode 100755 vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php create mode 100755 vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php create mode 100755 vendor/illuminate/database/Query/JoinClause.php create mode 100644 vendor/illuminate/database/Query/Processors/MySqlProcessor.php create mode 100755 vendor/illuminate/database/Query/Processors/PostgresProcessor.php create mode 100755 vendor/illuminate/database/Query/Processors/Processor.php create mode 100644 vendor/illuminate/database/Query/Processors/SQLiteProcessor.php create mode 100755 vendor/illuminate/database/Query/Processors/SqlServerProcessor.php create mode 100644 vendor/illuminate/database/QueryException.php create mode 100755 vendor/illuminate/database/README.md create mode 100755 vendor/illuminate/database/SQLiteConnection.php create mode 100755 vendor/illuminate/database/Schema/Blueprint.php create mode 100755 vendor/illuminate/database/Schema/Builder.php create mode 100755 vendor/illuminate/database/Schema/Grammars/Grammar.php create mode 100755 vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php create mode 100755 vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php create mode 100755 vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php create mode 100755 vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php create mode 100755 vendor/illuminate/database/Schema/MySqlBuilder.php create mode 100755 vendor/illuminate/database/SeedServiceProvider.php create mode 100755 vendor/illuminate/database/Seeder.php create mode 100755 vendor/illuminate/database/SqlServerConnection.php create mode 100755 vendor/illuminate/database/composer.json create mode 100644 vendor/illuminate/encryption/BaseEncrypter.php create mode 100755 vendor/illuminate/encryption/Encrypter.php create mode 100755 vendor/illuminate/encryption/EncryptionServiceProvider.php create mode 100644 vendor/illuminate/encryption/McryptEncrypter.php create mode 100755 vendor/illuminate/encryption/composer.json create mode 100644 vendor/illuminate/events/CallQueuedHandler.php create mode 100755 vendor/illuminate/events/Dispatcher.php create mode 100755 vendor/illuminate/events/EventServiceProvider.php create mode 100755 vendor/illuminate/events/composer.json create mode 100644 vendor/illuminate/filesystem/ClassFinder.php create mode 100755 vendor/illuminate/filesystem/Filesystem.php create mode 100644 vendor/illuminate/filesystem/FilesystemAdapter.php create mode 100644 vendor/illuminate/filesystem/FilesystemManager.php create mode 100755 vendor/illuminate/filesystem/FilesystemServiceProvider.php create mode 100755 vendor/illuminate/filesystem/composer.json create mode 100755 vendor/illuminate/hashing/BcryptHasher.php create mode 100755 vendor/illuminate/hashing/HashServiceProvider.php create mode 100755 vendor/illuminate/hashing/composer.json create mode 100644 vendor/illuminate/http/Exception/HttpResponseException.php create mode 100644 vendor/illuminate/http/Exception/PostTooLargeException.php create mode 100755 vendor/illuminate/http/JsonResponse.php create mode 100644 vendor/illuminate/http/Middleware/FrameGuard.php create mode 100755 vendor/illuminate/http/RedirectResponse.php create mode 100755 vendor/illuminate/http/Request.php create mode 100755 vendor/illuminate/http/Response.php create mode 100644 vendor/illuminate/http/ResponseTrait.php create mode 100755 vendor/illuminate/http/composer.json create mode 100644 vendor/illuminate/pagination/AbstractPaginator.php create mode 100644 vendor/illuminate/pagination/BootstrapThreeNextPreviousButtonRendererTrait.php create mode 100644 vendor/illuminate/pagination/BootstrapThreePresenter.php create mode 100644 vendor/illuminate/pagination/LengthAwarePaginator.php create mode 100755 vendor/illuminate/pagination/PaginationServiceProvider.php create mode 100644 vendor/illuminate/pagination/Paginator.php create mode 100644 vendor/illuminate/pagination/SimpleBootstrapThreePresenter.php create mode 100644 vendor/illuminate/pagination/UrlWindow.php create mode 100644 vendor/illuminate/pagination/UrlWindowPresenterTrait.php create mode 100755 vendor/illuminate/pagination/composer.json create mode 100644 vendor/illuminate/pipeline/Hub.php create mode 100644 vendor/illuminate/pipeline/Pipeline.php create mode 100644 vendor/illuminate/pipeline/PipelineServiceProvider.php create mode 100644 vendor/illuminate/pipeline/composer.json create mode 100755 vendor/illuminate/queue/BeanstalkdQueue.php create mode 100644 vendor/illuminate/queue/CallQueuedHandler.php create mode 100644 vendor/illuminate/queue/Capsule/Manager.php create mode 100755 vendor/illuminate/queue/Connectors/BeanstalkdConnector.php create mode 100755 vendor/illuminate/queue/Connectors/ConnectorInterface.php create mode 100644 vendor/illuminate/queue/Connectors/DatabaseConnector.php create mode 100755 vendor/illuminate/queue/Connectors/IronConnector.php create mode 100644 vendor/illuminate/queue/Connectors/NullConnector.php create mode 100644 vendor/illuminate/queue/Connectors/RedisConnector.php create mode 100755 vendor/illuminate/queue/Connectors/SqsConnector.php create mode 100755 vendor/illuminate/queue/Connectors/SyncConnector.php create mode 100644 vendor/illuminate/queue/Console/FailedTableCommand.php create mode 100644 vendor/illuminate/queue/Console/FlushFailedCommand.php create mode 100644 vendor/illuminate/queue/Console/ForgetFailedCommand.php create mode 100644 vendor/illuminate/queue/Console/ListFailedCommand.php create mode 100755 vendor/illuminate/queue/Console/ListenCommand.php create mode 100644 vendor/illuminate/queue/Console/RestartCommand.php create mode 100644 vendor/illuminate/queue/Console/RetryCommand.php create mode 100755 vendor/illuminate/queue/Console/SubscribeCommand.php create mode 100644 vendor/illuminate/queue/Console/TableCommand.php create mode 100755 vendor/illuminate/queue/Console/WorkCommand.php create mode 100644 vendor/illuminate/queue/Console/stubs/failed_jobs.stub create mode 100644 vendor/illuminate/queue/Console/stubs/jobs.stub create mode 100644 vendor/illuminate/queue/ConsoleServiceProvider.php create mode 100644 vendor/illuminate/queue/DatabaseQueue.php create mode 100644 vendor/illuminate/queue/Failed/DatabaseFailedJobProvider.php create mode 100644 vendor/illuminate/queue/Failed/FailedJobProviderInterface.php create mode 100644 vendor/illuminate/queue/Failed/NullFailedJobProvider.php create mode 100755 vendor/illuminate/queue/IlluminateQueueClosure.php create mode 100644 vendor/illuminate/queue/InteractsWithQueue.php create mode 100755 vendor/illuminate/queue/IronQueue.php create mode 100755 vendor/illuminate/queue/Jobs/BeanstalkdJob.php create mode 100644 vendor/illuminate/queue/Jobs/DatabaseJob.php create mode 100755 vendor/illuminate/queue/Jobs/IronJob.php create mode 100755 vendor/illuminate/queue/Jobs/Job.php create mode 100644 vendor/illuminate/queue/Jobs/RedisJob.php create mode 100755 vendor/illuminate/queue/Jobs/SqsJob.php create mode 100755 vendor/illuminate/queue/Jobs/SyncJob.php create mode 100755 vendor/illuminate/queue/Listener.php create mode 100644 vendor/illuminate/queue/NullQueue.php create mode 100755 vendor/illuminate/queue/Queue.php create mode 100755 vendor/illuminate/queue/QueueManager.php create mode 100755 vendor/illuminate/queue/QueueServiceProvider.php create mode 100644 vendor/illuminate/queue/README.md create mode 100644 vendor/illuminate/queue/RedisQueue.php create mode 100644 vendor/illuminate/queue/SerializesModels.php create mode 100755 vendor/illuminate/queue/SqsQueue.php create mode 100755 vendor/illuminate/queue/SyncQueue.php create mode 100755 vendor/illuminate/queue/Worker.php create mode 100755 vendor/illuminate/queue/composer.json create mode 100755 vendor/illuminate/session/CacheBasedSessionHandler.php create mode 100755 vendor/illuminate/session/CommandsServiceProvider.php create mode 100644 vendor/illuminate/session/Console/SessionTableCommand.php create mode 100755 vendor/illuminate/session/Console/stubs/database.stub create mode 100755 vendor/illuminate/session/CookieSessionHandler.php create mode 100644 vendor/illuminate/session/DatabaseSessionHandler.php create mode 100644 vendor/illuminate/session/EncryptedStore.php create mode 100644 vendor/illuminate/session/ExistenceAwareInterface.php create mode 100644 vendor/illuminate/session/FileSessionHandler.php create mode 100644 vendor/illuminate/session/Middleware/StartSession.php create mode 100644 vendor/illuminate/session/SessionInterface.php create mode 100755 vendor/illuminate/session/SessionManager.php create mode 100755 vendor/illuminate/session/SessionServiceProvider.php create mode 100755 vendor/illuminate/session/Store.php create mode 100755 vendor/illuminate/session/TokenMismatchException.php create mode 100755 vendor/illuminate/session/composer.json create mode 100644 vendor/illuminate/support/AggregateServiceProvider.php create mode 100755 vendor/illuminate/support/Arr.php create mode 100644 vendor/illuminate/support/ClassLoader.php create mode 100755 vendor/illuminate/support/Collection.php create mode 100644 vendor/illuminate/support/Debug/Dumper.php create mode 100644 vendor/illuminate/support/Debug/HtmlDumper.php create mode 100755 vendor/illuminate/support/Facades/App.php create mode 100755 vendor/illuminate/support/Facades/Artisan.php create mode 100755 vendor/illuminate/support/Facades/Auth.php create mode 100755 vendor/illuminate/support/Facades/Blade.php create mode 100644 vendor/illuminate/support/Facades/Bus.php create mode 100755 vendor/illuminate/support/Facades/Cache.php create mode 100755 vendor/illuminate/support/Facades/Config.php create mode 100755 vendor/illuminate/support/Facades/Cookie.php create mode 100755 vendor/illuminate/support/Facades/Crypt.php create mode 100755 vendor/illuminate/support/Facades/DB.php create mode 100755 vendor/illuminate/support/Facades/Event.php create mode 100755 vendor/illuminate/support/Facades/Facade.php create mode 100755 vendor/illuminate/support/Facades/File.php create mode 100644 vendor/illuminate/support/Facades/Gate.php create mode 100755 vendor/illuminate/support/Facades/Hash.php create mode 100755 vendor/illuminate/support/Facades/Input.php create mode 100755 vendor/illuminate/support/Facades/Lang.php create mode 100755 vendor/illuminate/support/Facades/Log.php create mode 100755 vendor/illuminate/support/Facades/Mail.php create mode 100755 vendor/illuminate/support/Facades/Password.php create mode 100755 vendor/illuminate/support/Facades/Queue.php create mode 100755 vendor/illuminate/support/Facades/Redirect.php create mode 100755 vendor/illuminate/support/Facades/Redis.php create mode 100755 vendor/illuminate/support/Facades/Request.php create mode 100755 vendor/illuminate/support/Facades/Response.php create mode 100755 vendor/illuminate/support/Facades/Route.php create mode 100755 vendor/illuminate/support/Facades/Schema.php create mode 100755 vendor/illuminate/support/Facades/Session.php create mode 100644 vendor/illuminate/support/Facades/Storage.php create mode 100755 vendor/illuminate/support/Facades/URL.php create mode 100755 vendor/illuminate/support/Facades/Validator.php create mode 100755 vendor/illuminate/support/Facades/View.php create mode 100755 vendor/illuminate/support/Fluent.php create mode 100644 vendor/illuminate/support/HtmlString.php create mode 100755 vendor/illuminate/support/Manager.php create mode 100755 vendor/illuminate/support/MessageBag.php create mode 100755 vendor/illuminate/support/NamespacedItemResolver.php create mode 100755 vendor/illuminate/support/Pluralizer.php create mode 100755 vendor/illuminate/support/ServiceProvider.php create mode 100755 vendor/illuminate/support/Str.php create mode 100644 vendor/illuminate/support/Traits/CapsuleManagerTrait.php create mode 100644 vendor/illuminate/support/Traits/Macroable.php create mode 100644 vendor/illuminate/support/ViewErrorBag.php create mode 100755 vendor/illuminate/support/composer.json create mode 100755 vendor/illuminate/support/helpers.php create mode 100755 vendor/illuminate/translation/FileLoader.php create mode 100755 vendor/illuminate/translation/LoaderInterface.php create mode 100755 vendor/illuminate/translation/TranslationServiceProvider.php create mode 100755 vendor/illuminate/translation/Translator.php create mode 100755 vendor/illuminate/translation/composer.json create mode 100755 vendor/illuminate/validation/DatabasePresenceVerifier.php create mode 100755 vendor/illuminate/validation/Factory.php create mode 100755 vendor/illuminate/validation/PresenceVerifierInterface.php create mode 100644 vendor/illuminate/validation/ValidatesWhenResolvedTrait.php create mode 100755 vendor/illuminate/validation/ValidationServiceProvider.php create mode 100755 vendor/illuminate/validation/Validator.php create mode 100755 vendor/illuminate/validation/composer.json create mode 100644 vendor/illuminate/view/Compilers/BladeCompiler.php create mode 100755 vendor/illuminate/view/Compilers/Compiler.php create mode 100755 vendor/illuminate/view/Compilers/CompilerInterface.php create mode 100755 vendor/illuminate/view/Engines/CompilerEngine.php create mode 100755 vendor/illuminate/view/Engines/Engine.php create mode 100755 vendor/illuminate/view/Engines/EngineInterface.php create mode 100755 vendor/illuminate/view/Engines/EngineResolver.php create mode 100755 vendor/illuminate/view/Engines/PhpEngine.php create mode 100644 vendor/illuminate/view/Expression.php create mode 100755 vendor/illuminate/view/Factory.php create mode 100755 vendor/illuminate/view/FileViewFinder.php create mode 100644 vendor/illuminate/view/Middleware/ShareErrorsFromSession.php create mode 100755 vendor/illuminate/view/View.php create mode 100755 vendor/illuminate/view/ViewFinderInterface.php create mode 100755 vendor/illuminate/view/ViewServiceProvider.php create mode 100755 vendor/illuminate/view/composer.json create mode 100644 vendor/laravel/lumen-framework/.gitignore create mode 100644 vendor/laravel/lumen-framework/.travis.yml create mode 100644 vendor/laravel/lumen-framework/LICENSE.txt create mode 100644 vendor/laravel/lumen-framework/composer.json create mode 100644 vendor/laravel/lumen-framework/config/app.php create mode 100644 vendor/laravel/lumen-framework/config/auth.php create mode 100644 vendor/laravel/lumen-framework/config/broadcasting.php create mode 100644 vendor/laravel/lumen-framework/config/cache.php create mode 100644 vendor/laravel/lumen-framework/config/database.php create mode 100644 vendor/laravel/lumen-framework/config/filesystems.php create mode 100644 vendor/laravel/lumen-framework/config/mail.php create mode 100644 vendor/laravel/lumen-framework/config/queue.php create mode 100644 vendor/laravel/lumen-framework/config/session.php create mode 100644 vendor/laravel/lumen-framework/config/view.php create mode 100644 vendor/laravel/lumen-framework/lang/en/validation.php create mode 100644 vendor/laravel/lumen-framework/phpunit.php create mode 100644 vendor/laravel/lumen-framework/phpunit.xml create mode 100644 vendor/laravel/lumen-framework/readme.md create mode 100644 vendor/laravel/lumen-framework/src/Application.php create mode 100644 vendor/laravel/lumen-framework/src/Console/Commands/ServeCommand.php create mode 100644 vendor/laravel/lumen-framework/src/Console/Commands/stubs/DatabaseSeeder.stub create mode 100644 vendor/laravel/lumen-framework/src/Console/Commands/stubs/routes.stub create mode 100644 vendor/laravel/lumen-framework/src/Console/Kernel.php create mode 100644 vendor/laravel/lumen-framework/src/Exceptions/Handler.php create mode 100644 vendor/laravel/lumen-framework/src/Foundation/Composer.php create mode 100644 vendor/laravel/lumen-framework/src/Foundation/Support/Providers/EventServiceProvider.php create mode 100644 vendor/laravel/lumen-framework/src/Foundation/Testing/DatabaseMigrations.php create mode 100644 vendor/laravel/lumen-framework/src/Foundation/Testing/DatabaseTransactions.php create mode 100644 vendor/laravel/lumen-framework/src/Foundation/Testing/WithoutMiddleware.php create mode 100644 vendor/laravel/lumen-framework/src/Http/Middleware/VerifyCsrfToken.php create mode 100644 vendor/laravel/lumen-framework/src/Http/Redirector.php create mode 100644 vendor/laravel/lumen-framework/src/Http/ResponseFactory.php create mode 100644 vendor/laravel/lumen-framework/src/Providers/CacheServiceProvider.php create mode 100644 vendor/laravel/lumen-framework/src/Routing/Closure.php create mode 100644 vendor/laravel/lumen-framework/src/Routing/Controller.php create mode 100644 vendor/laravel/lumen-framework/src/Routing/DispatchesJobs.php create mode 100644 vendor/laravel/lumen-framework/src/Routing/UrlGenerator.php create mode 100644 vendor/laravel/lumen-framework/src/Routing/ValidatesRequests.php create mode 100644 vendor/laravel/lumen-framework/src/Testing/ApplicationTrait.php create mode 100644 vendor/laravel/lumen-framework/src/Testing/AssertionsTrait.php create mode 100644 vendor/laravel/lumen-framework/src/Testing/CrawlerTrait.php create mode 100644 vendor/laravel/lumen-framework/src/Testing/TestCase.php create mode 100644 vendor/laravel/lumen-framework/src/helpers.php create mode 100644 vendor/laravel/lumen-framework/storage/logs/.gitignore create mode 100644 vendor/laravel/lumen-framework/tests/FullApplicationTest.php create mode 100644 vendor/laravel/lumen-framework/tests/fixtures/TestController.php create mode 100644 vendor/monolog/monolog/.php_cs create mode 100644 vendor/monolog/monolog/CHANGELOG.mdown create mode 100644 vendor/monolog/monolog/LICENSE create mode 100644 vendor/monolog/monolog/README.mdown create mode 100644 vendor/monolog/monolog/composer.json create mode 100644 vendor/monolog/monolog/doc/01-usage.md create mode 100644 vendor/monolog/monolog/doc/02-handlers-formatters-processors.md create mode 100644 vendor/monolog/monolog/doc/03-utilities.md create mode 100644 vendor/monolog/monolog/doc/04-extending.md create mode 100644 vendor/monolog/monolog/doc/sockets.md create mode 100644 vendor/monolog/monolog/phpunit.xml.dist create mode 100644 vendor/monolog/monolog/src/Monolog/ErrorHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php create mode 100644 vendor/monolog/monolog/src/Monolog/Logger.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php create mode 100644 vendor/monolog/monolog/src/Monolog/Registry.php create mode 100644 vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/LoggerTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/MemoryUsageProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/ProcessIdProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/PsrLogMessageProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/TagProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/UidProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/Processor/WebProcessorTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/PsrLogCompatTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/RegistryTest.php create mode 100644 vendor/monolog/monolog/tests/Monolog/TestCase.php create mode 100644 vendor/mtdowling/cron-expression/LICENSE create mode 100644 vendor/mtdowling/cron-expression/README.md create mode 100644 vendor/mtdowling/cron-expression/composer.json create mode 100644 vendor/mtdowling/cron-expression/phpunit.xml.dist create mode 100644 vendor/mtdowling/cron-expression/src/Cron/AbstractField.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/CronExpression.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/DayOfMonthField.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/DayOfWeekField.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/FieldFactory.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/FieldInterface.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/HoursField.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/MinutesField.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/MonthField.php create mode 100644 vendor/mtdowling/cron-expression/src/Cron/YearField.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/AbstractFieldTest.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/CronExpressionTest.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/DayOfMonthFieldTest.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/DayOfWeekFieldTest.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/FieldFactoryTest.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/HoursFieldTest.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/MinutesFieldTest.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/MonthFieldTest.php create mode 100644 vendor/mtdowling/cron-expression/tests/Cron/YearFieldTest.php create mode 100644 vendor/nesbot/carbon/.editorconfig create mode 100644 vendor/nesbot/carbon/LICENSE create mode 100644 vendor/nesbot/carbon/composer.json create mode 100644 vendor/nesbot/carbon/readme.md create mode 100644 vendor/nesbot/carbon/src/Carbon/Carbon.php create mode 100644 vendor/nesbot/carbon/src/Carbon/CarbonInterval.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/ar.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/az.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/bg.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/bn.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/ca.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/cs.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/da.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/de.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/el.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/en.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/eo.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/es.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/eu.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/fa.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/fi.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/fo.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/fr.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/he.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/hr.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/hu.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/id.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/it.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/ja.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/ko.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/lt.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/lv.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/ms.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/nl.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/no.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/pl.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/pt.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/ro.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/ru.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/sk.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/sl.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/sr.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/sv.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/th.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/tr.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/uk.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/uz.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/vi.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/zh-TW.php create mode 100644 vendor/nesbot/carbon/src/Carbon/Lang/zh.php create mode 100644 vendor/nikic/fast-route/.travis.yml create mode 100644 vendor/nikic/fast-route/LICENSE create mode 100644 vendor/nikic/fast-route/README.md create mode 100644 vendor/nikic/fast-route/composer.json create mode 100644 vendor/nikic/fast-route/phpunit.xml create mode 100644 vendor/nikic/fast-route/src/BadRouteException.php create mode 100644 vendor/nikic/fast-route/src/DataGenerator.php create mode 100644 vendor/nikic/fast-route/src/DataGenerator/CharCountBased.php create mode 100644 vendor/nikic/fast-route/src/DataGenerator/GroupCountBased.php create mode 100644 vendor/nikic/fast-route/src/DataGenerator/GroupPosBased.php create mode 100644 vendor/nikic/fast-route/src/DataGenerator/MarkBased.php create mode 100644 vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php create mode 100644 vendor/nikic/fast-route/src/Dispatcher.php create mode 100644 vendor/nikic/fast-route/src/Dispatcher/CharCountBased.php create mode 100644 vendor/nikic/fast-route/src/Dispatcher/GroupCountBased.php create mode 100644 vendor/nikic/fast-route/src/Dispatcher/GroupPosBased.php create mode 100644 vendor/nikic/fast-route/src/Dispatcher/MarkBased.php create mode 100644 vendor/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php create mode 100644 vendor/nikic/fast-route/src/Route.php create mode 100644 vendor/nikic/fast-route/src/RouteCollector.php create mode 100644 vendor/nikic/fast-route/src/RouteParser.php create mode 100644 vendor/nikic/fast-route/src/RouteParser/Std.php create mode 100644 vendor/nikic/fast-route/src/bootstrap.php create mode 100644 vendor/nikic/fast-route/src/functions.php create mode 100644 vendor/nikic/fast-route/test/Dispatcher/CharCountBasedTest.php create mode 100644 vendor/nikic/fast-route/test/Dispatcher/DispatcherTest.php create mode 100644 vendor/nikic/fast-route/test/Dispatcher/GroupCountBasedTest.php create mode 100644 vendor/nikic/fast-route/test/Dispatcher/GroupPosBasedTest.php create mode 100644 vendor/nikic/fast-route/test/Dispatcher/MarkBasedTest.php create mode 100644 vendor/nikic/fast-route/test/bootstrap.php create mode 100644 vendor/paragonie/random_compat/.gitignore create mode 100644 vendor/paragonie/random_compat/.scrutinizer.yml create mode 100644 vendor/paragonie/random_compat/.travis.yml create mode 100644 vendor/paragonie/random_compat/ERRATA.md create mode 100644 vendor/paragonie/random_compat/LICENSE create mode 100644 vendor/paragonie/random_compat/README.md create mode 100644 vendor/paragonie/random_compat/SECURITY.md create mode 100644 vendor/paragonie/random_compat/composer.json create mode 100644 vendor/paragonie/random_compat/lib/byte_safe_strings.php create mode 100644 vendor/paragonie/random_compat/lib/cast_to_int.php create mode 100644 vendor/paragonie/random_compat/lib/error_polyfill.php create mode 100644 vendor/paragonie/random_compat/lib/random.php create mode 100644 vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php create mode 100644 vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php create mode 100644 vendor/paragonie/random_compat/lib/random_bytes_libsodium.php create mode 100644 vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php create mode 100644 vendor/paragonie/random_compat/lib/random_bytes_openssl.php create mode 100644 vendor/paragonie/random_compat/lib/random_int.php create mode 100644 vendor/paragonie/random_compat/tests/full/DieHardTest.php create mode 100644 vendor/paragonie/random_compat/tests/full/StatTest.php create mode 100755 vendor/paragonie/random_compat/tests/phpunit.sh create mode 100644 vendor/paragonie/random_compat/tests/specific/capicom.php create mode 100644 vendor/paragonie/random_compat/tests/specific/dev_urandom.php create mode 100644 vendor/paragonie/random_compat/tests/specific/libsodium.php create mode 100644 vendor/paragonie/random_compat/tests/specific/mcrypt.php create mode 100644 vendor/paragonie/random_compat/tests/specific/openssl.php create mode 100644 vendor/paragonie/random_compat/tests/unit/RandomBytesTest.php create mode 100644 vendor/paragonie/random_compat/tests/unit/RandomIntTest.php create mode 100644 vendor/paragonie/random_compat/tests/unit/UtilityTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/.gitignore create mode 100644 vendor/phpdocumentor/reflection-docblock/.travis.yml create mode 100644 vendor/phpdocumentor/reflection-docblock/LICENSE create mode 100644 vendor/phpdocumentor/reflection-docblock/README.md create mode 100644 vendor/phpdocumentor/reflection-docblock/composer.json create mode 100644 vendor/phpdocumentor/reflection-docblock/composer.lock create mode 100644 vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Context.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Description.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Location.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Serializer.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/CoversTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ParamTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyReadTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyWriteTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ReturnTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SinceTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/UsesTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/VarTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/VersionTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Type/Collection.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/DescriptionTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/CoversTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ExampleTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/LinkTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/MethodTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ParamTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ReturnTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SeeTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SinceTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SourceTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/UsesTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VarTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VersionTagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/TagTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Type/CollectionTest.php create mode 100644 vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlockTest.php create mode 100644 vendor/phpspec/prophecy/.gitignore create mode 100644 vendor/phpspec/prophecy/.travis.yml create mode 100644 vendor/phpspec/prophecy/CHANGES.md create mode 100644 vendor/phpspec/prophecy/CONTRIBUTING.md create mode 100644 vendor/phpspec/prophecy/LICENSE create mode 100644 vendor/phpspec/prophecy/README.md create mode 100644 vendor/phpspec/prophecy/composer.json create mode 100644 vendor/phpspec/prophecy/composer.lock create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/ArgumentsWildcardSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/CallbackTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/TypeTokenSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/ArgumentSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Call/CallCenterSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Call/CallSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Comparator/ClosureComparatorSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Comparator/FactorySpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/DoublerSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassMirrorSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/LazyDoubleSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Doubler/NameGeneratorSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallPredictionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallTimesPredictionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallbackPredictionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Prediction/NoCallsPredictionSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Promise/CallbackPromiseSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnPromiseSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Promise/ThrowPromiseSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Prophecy/MethodProphecySpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Prophecy/ObjectProphecySpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Prophecy/RevealerSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/ProphetSpec.php create mode 100644 vendor/phpspec/prophecy/spec/Prophecy/Util/StringUtilSpec.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Call/Call.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophet.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php create mode 100644 vendor/phpunit/php-code-coverage/.gitattributes create mode 100644 vendor/phpunit/php-code-coverage/.gitignore create mode 100644 vendor/phpunit/php-code-coverage/.travis.yml create mode 100644 vendor/phpunit/php-code-coverage/CONTRIBUTING.md create mode 100644 vendor/phpunit/php-code-coverage/ChangeLog-2.2.md create mode 100644 vendor/phpunit/php-code-coverage/LICENSE create mode 100644 vendor/phpunit/php-code-coverage/README.md create mode 100644 vendor/phpunit/php-code-coverage/build.xml create mode 100644 vendor/phpunit/php-code-coverage/build/travis-ci.xml create mode 100644 vendor/phpunit/php-code-coverage/composer.json create mode 100644 vendor/phpunit/php-code-coverage/phpunit.xml.dist create mode 100644 vendor/phpunit/php-code-coverage/scripts/auto_append.php create mode 100644 vendor/phpunit/php-code-coverage/scripts/auto_prepend.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/PHPDBG.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Exception.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCode.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Filter.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.css create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.min.css create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/style.css create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/directory.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/file.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.eot create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.svg create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.ttf create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff2 create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/holder.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/html5shiv.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/nv.d3.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/respond.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/method_item.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Node.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Directory.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/File.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Iterator.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/PHP.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Text.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Directory.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Coverage.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Method.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Report.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Unit.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Node.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Project.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Tests.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Totals.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Util.php create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage/Util/InvalidArgumentHelper.php create mode 100644 vendor/phpunit/php-code-coverage/tests/PHP/CodeCoverage/FilterTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/PHP/CodeCoverage/Report/CloverTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/PHP/CodeCoverage/Report/FactoryTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/PHP/CodeCoverage/UtilTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/PHP/CodeCoverageTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/TestCase.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodOneLineAnnotationTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassExtendedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_ignore.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_namespace.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_oneline_annotations.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_without_namespace.php create mode 100644 vendor/phpunit/php-file-iterator/.gitattributes create mode 100644 vendor/phpunit/php-file-iterator/.gitignore create mode 100644 vendor/phpunit/php-file-iterator/ChangeLog.md create mode 100644 vendor/phpunit/php-file-iterator/LICENSE create mode 100644 vendor/phpunit/php-file-iterator/README.md create mode 100644 vendor/phpunit/php-file-iterator/composer.json create mode 100644 vendor/phpunit/php-file-iterator/src/Facade.php create mode 100644 vendor/phpunit/php-file-iterator/src/Factory.php create mode 100644 vendor/phpunit/php-file-iterator/src/Iterator.php create mode 100644 vendor/phpunit/php-text-template/.gitattributes create mode 100644 vendor/phpunit/php-text-template/.gitignore create mode 100644 vendor/phpunit/php-text-template/LICENSE create mode 100644 vendor/phpunit/php-text-template/README.md create mode 100644 vendor/phpunit/php-text-template/composer.json create mode 100644 vendor/phpunit/php-text-template/src/Template.php create mode 100644 vendor/phpunit/php-timer/.gitattributes create mode 100644 vendor/phpunit/php-timer/.gitignore create mode 100644 vendor/phpunit/php-timer/.travis.yml create mode 100644 vendor/phpunit/php-timer/LICENSE create mode 100644 vendor/phpunit/php-timer/README.md create mode 100644 vendor/phpunit/php-timer/composer.json create mode 100644 vendor/phpunit/php-timer/src/Timer.php create mode 100644 vendor/phpunit/php-timer/tests/TimerTest.php create mode 100644 vendor/phpunit/php-token-stream/.gitattributes create mode 100644 vendor/phpunit/php-token-stream/.gitignore create mode 100644 vendor/phpunit/php-token-stream/.travis.yml create mode 100644 vendor/phpunit/php-token-stream/LICENSE create mode 100644 vendor/phpunit/php-token-stream/README.md create mode 100644 vendor/phpunit/php-token-stream/build.xml create mode 100644 vendor/phpunit/php-token-stream/build/phpunit.xml create mode 100644 vendor/phpunit/php-token-stream/composer.json create mode 100644 vendor/phpunit/php-token-stream/src/Token.php create mode 100644 vendor/phpunit/php-token-stream/src/Token/Stream.php create mode 100644 vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/ClassTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/TokenTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/classInNamespace.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/classInScopedNamespace.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class2.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/closure.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/issue19.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/issue30.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingBraces.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingNonBraceSyntax.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source2.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source3.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source4.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source5.php create mode 100644 vendor/phpunit/php-token-stream/tests/bootstrap.php create mode 100644 vendor/phpunit/phpunit-mock-objects/.gitattributes create mode 100644 vendor/phpunit/phpunit-mock-objects/.gitignore create mode 100644 vendor/phpunit/phpunit-mock-objects/.travis.yml create mode 100644 vendor/phpunit/phpunit-mock-objects/CONTRIBUTING.md create mode 100644 vendor/phpunit/phpunit-mock-objects/LICENSE create mode 100644 vendor/phpunit/phpunit-mock-objects/README.md create mode 100644 vendor/phpunit/phpunit-mock-objects/build.xml create mode 100644 vendor/phpunit/phpunit-mock-objects/build/travis-ci.xml create mode 100644 vendor/phpunit/phpunit-mock-objects/composer.json create mode 100644 vendor/phpunit/phpunit-mock-objects/phpunit.xml.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class_method.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_clone.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_static_method.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/trait_class.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/unmocked_clone.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_class.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_method.tpl.dist create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php create mode 100644 vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/GeneratorTest.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockBuilderTest.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/232.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/ObjectTest.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/StaticTest.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/Matcher/ConsecutiveParametersTest.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/abstract_class.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_call_parent_clone.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_call_parent_constructor.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_dont_call_parent_clone.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_dont_call_parent_constructor.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_implementing_interface_call_parent_constructor.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_implementing_interface_dont_call_parent_constructor.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_partial.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_with_method_named_method.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_with_method_with_variadic_arguments.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/interface.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/invocation_object_clone_object.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_class.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_class_call_parent_clone.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_class_call_parent_constructor.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_class_dont_call_parent_clone.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_class_dont_call_parent_constructor.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_class_implementing_interface_call_parent_constructor.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_class_implementing_interface_dont_call_parent_constructor.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_class_partial.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/namespaced_interface.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/nonexistent_class.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/nonexistent_class_with_namespace.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/nonexistent_class_with_namespace_starting_with_separator.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/proxy.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/scalar_type_declarations.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/wsdl_class.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/wsdl_class_namespace.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObject/wsdl_class_partial.phpt create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/MockObjectTest.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/ProxyObjectTest.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractMockTestClass.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractTrait.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterface.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnotherInterface.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/Bar.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassThatImplementsSerializable.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithStaticMethod.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/Foo.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/FunctionCallback.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/GoogleSearch.wsdl create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithStaticMethod.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallback.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallbackByReference.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/MockTestInterface.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/Mockable.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/PartialMockTestClass.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/SingletonClass.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/SomeClass.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/StaticMockTestClass.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/_fixture/TraversableMockTestInterface.php create mode 100644 vendor/phpunit/phpunit-mock-objects/tests/bootstrap.php create mode 100644 vendor/phpunit/phpunit/.gitattributes create mode 100644 vendor/phpunit/phpunit/.gitignore create mode 100644 vendor/phpunit/phpunit/.php_cs create mode 100644 vendor/phpunit/phpunit/.travis.yml create mode 100644 vendor/phpunit/phpunit/CODE_OF_CONDUCT.md create mode 100644 vendor/phpunit/phpunit/CONTRIBUTING.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.0.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.1.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.2.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.3.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.4.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.5.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.6.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.7.md create mode 100644 vendor/phpunit/phpunit/ChangeLog-4.8.md create mode 100644 vendor/phpunit/phpunit/LICENSE create mode 100644 vendor/phpunit/phpunit/README.md create mode 100644 vendor/phpunit/phpunit/build.xml create mode 100755 vendor/phpunit/phpunit/build/bin/phpab create mode 100644 vendor/phpunit/phpunit/build/binary-phar-autoload.php.in create mode 100644 vendor/phpunit/phpunit/build/ca.pem create mode 100644 vendor/phpunit/phpunit/build/library-phar-autoload.php.in create mode 100755 vendor/phpunit/phpunit/build/phar-manifest.php create mode 100755 vendor/phpunit/phpunit/build/phar-version.php create mode 100644 vendor/phpunit/phpunit/build/travis-ci-fail.xml create mode 100644 vendor/phpunit/phpunit/composer.json create mode 100644 vendor/phpunit/phpunit/phpdox.xml.dist create mode 100755 vendor/phpunit/phpunit/phpunit create mode 100644 vendor/phpunit/phpunit/phpunit.xml.dist create mode 100644 vendor/phpunit/phpunit/phpunit.xsd create mode 100644 vendor/phpunit/phpunit/src/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Extensions/GroupTestSuite.php create mode 100644 vendor/phpunit/phpunit/src/Extensions/PhptTestCase.php create mode 100644 vendor/phpunit/phpunit/src/Extensions/PhptTestSuite.php create mode 100644 vendor/phpunit/phpunit/src/Extensions/RepeatedTest.php create mode 100644 vendor/phpunit/phpunit/src/Extensions/TestDecorator.php create mode 100644 vendor/phpunit/phpunit/src/Extensions/TicketListener.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Assert.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Assert/Functions.php create mode 100644 vendor/phpunit/phpunit/src/Framework/AssertionFailedError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/BaseTestListener.php create mode 100644 vendor/phpunit/phpunit/src/Framework/CodeCoverageException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/And.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Count.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Not.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Or.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/StringMatches.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Xor.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Error.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Error/Notice.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Error/Warning.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php create mode 100644 vendor/phpunit/phpunit/src/Framework/ExpectationFailedException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/IncompleteTest.php create mode 100644 vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php create mode 100644 vendor/phpunit/phpunit/src/Framework/IncompleteTestError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/InvalidCoversTargetError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/OutputError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/RiskyTest.php create mode 100644 vendor/phpunit/phpunit/src/Framework/RiskyTestError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SelfDescribing.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SkippedTest.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SkippedTestError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SyntheticError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Test.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestCase.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestFailure.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestListener.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestResult.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestSuite.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php create mode 100644 vendor/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Warning.php create mode 100644 vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/Factory.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/Group.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/Group/Include.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/Test.php create mode 100644 vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php create mode 100644 vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Version.php create mode 100644 vendor/phpunit/phpunit/src/TextUI/Command.php create mode 100644 vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php create mode 100644 vendor/phpunit/phpunit/src/TextUI/TestRunner.php create mode 100644 vendor/phpunit/phpunit/src/Util/Blacklist.php create mode 100644 vendor/phpunit/phpunit/src/Util/Configuration.php create mode 100644 vendor/phpunit/phpunit/src/Util/ErrorHandler.php create mode 100644 vendor/phpunit/phpunit/src/Util/Fileloader.php create mode 100644 vendor/phpunit/phpunit/src/Util/Filesystem.php create mode 100644 vendor/phpunit/phpunit/src/Util/Filter.php create mode 100644 vendor/phpunit/phpunit/src/Util/Getopt.php create mode 100644 vendor/phpunit/phpunit/src/Util/GlobalState.php create mode 100644 vendor/phpunit/phpunit/src/Util/InvalidArgumentHelper.php create mode 100644 vendor/phpunit/phpunit/src/Util/Log/JSON.php create mode 100644 vendor/phpunit/phpunit/src/Util/Log/JUnit.php create mode 100644 vendor/phpunit/phpunit/src/Util/Log/TAP.php create mode 100644 vendor/phpunit/phpunit/src/Util/PHP.php create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/Default.php create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl.dist create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/Windows.php create mode 100644 vendor/phpunit/phpunit/src/Util/Printer.php create mode 100644 vendor/phpunit/phpunit/src/Util/Regex.php create mode 100644 vendor/phpunit/phpunit/src/Util/String.php create mode 100644 vendor/phpunit/phpunit/src/Util/Test.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestSuiteIterator.php create mode 100644 vendor/phpunit/phpunit/src/Util/Type.php create mode 100644 vendor/phpunit/phpunit/src/Util/XML.php create mode 100644 vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php create mode 100644 vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php create mode 100644 vendor/phpunit/phpunit/tests/Fail/fail.phpt create mode 100644 vendor/phpunit/phpunit/tests/Framework/AssertTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/SuiteTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php create mode 100644 vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/1021.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/1021/Issue1021Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/523.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/523/Issue523Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/578.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/578/Issue578Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/684.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/684/Issue684Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/783.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/783/ChildSuite.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/783/OneTest.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/783/ParentSuite.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/783/TwoTest.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1216/phpunit1216.xml create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1351/Issue1351Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/322/phpunit322.xml create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/74/NewException.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/765.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/863.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt create mode 100644 vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php create mode 100644 vendor/phpunit/phpunit/tests/Runner/BaseTestRunnerTest.php create mode 100644 vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/debug.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/default.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/failure.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/group.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/help.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/help2.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/log-json-no-pretty-print.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/log-json-pre-66021.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/log-xml.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/repeat.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/tap.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt create mode 100644 vendor/phpunit/phpunit/tests/TextUI/testdox.phpt create mode 100644 vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php create mode 100644 vendor/phpunit/phpunit/tests/Util/GetoptTest.php create mode 100644 vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php create mode 100644 vendor/phpunit/phpunit/tests/Util/RegexTest.php create mode 100644 vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php create mode 100644 vendor/phpunit/phpunit/tests/Util/TestTest.php create mode 100644 vendor/phpunit/phpunit/tests/Util/XMLTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/AbstractTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Author.php create mode 100644 vendor/phpunit/phpunit/tests/_files/BankAccount.php create mode 100644 vendor/phpunit/phpunit/tests/_files/BankAccountTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php create mode 100644 vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php create mode 100644 vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/BeforeClassAndAfterClassTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Book.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Calculator.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ChangeCurrentWorkingDirectoryTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ClassWithScalarTypeDeclarations.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ClassWithToString.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ConcreteTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageClassExtendedTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageFunctionTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageMethodOneLineAnnotationTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageNoneTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoveredClass.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CoveredFunction.php create mode 100644 vendor/phpunit/phpunit/tests/_files/CustomPrinter.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DataProviderDebugTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DataProviderTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DependencyTestSuite.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/DummyException.php create mode 100644 vendor/phpunit/phpunit/tests/_files/EmptyTestCaseTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPostConditionsTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ExceptionStackTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ExceptionTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Failure.php create mode 100644 vendor/phpunit/phpunit/tests/_files/FailureTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/FatalTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/IncompleteTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceB.php create mode 100644 vendor/phpunit/phpunit/tests/_files/InheritedTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/IniTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/IsolationTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json create mode 100644 vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json create mode 100644 vendor/phpunit/phpunit/tests/_files/MockRunner.php create mode 100644 vendor/phpunit/phpunit/tests/_files/MultiDependencyTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NoArgTestCaseTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NoTestCaseClass.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NoTestCases.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NonStatic.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NotExistingCoveredElementTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NotVoidTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/NothingTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/OneTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/OutputTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/RequirementsClassBeforeClassHookTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/RequirementsClassDocBlockTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/RequirementsTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/SampleArrayAccess.php create mode 100644 vendor/phpunit/phpunit/tests/_files/SampleClass.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Singleton.php create mode 100644 vendor/phpunit/phpunit/tests/_files/StackTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Struct.php create mode 100644 vendor/phpunit/phpunit/tests/_files/Success.php create mode 100644 vendor/phpunit/phpunit/tests/_files/TemplateMethodsTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/TestIncomplete.php create mode 100644 vendor/phpunit/phpunit/tests/_files/TestIterator.php create mode 100644 vendor/phpunit/phpunit/tests/_files/TestIterator2.php create mode 100644 vendor/phpunit/phpunit/tests/_files/TestSkipped.php create mode 100644 vendor/phpunit/phpunit/tests/_files/TestTestError.php create mode 100644 vendor/phpunit/phpunit/tests/_files/TestWithTest.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/ThrowNoExceptionTestCase.php create mode 100644 vendor/phpunit/phpunit/tests/_files/WasRun.php create mode 100644 vendor/phpunit/phpunit/tests/_files/bar.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/configuration.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/configuration_empty.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt create mode 100644 vendor/phpunit/phpunit/tests/_files/foo.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/structureExpected.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml create mode 100644 vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml create mode 100644 vendor/phpunit/phpunit/tests/bootstrap.php create mode 100644 vendor/psr/log/.gitignore create mode 100644 vendor/psr/log/LICENSE create mode 100644 vendor/psr/log/Psr/Log/AbstractLogger.php create mode 100644 vendor/psr/log/Psr/Log/InvalidArgumentException.php create mode 100644 vendor/psr/log/Psr/Log/LogLevel.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareTrait.php create mode 100644 vendor/psr/log/Psr/Log/LoggerInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 vendor/psr/log/Psr/Log/NullLogger.php create mode 100644 vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php create mode 100644 vendor/psr/log/README.md create mode 100644 vendor/psr/log/composer.json create mode 100644 vendor/rcrowe/twigbridge/CHANGELOG.md create mode 100644 vendor/rcrowe/twigbridge/LICENSE create mode 100644 vendor/rcrowe/twigbridge/README.md create mode 100644 vendor/rcrowe/twigbridge/UPGRADE.md create mode 100644 vendor/rcrowe/twigbridge/composer.json create mode 100644 vendor/rcrowe/twigbridge/config/twigbridge.php create mode 100644 vendor/rcrowe/twigbridge/src/Bridge.php create mode 100644 vendor/rcrowe/twigbridge/src/Command/Clean.php create mode 100644 vendor/rcrowe/twigbridge/src/Command/Lint.php create mode 100644 vendor/rcrowe/twigbridge/src/Command/TwigBridge.php create mode 100644 vendor/rcrowe/twigbridge/src/Engine/Compiler.php create mode 100644 vendor/rcrowe/twigbridge/src/Engine/Twig.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Bridge/Former.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Auth.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Config.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Dump.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Form.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Html.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Input.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Legacy/Facades.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Session.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Str.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Translator.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Laravel/Url.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Loader/Facade/Caller.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Loader/Facades.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Loader/Filters.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Loader/Functions.php create mode 100644 vendor/rcrowe/twigbridge/src/Extension/Loader/Loader.php create mode 100644 vendor/rcrowe/twigbridge/src/Facade/Twig.php create mode 100644 vendor/rcrowe/twigbridge/src/ServiceProvider.php create mode 100644 vendor/rcrowe/twigbridge/src/Twig/Loader.php create mode 100644 vendor/rcrowe/twigbridge/src/Twig/Template.php create mode 100644 vendor/sebastian/comparator/.gitignore create mode 100644 vendor/sebastian/comparator/.travis.yml create mode 100644 vendor/sebastian/comparator/LICENSE create mode 100644 vendor/sebastian/comparator/README.md create mode 100644 vendor/sebastian/comparator/build.xml create mode 100644 vendor/sebastian/comparator/build/travis-ci.xml create mode 100644 vendor/sebastian/comparator/composer.json create mode 100644 vendor/sebastian/comparator/phpunit.xml.dist create mode 100644 vendor/sebastian/comparator/src/ArrayComparator.php create mode 100644 vendor/sebastian/comparator/src/Comparator.php create mode 100644 vendor/sebastian/comparator/src/ComparisonFailure.php create mode 100644 vendor/sebastian/comparator/src/DOMNodeComparator.php create mode 100644 vendor/sebastian/comparator/src/DateTimeComparator.php create mode 100644 vendor/sebastian/comparator/src/DoubleComparator.php create mode 100644 vendor/sebastian/comparator/src/ExceptionComparator.php create mode 100644 vendor/sebastian/comparator/src/Factory.php create mode 100644 vendor/sebastian/comparator/src/MockObjectComparator.php create mode 100644 vendor/sebastian/comparator/src/NumericComparator.php create mode 100644 vendor/sebastian/comparator/src/ObjectComparator.php create mode 100644 vendor/sebastian/comparator/src/ResourceComparator.php create mode 100644 vendor/sebastian/comparator/src/ScalarComparator.php create mode 100644 vendor/sebastian/comparator/src/SplObjectStorageComparator.php create mode 100644 vendor/sebastian/comparator/src/TypeComparator.php create mode 100644 vendor/sebastian/comparator/tests/ArrayComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/DOMNodeComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/DateTimeComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/DoubleComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ExceptionComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/FactoryTest.php create mode 100644 vendor/sebastian/comparator/tests/MockObjectComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/NumericComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ObjectComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ResourceComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ScalarComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/SplObjectStorageComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/TypeComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/_files/Author.php create mode 100644 vendor/sebastian/comparator/tests/_files/Book.php create mode 100644 vendor/sebastian/comparator/tests/_files/ClassWithToString.php create mode 100644 vendor/sebastian/comparator/tests/_files/SampleClass.php create mode 100644 vendor/sebastian/comparator/tests/_files/Struct.php create mode 100644 vendor/sebastian/comparator/tests/_files/TestClass.php create mode 100644 vendor/sebastian/comparator/tests/_files/TestClassComparator.php create mode 100644 vendor/sebastian/comparator/tests/autoload.php create mode 100644 vendor/sebastian/comparator/tests/bootstrap.php create mode 100644 vendor/sebastian/diff/.gitignore create mode 100644 vendor/sebastian/diff/.travis.yml create mode 100644 vendor/sebastian/diff/LICENSE create mode 100644 vendor/sebastian/diff/README.md create mode 100644 vendor/sebastian/diff/build.xml create mode 100644 vendor/sebastian/diff/composer.json create mode 100644 vendor/sebastian/diff/phpunit.xml.dist create mode 100644 vendor/sebastian/diff/src/Chunk.php create mode 100644 vendor/sebastian/diff/src/Diff.php create mode 100644 vendor/sebastian/diff/src/Differ.php create mode 100644 vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php create mode 100644 vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php create mode 100644 vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php create mode 100644 vendor/sebastian/diff/src/Line.php create mode 100644 vendor/sebastian/diff/src/Parser.php create mode 100644 vendor/sebastian/diff/tests/DifferTest.php create mode 100644 vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php create mode 100644 vendor/sebastian/diff/tests/ParserTest.php create mode 100644 vendor/sebastian/diff/tests/fixtures/patch.txt create mode 100644 vendor/sebastian/diff/tests/fixtures/patch2.txt create mode 100644 vendor/sebastian/environment/.gitignore create mode 100644 vendor/sebastian/environment/.travis.yml create mode 100644 vendor/sebastian/environment/LICENSE create mode 100644 vendor/sebastian/environment/README.md create mode 100644 vendor/sebastian/environment/build.xml create mode 100644 vendor/sebastian/environment/composer.json create mode 100644 vendor/sebastian/environment/phpunit.xml.dist create mode 100644 vendor/sebastian/environment/src/Console.php create mode 100644 vendor/sebastian/environment/src/Runtime.php create mode 100644 vendor/sebastian/environment/tests/ConsoleTest.php create mode 100644 vendor/sebastian/environment/tests/RuntimeTest.php create mode 100644 vendor/sebastian/exporter/.gitignore create mode 100644 vendor/sebastian/exporter/.travis.yml create mode 100644 vendor/sebastian/exporter/LICENSE create mode 100644 vendor/sebastian/exporter/README.md create mode 100644 vendor/sebastian/exporter/build.xml create mode 100644 vendor/sebastian/exporter/composer.json create mode 100644 vendor/sebastian/exporter/phpunit.xml.dist create mode 100644 vendor/sebastian/exporter/src/Exporter.php create mode 100644 vendor/sebastian/exporter/tests/ExporterTest.php create mode 100644 vendor/sebastian/global-state/.gitignore create mode 100644 vendor/sebastian/global-state/.travis.yml create mode 100644 vendor/sebastian/global-state/LICENSE create mode 100644 vendor/sebastian/global-state/README.md create mode 100644 vendor/sebastian/global-state/build.xml create mode 100644 vendor/sebastian/global-state/composer.json create mode 100644 vendor/sebastian/global-state/phpunit.xml.dist create mode 100644 vendor/sebastian/global-state/src/Blacklist.php create mode 100644 vendor/sebastian/global-state/src/CodeExporter.php create mode 100644 vendor/sebastian/global-state/src/Exception.php create mode 100644 vendor/sebastian/global-state/src/Restorer.php create mode 100644 vendor/sebastian/global-state/src/RuntimeException.php create mode 100644 vendor/sebastian/global-state/src/Snapshot.php create mode 100644 vendor/sebastian/global-state/tests/BlacklistTest.php create mode 100644 vendor/sebastian/global-state/tests/SnapshotTest.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/BlacklistedChildClass.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/BlacklistedClass.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/BlacklistedImplementor.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/BlacklistedInterface.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/SnapshotClass.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/SnapshotDomDocument.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/SnapshotFunctions.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/SnapshotTrait.php create mode 100644 vendor/sebastian/recursion-context/.gitignore create mode 100644 vendor/sebastian/recursion-context/.travis.yml create mode 100644 vendor/sebastian/recursion-context/LICENSE create mode 100644 vendor/sebastian/recursion-context/README.md create mode 100644 vendor/sebastian/recursion-context/build.xml create mode 100644 vendor/sebastian/recursion-context/composer.json create mode 100644 vendor/sebastian/recursion-context/phpunit.xml.dist create mode 100644 vendor/sebastian/recursion-context/src/Context.php create mode 100644 vendor/sebastian/recursion-context/src/Exception.php create mode 100644 vendor/sebastian/recursion-context/src/InvalidArgumentException.php create mode 100644 vendor/sebastian/recursion-context/tests/ContextTest.php create mode 100644 vendor/sebastian/version/.gitattributes create mode 100644 vendor/sebastian/version/.gitignore create mode 100644 vendor/sebastian/version/LICENSE create mode 100644 vendor/sebastian/version/README.md create mode 100644 vendor/sebastian/version/composer.json create mode 100644 vendor/sebastian/version/src/Version.php create mode 100644 vendor/symfony/console/.gitignore create mode 100644 vendor/symfony/console/Application.php create mode 100644 vendor/symfony/console/CHANGELOG.md create mode 100644 vendor/symfony/console/Command/Command.php create mode 100644 vendor/symfony/console/Command/HelpCommand.php create mode 100644 vendor/symfony/console/Command/ListCommand.php create mode 100644 vendor/symfony/console/ConsoleEvents.php create mode 100644 vendor/symfony/console/Descriptor/ApplicationDescription.php create mode 100644 vendor/symfony/console/Descriptor/Descriptor.php create mode 100644 vendor/symfony/console/Descriptor/DescriptorInterface.php create mode 100644 vendor/symfony/console/Descriptor/JsonDescriptor.php create mode 100644 vendor/symfony/console/Descriptor/MarkdownDescriptor.php create mode 100644 vendor/symfony/console/Descriptor/TextDescriptor.php create mode 100644 vendor/symfony/console/Descriptor/XmlDescriptor.php create mode 100644 vendor/symfony/console/Event/ConsoleCommandEvent.php create mode 100644 vendor/symfony/console/Event/ConsoleEvent.php create mode 100644 vendor/symfony/console/Event/ConsoleExceptionEvent.php create mode 100644 vendor/symfony/console/Event/ConsoleTerminateEvent.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatter.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatterInterface.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyle.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyleStack.php create mode 100644 vendor/symfony/console/Helper/DebugFormatterHelper.php create mode 100644 vendor/symfony/console/Helper/DescriptorHelper.php create mode 100644 vendor/symfony/console/Helper/DialogHelper.php create mode 100644 vendor/symfony/console/Helper/FormatterHelper.php create mode 100644 vendor/symfony/console/Helper/Helper.php create mode 100644 vendor/symfony/console/Helper/HelperInterface.php create mode 100644 vendor/symfony/console/Helper/HelperSet.php create mode 100644 vendor/symfony/console/Helper/InputAwareHelper.php create mode 100644 vendor/symfony/console/Helper/ProcessHelper.php create mode 100644 vendor/symfony/console/Helper/ProgressBar.php create mode 100644 vendor/symfony/console/Helper/ProgressHelper.php create mode 100644 vendor/symfony/console/Helper/QuestionHelper.php create mode 100644 vendor/symfony/console/Helper/SymfonyQuestionHelper.php create mode 100644 vendor/symfony/console/Helper/Table.php create mode 100644 vendor/symfony/console/Helper/TableCell.php create mode 100644 vendor/symfony/console/Helper/TableHelper.php create mode 100644 vendor/symfony/console/Helper/TableSeparator.php create mode 100644 vendor/symfony/console/Helper/TableStyle.php create mode 100644 vendor/symfony/console/Input/ArgvInput.php create mode 100644 vendor/symfony/console/Input/ArrayInput.php create mode 100644 vendor/symfony/console/Input/Input.php create mode 100644 vendor/symfony/console/Input/InputArgument.php create mode 100644 vendor/symfony/console/Input/InputAwareInterface.php create mode 100644 vendor/symfony/console/Input/InputDefinition.php create mode 100644 vendor/symfony/console/Input/InputInterface.php create mode 100644 vendor/symfony/console/Input/InputOption.php create mode 100644 vendor/symfony/console/Input/StringInput.php create mode 100644 vendor/symfony/console/LICENSE create mode 100644 vendor/symfony/console/Logger/ConsoleLogger.php create mode 100644 vendor/symfony/console/Output/BufferedOutput.php create mode 100644 vendor/symfony/console/Output/ConsoleOutput.php create mode 100644 vendor/symfony/console/Output/ConsoleOutputInterface.php create mode 100644 vendor/symfony/console/Output/NullOutput.php create mode 100644 vendor/symfony/console/Output/Output.php create mode 100644 vendor/symfony/console/Output/OutputInterface.php create mode 100644 vendor/symfony/console/Output/StreamOutput.php create mode 100644 vendor/symfony/console/Question/ChoiceQuestion.php create mode 100644 vendor/symfony/console/Question/ConfirmationQuestion.php create mode 100644 vendor/symfony/console/Question/Question.php create mode 100644 vendor/symfony/console/README.md create mode 100644 vendor/symfony/console/Resources/bin/hiddeninput.exe create mode 100644 vendor/symfony/console/Shell.php create mode 100644 vendor/symfony/console/Style/OutputStyle.php create mode 100644 vendor/symfony/console/Style/StyleInterface.php create mode 100644 vendor/symfony/console/Style/SymfonyStyle.php create mode 100644 vendor/symfony/console/Tester/ApplicationTester.php create mode 100644 vendor/symfony/console/Tester/CommandTester.php create mode 100644 vendor/symfony/console/Tests/ApplicationTest.php create mode 100644 vendor/symfony/console/Tests/Command/CommandTest.php create mode 100644 vendor/symfony/console/Tests/Command/HelpCommandTest.php create mode 100644 vendor/symfony/console/Tests/Command/ListCommandTest.php create mode 100644 vendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php create mode 100644 vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php create mode 100644 vendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php create mode 100644 vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php create mode 100644 vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.php create mode 100644 vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php create mode 100644 vendor/symfony/console/Tests/Fixtures/BarBucCommand.php create mode 100644 vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php create mode 100644 vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.php create mode 100644 vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php create mode 100644 vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.php create mode 100644 vendor/symfony/console/Tests/Fixtures/DummyOutput.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Foo1Command.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Foo2Command.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Foo3Command.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Foo4Command.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Foo5Command.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Foo6Command.php create mode 100644 vendor/symfony/console/Tests/Fixtures/FooCommand.php create mode 100644 vendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php create mode 100644 vendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php create mode 100644 vendor/symfony/console/Tests/Fixtures/FoobarCommand.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.php create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/TestCommand.php create mode 100644 vendor/symfony/console/Tests/Fixtures/application_1.json create mode 100644 vendor/symfony/console/Tests/Fixtures/application_1.md create mode 100644 vendor/symfony/console/Tests/Fixtures/application_1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_1.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/application_2.json create mode 100644 vendor/symfony/console/Tests/Fixtures/application_2.md create mode 100644 vendor/symfony/console/Tests/Fixtures/application_2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_2.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/application_astext1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_astext2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_asxml1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_asxml2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_gethelp.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_renderexception1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_renderexception2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_renderexception3.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_renderexception3decorated.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_renderexception4.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_run1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_run2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_run3.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/application_run4.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/command_1.json create mode 100644 vendor/symfony/console/Tests/Fixtures/command_1.md create mode 100644 vendor/symfony/console/Tests/Fixtures/command_1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/command_1.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/command_2.json create mode 100644 vendor/symfony/console/Tests/Fixtures/command_2.md create mode 100644 vendor/symfony/console/Tests/Fixtures/command_2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/command_2.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/command_astext.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/command_asxml.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/definition_astext.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/definition_asxml.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_1.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_1.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_1.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_2.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_2.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_2.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_3.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_3.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_3.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_3.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_4.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_4.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_4.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_argument_4.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_1.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_1.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_1.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_2.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_2.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_2.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_3.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_3.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_3.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_3.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_4.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_4.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_4.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_definition_4.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_1.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_1.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_1.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_1.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_2.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_2.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_2.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_2.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_3.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_3.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_3.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_3.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_4.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_4.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_4.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_4.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_5.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_5.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_5.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_5.xml create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_6.json create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_6.md create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_6.txt create mode 100644 vendor/symfony/console/Tests/Fixtures/input_option_6.xml create mode 100644 vendor/symfony/console/Tests/Formatter/OutputFormatterStyleStackTest.php create mode 100644 vendor/symfony/console/Tests/Formatter/OutputFormatterStyleTest.php create mode 100644 vendor/symfony/console/Tests/Formatter/OutputFormatterTest.php create mode 100644 vendor/symfony/console/Tests/Helper/FormatterHelperTest.php create mode 100644 vendor/symfony/console/Tests/Helper/HelperSetTest.php create mode 100644 vendor/symfony/console/Tests/Helper/LegacyDialogHelperTest.php create mode 100644 vendor/symfony/console/Tests/Helper/LegacyProgressHelperTest.php create mode 100644 vendor/symfony/console/Tests/Helper/LegacyTableHelperTest.php create mode 100644 vendor/symfony/console/Tests/Helper/ProcessHelperTest.php create mode 100644 vendor/symfony/console/Tests/Helper/ProgressBarTest.php create mode 100644 vendor/symfony/console/Tests/Helper/QuestionHelperTest.php create mode 100644 vendor/symfony/console/Tests/Helper/TableStyleTest.php create mode 100644 vendor/symfony/console/Tests/Helper/TableTest.php create mode 100644 vendor/symfony/console/Tests/Input/ArgvInputTest.php create mode 100644 vendor/symfony/console/Tests/Input/ArrayInputTest.php create mode 100644 vendor/symfony/console/Tests/Input/InputArgumentTest.php create mode 100644 vendor/symfony/console/Tests/Input/InputDefinitionTest.php create mode 100644 vendor/symfony/console/Tests/Input/InputOptionTest.php create mode 100644 vendor/symfony/console/Tests/Input/InputTest.php create mode 100644 vendor/symfony/console/Tests/Input/StringInputTest.php create mode 100644 vendor/symfony/console/Tests/Logger/ConsoleLoggerTest.php create mode 100644 vendor/symfony/console/Tests/Output/ConsoleOutputTest.php create mode 100644 vendor/symfony/console/Tests/Output/NullOutputTest.php create mode 100644 vendor/symfony/console/Tests/Output/OutputTest.php create mode 100644 vendor/symfony/console/Tests/Output/StreamOutputTest.php create mode 100644 vendor/symfony/console/Tests/Style/SymfonyStyleTest.php create mode 100644 vendor/symfony/console/Tests/Tester/ApplicationTesterTest.php create mode 100644 vendor/symfony/console/Tests/Tester/CommandTesterTest.php create mode 100644 vendor/symfony/console/composer.json create mode 100644 vendor/symfony/console/phpunit.xml.dist create mode 100644 vendor/symfony/debug/.gitignore create mode 100644 vendor/symfony/debug/CHANGELOG.md create mode 100644 vendor/symfony/debug/Debug.php create mode 100644 vendor/symfony/debug/DebugClassLoader.php create mode 100644 vendor/symfony/debug/ErrorHandler.php create mode 100644 vendor/symfony/debug/Exception/ClassNotFoundException.php create mode 100644 vendor/symfony/debug/Exception/ContextErrorException.php create mode 100644 vendor/symfony/debug/Exception/DummyException.php create mode 100644 vendor/symfony/debug/Exception/FatalErrorException.php create mode 100644 vendor/symfony/debug/Exception/FatalThrowableError.php create mode 100644 vendor/symfony/debug/Exception/FlattenException.php create mode 100644 vendor/symfony/debug/Exception/OutOfMemoryException.php create mode 100644 vendor/symfony/debug/Exception/UndefinedFunctionException.php create mode 100644 vendor/symfony/debug/Exception/UndefinedMethodException.php create mode 100644 vendor/symfony/debug/ExceptionHandler.php create mode 100644 vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php create mode 100644 vendor/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php create mode 100644 vendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php create mode 100644 vendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php create mode 100644 vendor/symfony/debug/LICENSE create mode 100644 vendor/symfony/debug/README.md create mode 100644 vendor/symfony/debug/Resources/ext/README.md create mode 100644 vendor/symfony/debug/Resources/ext/config.m4 create mode 100644 vendor/symfony/debug/Resources/ext/config.w32 create mode 100644 vendor/symfony/debug/Resources/ext/php_symfony_debug.h create mode 100644 vendor/symfony/debug/Resources/ext/symfony_debug.c create mode 100644 vendor/symfony/debug/Resources/ext/tests/001.phpt create mode 100644 vendor/symfony/debug/Resources/ext/tests/002.phpt create mode 100644 vendor/symfony/debug/Resources/ext/tests/002_1.phpt create mode 100644 vendor/symfony/debug/Resources/ext/tests/003.phpt create mode 100644 vendor/symfony/debug/Tests/DebugClassLoaderTest.php create mode 100644 vendor/symfony/debug/Tests/ErrorHandlerTest.php create mode 100644 vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php create mode 100644 vendor/symfony/debug/Tests/ExceptionHandlerTest.php create mode 100644 vendor/symfony/debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php create mode 100644 vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php create mode 100644 vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php create mode 100644 vendor/symfony/debug/Tests/Fixtures/ClassAlias.php create mode 100644 vendor/symfony/debug/Tests/Fixtures/DeprecatedClass.php create mode 100644 vendor/symfony/debug/Tests/Fixtures/DeprecatedInterface.php create mode 100644 vendor/symfony/debug/Tests/Fixtures/PEARClass.php create mode 100644 vendor/symfony/debug/Tests/Fixtures/casemismatch.php create mode 100644 vendor/symfony/debug/Tests/Fixtures/notPsr0Bis.php create mode 100644 vendor/symfony/debug/Tests/Fixtures/psr4/Psr4CaseMismatch.php create mode 100644 vendor/symfony/debug/Tests/Fixtures/reallyNotPsr0.php create mode 100644 vendor/symfony/debug/Tests/Fixtures2/RequiredTwice.php create mode 100644 vendor/symfony/debug/Tests/HeaderMock.php create mode 100644 vendor/symfony/debug/Tests/MockExceptionHandler.php create mode 100644 vendor/symfony/debug/composer.json create mode 100644 vendor/symfony/debug/phpunit.xml.dist create mode 100644 vendor/symfony/dom-crawler/.gitignore create mode 100644 vendor/symfony/dom-crawler/CHANGELOG.md create mode 100644 vendor/symfony/dom-crawler/Crawler.php create mode 100644 vendor/symfony/dom-crawler/Field/ChoiceFormField.php create mode 100644 vendor/symfony/dom-crawler/Field/FileFormField.php create mode 100644 vendor/symfony/dom-crawler/Field/FormField.php create mode 100644 vendor/symfony/dom-crawler/Field/InputFormField.php create mode 100644 vendor/symfony/dom-crawler/Field/TextareaFormField.php create mode 100644 vendor/symfony/dom-crawler/Form.php create mode 100644 vendor/symfony/dom-crawler/FormFieldRegistry.php create mode 100644 vendor/symfony/dom-crawler/LICENSE create mode 100644 vendor/symfony/dom-crawler/Link.php create mode 100644 vendor/symfony/dom-crawler/README.md create mode 100755 vendor/symfony/dom-crawler/Tests/CrawlerTest.php create mode 100644 vendor/symfony/dom-crawler/Tests/Field/ChoiceFormFieldTest.php create mode 100644 vendor/symfony/dom-crawler/Tests/Field/FileFormFieldTest.php create mode 100644 vendor/symfony/dom-crawler/Tests/Field/FormFieldTest.php create mode 100644 vendor/symfony/dom-crawler/Tests/Field/FormFieldTestCase.php create mode 100644 vendor/symfony/dom-crawler/Tests/Field/InputFormFieldTest.php create mode 100644 vendor/symfony/dom-crawler/Tests/Field/TextareaFormFieldTest.php create mode 100644 vendor/symfony/dom-crawler/Tests/Fixtures/no-extension create mode 100644 vendor/symfony/dom-crawler/Tests/Fixtures/windows-1250.html create mode 100644 vendor/symfony/dom-crawler/Tests/FormTest.php create mode 100644 vendor/symfony/dom-crawler/Tests/LinkTest.php create mode 100644 vendor/symfony/dom-crawler/composer.json create mode 100644 vendor/symfony/dom-crawler/phpunit.xml.dist create mode 100644 vendor/symfony/event-dispatcher/.gitignore create mode 100644 vendor/symfony/event-dispatcher/CHANGELOG.md create mode 100644 vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php create mode 100644 vendor/symfony/event-dispatcher/Debug/WrappedListener.php create mode 100644 vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php create mode 100644 vendor/symfony/event-dispatcher/Event.php create mode 100644 vendor/symfony/event-dispatcher/EventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/EventDispatcherInterface.php create mode 100644 vendor/symfony/event-dispatcher/EventSubscriberInterface.php create mode 100644 vendor/symfony/event-dispatcher/GenericEvent.php create mode 100644 vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/LICENSE create mode 100644 vendor/symfony/event-dispatcher/README.md create mode 100644 vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/EventTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/GenericEventTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/composer.json create mode 100644 vendor/symfony/event-dispatcher/phpunit.xml.dist create mode 100644 vendor/symfony/finder/.gitignore create mode 100644 vendor/symfony/finder/Adapter/AbstractAdapter.php create mode 100644 vendor/symfony/finder/Adapter/AbstractFindAdapter.php create mode 100644 vendor/symfony/finder/Adapter/AdapterInterface.php create mode 100644 vendor/symfony/finder/Adapter/BsdFindAdapter.php create mode 100644 vendor/symfony/finder/Adapter/GnuFindAdapter.php create mode 100644 vendor/symfony/finder/Adapter/PhpAdapter.php create mode 100644 vendor/symfony/finder/CHANGELOG.md create mode 100644 vendor/symfony/finder/Comparator/Comparator.php create mode 100644 vendor/symfony/finder/Comparator/DateComparator.php create mode 100644 vendor/symfony/finder/Comparator/NumberComparator.php create mode 100644 vendor/symfony/finder/Exception/AccessDeniedException.php create mode 100644 vendor/symfony/finder/Exception/AdapterFailureException.php create mode 100644 vendor/symfony/finder/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/finder/Exception/OperationNotPermitedException.php create mode 100644 vendor/symfony/finder/Exception/ShellCommandFailureException.php create mode 100644 vendor/symfony/finder/Expression/Expression.php create mode 100644 vendor/symfony/finder/Expression/Glob.php create mode 100644 vendor/symfony/finder/Expression/Regex.php create mode 100644 vendor/symfony/finder/Expression/ValueInterface.php create mode 100644 vendor/symfony/finder/Finder.php create mode 100644 vendor/symfony/finder/Glob.php create mode 100644 vendor/symfony/finder/Iterator/CustomFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/DateRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/FilePathsIterator.php create mode 100644 vendor/symfony/finder/Iterator/FileTypeFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/FilecontentFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/FilenameFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/FilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/PathFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php create mode 100644 vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/SortableIterator.php create mode 100644 vendor/symfony/finder/LICENSE create mode 100644 vendor/symfony/finder/README.md create mode 100644 vendor/symfony/finder/Shell/Command.php create mode 100644 vendor/symfony/finder/Shell/Shell.php create mode 100644 vendor/symfony/finder/SplFileInfo.php create mode 100644 vendor/symfony/finder/Tests/BsdFinderTest.php create mode 100644 vendor/symfony/finder/Tests/Comparator/ComparatorTest.php create mode 100644 vendor/symfony/finder/Tests/Comparator/DateComparatorTest.php create mode 100644 vendor/symfony/finder/Tests/Comparator/NumberComparatorTest.php create mode 100644 vendor/symfony/finder/Tests/Expression/ExpressionTest.php create mode 100644 vendor/symfony/finder/Tests/Expression/GlobTest.php create mode 100644 vendor/symfony/finder/Tests/Expression/RegexTest.php create mode 100644 vendor/symfony/finder/Tests/FakeAdapter/DummyAdapter.php create mode 100644 vendor/symfony/finder/Tests/FakeAdapter/FailingAdapter.php create mode 100644 vendor/symfony/finder/Tests/FakeAdapter/NamedAdapter.php create mode 100644 vendor/symfony/finder/Tests/FakeAdapter/UnsupportedAdapter.php create mode 100644 vendor/symfony/finder/Tests/FinderTest.php create mode 100644 vendor/symfony/finder/Tests/Fixtures/A/B/C/abc.dat create mode 100644 vendor/symfony/finder/Tests/Fixtures/A/B/ab.dat create mode 100644 vendor/symfony/finder/Tests/Fixtures/A/a.dat create mode 100644 vendor/symfony/finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy create mode 100644 vendor/symfony/finder/Tests/Fixtures/copy/A/B/ab.dat.copy create mode 100644 vendor/symfony/finder/Tests/Fixtures/copy/A/a.dat.copy create mode 100644 vendor/symfony/finder/Tests/Fixtures/dolor.txt create mode 100644 vendor/symfony/finder/Tests/Fixtures/ipsum.txt create mode 100644 vendor/symfony/finder/Tests/Fixtures/lorem.txt create mode 100644 vendor/symfony/finder/Tests/Fixtures/one/a create mode 100644 vendor/symfony/finder/Tests/Fixtures/one/b/c.neon create mode 100644 vendor/symfony/finder/Tests/Fixtures/one/b/d.neon create mode 100644 vendor/symfony/finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat create mode 100644 vendor/symfony/finder/Tests/Fixtures/with space/foo.txt create mode 100755 vendor/symfony/finder/Tests/GlobTest.php create mode 100644 vendor/symfony/finder/Tests/GnuFinderTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/CustomFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/DateRangeFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/DepthRangeFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/FilePathsIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/FileTypeFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/FilecontentFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/FilenameFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/FilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/Iterator.php create mode 100644 vendor/symfony/finder/Tests/Iterator/IteratorTestCase.php create mode 100644 vendor/symfony/finder/Tests/Iterator/MockFileListIterator.php create mode 100644 vendor/symfony/finder/Tests/Iterator/MockSplFileInfo.php create mode 100644 vendor/symfony/finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/PathFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/RealIteratorTestCase.php create mode 100644 vendor/symfony/finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/SizeRangeFilterIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Iterator/SortableIteratorTest.php create mode 100644 vendor/symfony/finder/Tests/Shell/CommandTest.php create mode 100644 vendor/symfony/finder/composer.json create mode 100644 vendor/symfony/finder/phpunit.xml.dist create mode 100644 vendor/symfony/http-foundation/.gitignore create mode 100644 vendor/symfony/http-foundation/AcceptHeader.php create mode 100644 vendor/symfony/http-foundation/AcceptHeaderItem.php create mode 100644 vendor/symfony/http-foundation/ApacheRequest.php create mode 100644 vendor/symfony/http-foundation/BinaryFileResponse.php create mode 100644 vendor/symfony/http-foundation/CHANGELOG.md create mode 100644 vendor/symfony/http-foundation/Cookie.php create mode 100644 vendor/symfony/http-foundation/ExpressionRequestMatcher.php create mode 100644 vendor/symfony/http-foundation/File/Exception/AccessDeniedException.php create mode 100644 vendor/symfony/http-foundation/File/Exception/FileException.php create mode 100644 vendor/symfony/http-foundation/File/Exception/FileNotFoundException.php create mode 100644 vendor/symfony/http-foundation/File/Exception/UnexpectedTypeException.php create mode 100644 vendor/symfony/http-foundation/File/Exception/UploadException.php create mode 100644 vendor/symfony/http-foundation/File/File.php create mode 100644 vendor/symfony/http-foundation/File/MimeType/ExtensionGuesser.php create mode 100644 vendor/symfony/http-foundation/File/MimeType/ExtensionGuesserInterface.php create mode 100644 vendor/symfony/http-foundation/File/MimeType/FileBinaryMimeTypeGuesser.php create mode 100644 vendor/symfony/http-foundation/File/MimeType/FileinfoMimeTypeGuesser.php create mode 100644 vendor/symfony/http-foundation/File/MimeType/MimeTypeExtensionGuesser.php create mode 100644 vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesser.php create mode 100644 vendor/symfony/http-foundation/File/MimeType/MimeTypeGuesserInterface.php create mode 100644 vendor/symfony/http-foundation/File/UploadedFile.php create mode 100644 vendor/symfony/http-foundation/FileBag.php create mode 100644 vendor/symfony/http-foundation/HeaderBag.php create mode 100644 vendor/symfony/http-foundation/IpUtils.php create mode 100644 vendor/symfony/http-foundation/JsonResponse.php create mode 100644 vendor/symfony/http-foundation/LICENSE create mode 100644 vendor/symfony/http-foundation/ParameterBag.php create mode 100644 vendor/symfony/http-foundation/README.md create mode 100644 vendor/symfony/http-foundation/RedirectResponse.php create mode 100644 vendor/symfony/http-foundation/Request.php create mode 100644 vendor/symfony/http-foundation/RequestMatcher.php create mode 100644 vendor/symfony/http-foundation/RequestMatcherInterface.php create mode 100644 vendor/symfony/http-foundation/RequestStack.php create mode 100644 vendor/symfony/http-foundation/Resources/stubs/SessionHandlerInterface.php create mode 100644 vendor/symfony/http-foundation/Response.php create mode 100644 vendor/symfony/http-foundation/ResponseHeaderBag.php create mode 100644 vendor/symfony/http-foundation/ServerBag.php create mode 100644 vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php create mode 100644 vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php create mode 100644 vendor/symfony/http-foundation/Session/Attribute/NamespacedAttributeBag.php create mode 100644 vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php create mode 100644 vendor/symfony/http-foundation/Session/Flash/FlashBag.php create mode 100644 vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php create mode 100644 vendor/symfony/http-foundation/Session/Session.php create mode 100644 vendor/symfony/http-foundation/Session/SessionBagInterface.php create mode 100644 vendor/symfony/http-foundation/Session/SessionInterface.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/MetadataBag.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php create mode 100644 vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php create mode 100644 vendor/symfony/http-foundation/StreamedResponse.php create mode 100644 vendor/symfony/http-foundation/Tests/AcceptHeaderItemTest.php create mode 100644 vendor/symfony/http-foundation/Tests/AcceptHeaderTest.php create mode 100644 vendor/symfony/http-foundation/Tests/ApacheRequestTest.php create mode 100644 vendor/symfony/http-foundation/Tests/BinaryFileResponseTest.php create mode 100644 vendor/symfony/http-foundation/Tests/CookieTest.php create mode 100644 vendor/symfony/http-foundation/Tests/ExpressionRequestMatcherTest.php create mode 100644 vendor/symfony/http-foundation/Tests/File/FakeFile.php create mode 100644 vendor/symfony/http-foundation/Tests/File/FileTest.php create mode 100644 vendor/symfony/http-foundation/Tests/File/Fixtures/.unknownextension create mode 100644 vendor/symfony/http-foundation/Tests/File/Fixtures/directory/.empty create mode 100644 vendor/symfony/http-foundation/Tests/File/Fixtures/other-file.example create mode 100644 vendor/symfony/http-foundation/Tests/File/Fixtures/test create mode 100644 vendor/symfony/http-foundation/Tests/File/Fixtures/test.gif create mode 100644 vendor/symfony/http-foundation/Tests/File/MimeType/MimeTypeTest.php create mode 100644 vendor/symfony/http-foundation/Tests/File/UploadedFileTest.php create mode 100644 vendor/symfony/http-foundation/Tests/FileBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/HeaderBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/IpUtilsTest.php create mode 100644 vendor/symfony/http-foundation/Tests/JsonResponseTest.php create mode 100644 vendor/symfony/http-foundation/Tests/ParameterBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/RedirectResponseTest.php create mode 100644 vendor/symfony/http-foundation/Tests/RequestMatcherTest.php create mode 100644 vendor/symfony/http-foundation/Tests/RequestStackTest.php create mode 100644 vendor/symfony/http-foundation/Tests/RequestTest.php create mode 100644 vendor/symfony/http-foundation/Tests/ResponseHeaderBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/ResponseTest.php create mode 100644 vendor/symfony/http-foundation/Tests/ResponseTestCase.php create mode 100644 vendor/symfony/http-foundation/Tests/ServerBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Attribute/AttributeBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Flash/AutoExpireFlashBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Flash/FlashBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/SessionTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/LegacyPdoSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Handler/WriteCheckSessionHandlerTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/MetadataBagTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/MockArraySessionStorageTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/MockFileSessionStorageTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/NativeProxyTest.php create mode 100644 vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php create mode 100644 vendor/symfony/http-foundation/Tests/StreamedResponseTest.php create mode 100644 vendor/symfony/http-foundation/composer.json create mode 100644 vendor/symfony/http-foundation/phpunit.xml.dist create mode 100644 vendor/symfony/http-kernel/.gitignore create mode 100644 vendor/symfony/http-kernel/Bundle/Bundle.php create mode 100644 vendor/symfony/http-kernel/Bundle/BundleInterface.php create mode 100644 vendor/symfony/http-kernel/CHANGELOG.md create mode 100644 vendor/symfony/http-kernel/CacheClearer/CacheClearerInterface.php create mode 100644 vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php create mode 100644 vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php create mode 100644 vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php create mode 100644 vendor/symfony/http-kernel/CacheWarmer/CacheWarmerInterface.php create mode 100644 vendor/symfony/http-kernel/CacheWarmer/WarmableInterface.php create mode 100644 vendor/symfony/http-kernel/Client.php create mode 100644 vendor/symfony/http-kernel/Config/EnvParametersResource.php create mode 100644 vendor/symfony/http-kernel/Config/FileLocator.php create mode 100644 vendor/symfony/http-kernel/Controller/ControllerReference.php create mode 100644 vendor/symfony/http-kernel/Controller/ControllerResolver.php create mode 100644 vendor/symfony/http-kernel/Controller/ControllerResolverInterface.php create mode 100644 vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php create mode 100644 vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/DataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/DataCollectorInterface.php create mode 100644 vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/EventDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/LateDataCollectorInterface.php create mode 100644 vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php create mode 100644 vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php create mode 100644 vendor/symfony/http-kernel/Debug/ErrorHandler.php create mode 100644 vendor/symfony/http-kernel/Debug/ExceptionHandler.php create mode 100644 vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php create mode 100644 vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php create mode 100644 vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php create mode 100644 vendor/symfony/http-kernel/DependencyInjection/ContainerAwareHttpKernel.php create mode 100644 vendor/symfony/http-kernel/DependencyInjection/Extension.php create mode 100644 vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php create mode 100644 vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php create mode 100644 vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php create mode 100644 vendor/symfony/http-kernel/DependencyInjection/RegisterListenersPass.php create mode 100644 vendor/symfony/http-kernel/Event/FilterControllerEvent.php create mode 100644 vendor/symfony/http-kernel/Event/FilterResponseEvent.php create mode 100644 vendor/symfony/http-kernel/Event/FinishRequestEvent.php create mode 100644 vendor/symfony/http-kernel/Event/GetResponseEvent.php create mode 100644 vendor/symfony/http-kernel/Event/GetResponseForControllerResultEvent.php create mode 100644 vendor/symfony/http-kernel/Event/GetResponseForExceptionEvent.php create mode 100644 vendor/symfony/http-kernel/Event/KernelEvent.php create mode 100644 vendor/symfony/http-kernel/Event/PostResponseEvent.php create mode 100644 vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/DumpListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/ErrorsLoggerListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/EsiListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/ExceptionListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/FragmentListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/LocaleListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/ProfilerListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/ResponseListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/RouterListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/SaveSessionListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/SessionListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/SurrogateListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/TestSessionListener.php create mode 100644 vendor/symfony/http-kernel/EventListener/TranslatorListener.php create mode 100644 vendor/symfony/http-kernel/Exception/AccessDeniedHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/BadRequestHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/ConflictHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/FatalErrorException.php create mode 100644 vendor/symfony/http-kernel/Exception/FlattenException.php create mode 100644 vendor/symfony/http-kernel/Exception/GoneHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/HttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/HttpExceptionInterface.php create mode 100644 vendor/symfony/http-kernel/Exception/LengthRequiredHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/NotAcceptableHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/NotFoundHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/PreconditionFailedHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/TooManyRequestsHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/UnauthorizedHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php create mode 100644 vendor/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php create mode 100644 vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php create mode 100644 vendor/symfony/http-kernel/Fragment/EsiFragmentRenderer.php create mode 100644 vendor/symfony/http-kernel/Fragment/FragmentHandler.php create mode 100644 vendor/symfony/http-kernel/Fragment/FragmentRendererInterface.php create mode 100644 vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php create mode 100644 vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php create mode 100644 vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php create mode 100644 vendor/symfony/http-kernel/Fragment/SsiFragmentRenderer.php create mode 100644 vendor/symfony/http-kernel/HttpCache/Esi.php create mode 100644 vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategy.php create mode 100644 vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategyInterface.php create mode 100644 vendor/symfony/http-kernel/HttpCache/HttpCache.php create mode 100644 vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php create mode 100644 vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategyInterface.php create mode 100644 vendor/symfony/http-kernel/HttpCache/Ssi.php create mode 100644 vendor/symfony/http-kernel/HttpCache/Store.php create mode 100644 vendor/symfony/http-kernel/HttpCache/StoreInterface.php create mode 100644 vendor/symfony/http-kernel/HttpCache/SurrogateInterface.php create mode 100644 vendor/symfony/http-kernel/HttpKernel.php create mode 100644 vendor/symfony/http-kernel/HttpKernelInterface.php create mode 100644 vendor/symfony/http-kernel/Kernel.php create mode 100644 vendor/symfony/http-kernel/KernelEvents.php create mode 100644 vendor/symfony/http-kernel/KernelInterface.php create mode 100644 vendor/symfony/http-kernel/LICENSE create mode 100644 vendor/symfony/http-kernel/Log/DebugLoggerInterface.php create mode 100644 vendor/symfony/http-kernel/Log/LoggerInterface.php create mode 100644 vendor/symfony/http-kernel/Log/NullLogger.php create mode 100644 vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/Profiler/Profile.php create mode 100644 vendor/symfony/http-kernel/Profiler/Profiler.php create mode 100644 vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php create mode 100644 vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php create mode 100644 vendor/symfony/http-kernel/README.md create mode 100644 vendor/symfony/http-kernel/TerminableInterface.php create mode 100644 vendor/symfony/http-kernel/Tests/Bundle/BundleTest.php create mode 100644 vendor/symfony/http-kernel/Tests/CacheClearer/ChainCacheClearerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/CacheWarmer/CacheWarmerAggregateTest.php create mode 100644 vendor/symfony/http-kernel/Tests/CacheWarmer/CacheWarmerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/ClientTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Config/EnvParametersResourceTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Config/FileLocatorTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Controller/ControllerResolverTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DataCollector/ConfigDataCollectorTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DataCollector/DumpDataCollectorTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DataCollector/ExceptionDataCollectorTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DataCollector/LoggerDataCollectorTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DataCollector/MemoryDataCollectorTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DataCollector/RequestDataCollectorTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DataCollector/TimeDataCollectorTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DataCollector/Util/ValueExporterTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Debug/TraceableEventDispatcherTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DependencyInjection/FragmentRendererPassTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DependencyInjection/LazyLoadingFragmentHandlerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/DependencyInjection/MergeExtensionConfigurationPassTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/AddRequestFormatsListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/DebugHandlersListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/DumpListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/ExceptionListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/FragmentListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/LocaleListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/ProfilerListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/ResponseListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/RouterListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/SurrogateListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/TestSessionListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/EventListener/TranslatorListenerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/BaseBundle/Resources/foo.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/BaseBundle/Resources/hide.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/Bundle1Bundle/Resources/foo.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/Bundle1Bundle/bar.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/Bundle1Bundle/foo.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/Bundle2Bundle/foo.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ChildBundle/Resources/foo.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ChildBundle/Resources/hide.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionAbsentBundle/ExtensionAbsentBundle.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionLoadedBundle/DependencyInjection/ExtensionLoadedExtension.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionLoadedBundle/ExtensionLoadedBundle.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionNotValidBundle/DependencyInjection/ExtensionNotValidExtension.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionNotValidBundle/ExtensionNotValidBundle.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionPresentBundle/Command/BarCommand.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionPresentBundle/Command/FooCommand.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionPresentBundle/DependencyInjection/ExtensionPresentExtension.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/ExtensionPresentBundle/ExtensionPresentBundle.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/FooBarBundle.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/KernelForOverrideName.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/KernelForTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/Resources/BaseBundle/hide.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/Resources/Bundle1Bundle/foo.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/Resources/ChildBundle/foo.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/Resources/FooBundle/foo.txt create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/TestClient.php create mode 100644 vendor/symfony/http-kernel/Tests/Fixtures/TestEventDispatcher.php create mode 100644 vendor/symfony/http-kernel/Tests/Fragment/EsiFragmentRendererTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Fragment/FragmentHandlerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Fragment/HIncludeFragmentRendererTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Fragment/InlineFragmentRendererTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Fragment/RoutableFragmentRendererTest.php create mode 100644 vendor/symfony/http-kernel/Tests/HttpCache/EsiTest.php create mode 100644 vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php create mode 100644 vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTestCase.php create mode 100644 vendor/symfony/http-kernel/Tests/HttpCache/SsiTest.php create mode 100644 vendor/symfony/http-kernel/Tests/HttpCache/StoreTest.php create mode 100644 vendor/symfony/http-kernel/Tests/HttpCache/TestHttpKernel.php create mode 100644 vendor/symfony/http-kernel/Tests/HttpCache/TestMultipleHttpKernel.php create mode 100644 vendor/symfony/http-kernel/Tests/HttpKernelTest.php create mode 100644 vendor/symfony/http-kernel/Tests/KernelTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Logger.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/AbstractProfilerStorageTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/FileProfilerStorageTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/MemcacheProfilerStorageTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/MemcachedProfilerStorageTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/Mock/MemcacheMock.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/Mock/MemcachedMock.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/Mock/RedisMock.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/MongoDbProfilerStorageTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/ProfilerTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/RedisProfilerStorageTest.php create mode 100644 vendor/symfony/http-kernel/Tests/Profiler/SqliteProfilerStorageTest.php create mode 100644 vendor/symfony/http-kernel/Tests/TestHttpKernel.php create mode 100644 vendor/symfony/http-kernel/Tests/UriSignerTest.php create mode 100644 vendor/symfony/http-kernel/UriSigner.php create mode 100644 vendor/symfony/http-kernel/composer.json create mode 100644 vendor/symfony/http-kernel/phpunit.xml.dist create mode 100644 vendor/symfony/process/.gitignore create mode 100644 vendor/symfony/process/CHANGELOG.md create mode 100644 vendor/symfony/process/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/process/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/process/Exception/LogicException.php create mode 100644 vendor/symfony/process/Exception/ProcessFailedException.php create mode 100644 vendor/symfony/process/Exception/ProcessTimedOutException.php create mode 100644 vendor/symfony/process/Exception/RuntimeException.php create mode 100644 vendor/symfony/process/ExecutableFinder.php create mode 100644 vendor/symfony/process/LICENSE create mode 100644 vendor/symfony/process/PhpExecutableFinder.php create mode 100644 vendor/symfony/process/PhpProcess.php create mode 100644 vendor/symfony/process/Pipes/AbstractPipes.php create mode 100644 vendor/symfony/process/Pipes/PipesInterface.php create mode 100644 vendor/symfony/process/Pipes/UnixPipes.php create mode 100644 vendor/symfony/process/Pipes/WindowsPipes.php create mode 100644 vendor/symfony/process/Process.php create mode 100644 vendor/symfony/process/ProcessBuilder.php create mode 100644 vendor/symfony/process/ProcessUtils.php create mode 100644 vendor/symfony/process/README.md create mode 100644 vendor/symfony/process/Tests/AbstractProcessTest.php create mode 100644 vendor/symfony/process/Tests/ExecutableFinderTest.php create mode 100644 vendor/symfony/process/Tests/NonStopableProcess.php create mode 100644 vendor/symfony/process/Tests/PhpExecutableFinderTest.php create mode 100644 vendor/symfony/process/Tests/PhpProcessTest.php create mode 100644 vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php create mode 100644 vendor/symfony/process/Tests/ProcessBuilderTest.php create mode 100644 vendor/symfony/process/Tests/ProcessFailedExceptionTest.php create mode 100644 vendor/symfony/process/Tests/ProcessInSigchildEnvironment.php create mode 100644 vendor/symfony/process/Tests/ProcessUtilsTest.php create mode 100644 vendor/symfony/process/Tests/SigchildDisabledProcessTest.php create mode 100644 vendor/symfony/process/Tests/SigchildEnabledProcessTest.php create mode 100644 vendor/symfony/process/Tests/SignalListener.php create mode 100644 vendor/symfony/process/Tests/SimpleProcessTest.php create mode 100644 vendor/symfony/process/composer.json create mode 100644 vendor/symfony/process/phpunit.xml.dist create mode 100644 vendor/symfony/security-core/.gitignore create mode 100644 vendor/symfony/security-core/Authentication/AuthenticationManagerInterface.php create mode 100644 vendor/symfony/security-core/Authentication/AuthenticationProviderManager.php create mode 100644 vendor/symfony/security-core/Authentication/AuthenticationTrustResolver.php create mode 100644 vendor/symfony/security-core/Authentication/AuthenticationTrustResolverInterface.php create mode 100644 vendor/symfony/security-core/Authentication/Provider/AnonymousAuthenticationProvider.php create mode 100644 vendor/symfony/security-core/Authentication/Provider/AuthenticationProviderInterface.php create mode 100644 vendor/symfony/security-core/Authentication/Provider/DaoAuthenticationProvider.php create mode 100644 vendor/symfony/security-core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php create mode 100644 vendor/symfony/security-core/Authentication/Provider/RememberMeAuthenticationProvider.php create mode 100644 vendor/symfony/security-core/Authentication/Provider/SimpleAuthenticationProvider.php create mode 100644 vendor/symfony/security-core/Authentication/Provider/UserAuthenticationProvider.php create mode 100644 vendor/symfony/security-core/Authentication/RememberMe/InMemoryTokenProvider.php create mode 100644 vendor/symfony/security-core/Authentication/RememberMe/PersistentToken.php create mode 100644 vendor/symfony/security-core/Authentication/RememberMe/PersistentTokenInterface.php create mode 100644 vendor/symfony/security-core/Authentication/RememberMe/TokenProviderInterface.php create mode 100644 vendor/symfony/security-core/Authentication/SimpleAuthenticatorInterface.php create mode 100644 vendor/symfony/security-core/Authentication/SimpleFormAuthenticatorInterface.php create mode 100644 vendor/symfony/security-core/Authentication/SimplePreAuthenticatorInterface.php create mode 100644 vendor/symfony/security-core/Authentication/Token/AbstractToken.php create mode 100644 vendor/symfony/security-core/Authentication/Token/AnonymousToken.php create mode 100644 vendor/symfony/security-core/Authentication/Token/PreAuthenticatedToken.php create mode 100644 vendor/symfony/security-core/Authentication/Token/RememberMeToken.php create mode 100644 vendor/symfony/security-core/Authentication/Token/Storage/TokenStorage.php create mode 100644 vendor/symfony/security-core/Authentication/Token/Storage/TokenStorageInterface.php create mode 100644 vendor/symfony/security-core/Authentication/Token/TokenInterface.php create mode 100644 vendor/symfony/security-core/Authentication/Token/UsernamePasswordToken.php create mode 100644 vendor/symfony/security-core/AuthenticationEvents.php create mode 100644 vendor/symfony/security-core/Authorization/AccessDecisionManager.php create mode 100644 vendor/symfony/security-core/Authorization/AccessDecisionManagerInterface.php create mode 100644 vendor/symfony/security-core/Authorization/AuthorizationChecker.php create mode 100644 vendor/symfony/security-core/Authorization/AuthorizationCheckerInterface.php create mode 100644 vendor/symfony/security-core/Authorization/ExpressionLanguage.php create mode 100644 vendor/symfony/security-core/Authorization/ExpressionLanguageProvider.php create mode 100644 vendor/symfony/security-core/Authorization/Voter/AbstractVoter.php create mode 100644 vendor/symfony/security-core/Authorization/Voter/AuthenticatedVoter.php create mode 100644 vendor/symfony/security-core/Authorization/Voter/ExpressionVoter.php create mode 100644 vendor/symfony/security-core/Authorization/Voter/RoleHierarchyVoter.php create mode 100644 vendor/symfony/security-core/Authorization/Voter/RoleVoter.php create mode 100644 vendor/symfony/security-core/Authorization/Voter/VoterInterface.php create mode 100644 vendor/symfony/security-core/Encoder/BCryptPasswordEncoder.php create mode 100644 vendor/symfony/security-core/Encoder/BasePasswordEncoder.php create mode 100644 vendor/symfony/security-core/Encoder/EncoderAwareInterface.php create mode 100644 vendor/symfony/security-core/Encoder/EncoderFactory.php create mode 100644 vendor/symfony/security-core/Encoder/EncoderFactoryInterface.php create mode 100644 vendor/symfony/security-core/Encoder/MessageDigestPasswordEncoder.php create mode 100644 vendor/symfony/security-core/Encoder/PasswordEncoderInterface.php create mode 100644 vendor/symfony/security-core/Encoder/Pbkdf2PasswordEncoder.php create mode 100644 vendor/symfony/security-core/Encoder/PlaintextPasswordEncoder.php create mode 100644 vendor/symfony/security-core/Encoder/UserPasswordEncoder.php create mode 100644 vendor/symfony/security-core/Encoder/UserPasswordEncoderInterface.php create mode 100644 vendor/symfony/security-core/Event/AuthenticationEvent.php create mode 100644 vendor/symfony/security-core/Event/AuthenticationFailureEvent.php create mode 100644 vendor/symfony/security-core/Exception/AccessDeniedException.php create mode 100644 vendor/symfony/security-core/Exception/AccountExpiredException.php create mode 100644 vendor/symfony/security-core/Exception/AccountStatusException.php create mode 100644 vendor/symfony/security-core/Exception/AuthenticationCredentialsNotFoundException.php create mode 100644 vendor/symfony/security-core/Exception/AuthenticationException.php create mode 100644 vendor/symfony/security-core/Exception/AuthenticationServiceException.php create mode 100644 vendor/symfony/security-core/Exception/BadCredentialsException.php create mode 100644 vendor/symfony/security-core/Exception/CookieTheftException.php create mode 100644 vendor/symfony/security-core/Exception/CredentialsExpiredException.php create mode 100644 vendor/symfony/security-core/Exception/DisabledException.php create mode 100644 vendor/symfony/security-core/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/security-core/Exception/InsufficientAuthenticationException.php create mode 100644 vendor/symfony/security-core/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/security-core/Exception/InvalidCsrfTokenException.php create mode 100644 vendor/symfony/security-core/Exception/LockedException.php create mode 100644 vendor/symfony/security-core/Exception/LogoutException.php create mode 100644 vendor/symfony/security-core/Exception/NonceExpiredException.php create mode 100644 vendor/symfony/security-core/Exception/ProviderNotFoundException.php create mode 100644 vendor/symfony/security-core/Exception/RuntimeException.php create mode 100644 vendor/symfony/security-core/Exception/SessionUnavailableException.php create mode 100644 vendor/symfony/security-core/Exception/TokenNotFoundException.php create mode 100644 vendor/symfony/security-core/Exception/UnsupportedUserException.php create mode 100644 vendor/symfony/security-core/Exception/UsernameNotFoundException.php create mode 100644 vendor/symfony/security-core/LICENSE create mode 100644 vendor/symfony/security-core/README.md create mode 100644 vendor/symfony/security-core/Resources/translations/security.ar.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.az.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.bg.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.ca.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.cs.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.da.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.de.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.el.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.en.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.es.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.fa.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.fr.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.gl.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.he.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.hr.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.hu.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.id.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.it.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.ja.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.lb.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.lt.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.nl.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.no.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.pl.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.pt_BR.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.pt_PT.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.ro.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.ru.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.sk.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.sl.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.sr_Cyrl.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.sr_Latn.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.sv.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.th.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.tr.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.ua.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.vi.xlf create mode 100644 vendor/symfony/security-core/Resources/translations/security.zh_CN.xlf create mode 100644 vendor/symfony/security-core/Role/Role.php create mode 100644 vendor/symfony/security-core/Role/RoleHierarchy.php create mode 100644 vendor/symfony/security-core/Role/RoleHierarchyInterface.php create mode 100644 vendor/symfony/security-core/Role/RoleInterface.php create mode 100644 vendor/symfony/security-core/Role/SwitchUserRole.php create mode 100644 vendor/symfony/security-core/Security.php create mode 100644 vendor/symfony/security-core/SecurityContext.php create mode 100644 vendor/symfony/security-core/SecurityContextInterface.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/AuthenticationProviderManagerTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/AuthenticationTrustResolverTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/RememberMe/InMemoryTokenProviderTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/RememberMe/PersistentTokenTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Token/AbstractTokenTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Token/AnonymousTokenTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Token/RememberMeTokenTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Token/Storage/TokenStorageTest.php create mode 100644 vendor/symfony/security-core/Tests/Authentication/Token/UsernamePasswordTokenTest.php create mode 100644 vendor/symfony/security-core/Tests/Authorization/AccessDecisionManagerTest.php create mode 100644 vendor/symfony/security-core/Tests/Authorization/AuthorizationCheckerTest.php create mode 100644 vendor/symfony/security-core/Tests/Authorization/ExpressionLanguageTest.php create mode 100644 vendor/symfony/security-core/Tests/Authorization/Voter/AbstractVoterTest.php create mode 100644 vendor/symfony/security-core/Tests/Authorization/Voter/AuthenticatedVoterTest.php create mode 100644 vendor/symfony/security-core/Tests/Authorization/Voter/ExpressionVoterTest.php create mode 100644 vendor/symfony/security-core/Tests/Authorization/Voter/RoleHierarchyVoterTest.php create mode 100644 vendor/symfony/security-core/Tests/Authorization/Voter/RoleVoterTest.php create mode 100644 vendor/symfony/security-core/Tests/Encoder/BCryptPasswordEncoderTest.php create mode 100644 vendor/symfony/security-core/Tests/Encoder/BasePasswordEncoderTest.php create mode 100644 vendor/symfony/security-core/Tests/Encoder/EncoderFactoryTest.php create mode 100644 vendor/symfony/security-core/Tests/Encoder/MessageDigestPasswordEncoderTest.php create mode 100644 vendor/symfony/security-core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php create mode 100644 vendor/symfony/security-core/Tests/Encoder/PlaintextPasswordEncoderTest.php create mode 100644 vendor/symfony/security-core/Tests/Encoder/UserPasswordEncoderTest.php create mode 100644 vendor/symfony/security-core/Tests/Exception/UsernameNotFoundExceptionTest.php create mode 100644 vendor/symfony/security-core/Tests/LegacySecurityContextInterfaceTest.php create mode 100644 vendor/symfony/security-core/Tests/LegacySecurityContextTest.php create mode 100644 vendor/symfony/security-core/Tests/Role/RoleHierarchyTest.php create mode 100644 vendor/symfony/security-core/Tests/Role/RoleTest.php create mode 100644 vendor/symfony/security-core/Tests/Role/SwitchUserRoleTest.php create mode 100644 vendor/symfony/security-core/Tests/User/ChainUserProviderTest.php create mode 100644 vendor/symfony/security-core/Tests/User/InMemoryUserProviderTest.php create mode 100644 vendor/symfony/security-core/Tests/User/UserCheckerTest.php create mode 100644 vendor/symfony/security-core/Tests/User/UserTest.php create mode 100644 vendor/symfony/security-core/Tests/Util/ClassUtilsTest.php create mode 100644 vendor/symfony/security-core/Tests/Util/SecureRandomTest.php create mode 100644 vendor/symfony/security-core/Tests/Util/StringUtilsTest.php create mode 100644 vendor/symfony/security-core/Tests/Validator/Constraints/LegacyUserPasswordValidatorTest.php create mode 100644 vendor/symfony/security-core/Tests/Validator/Constraints/UserPasswordValidatorTest.php create mode 100644 vendor/symfony/security-core/User/AdvancedUserInterface.php create mode 100644 vendor/symfony/security-core/User/ChainUserProvider.php create mode 100644 vendor/symfony/security-core/User/EquatableInterface.php create mode 100644 vendor/symfony/security-core/User/InMemoryUserProvider.php create mode 100644 vendor/symfony/security-core/User/User.php create mode 100644 vendor/symfony/security-core/User/UserChecker.php create mode 100644 vendor/symfony/security-core/User/UserCheckerInterface.php create mode 100644 vendor/symfony/security-core/User/UserInterface.php create mode 100644 vendor/symfony/security-core/User/UserProviderInterface.php create mode 100644 vendor/symfony/security-core/Util/ClassUtils.php create mode 100644 vendor/symfony/security-core/Util/SecureRandom.php create mode 100644 vendor/symfony/security-core/Util/SecureRandomInterface.php create mode 100644 vendor/symfony/security-core/Util/StringUtils.php create mode 100644 vendor/symfony/security-core/Validator/Constraints/UserPassword.php create mode 100644 vendor/symfony/security-core/Validator/Constraints/UserPasswordValidator.php create mode 100644 vendor/symfony/security-core/composer.json create mode 100644 vendor/symfony/security-core/phpunit.xml.dist create mode 100644 vendor/symfony/translation/.gitignore create mode 100644 vendor/symfony/translation/CHANGELOG.md create mode 100644 vendor/symfony/translation/Catalogue/AbstractOperation.php create mode 100644 vendor/symfony/translation/Catalogue/DiffOperation.php create mode 100644 vendor/symfony/translation/Catalogue/MergeOperation.php create mode 100644 vendor/symfony/translation/Catalogue/OperationInterface.php create mode 100644 vendor/symfony/translation/DataCollector/TranslationDataCollector.php create mode 100644 vendor/symfony/translation/DataCollectorTranslator.php create mode 100644 vendor/symfony/translation/Dumper/CsvFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/DumperInterface.php create mode 100644 vendor/symfony/translation/Dumper/FileDumper.php create mode 100644 vendor/symfony/translation/Dumper/IcuResFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/IniFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/JsonFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/MoFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/PhpFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/PoFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/QtFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/XliffFileDumper.php create mode 100644 vendor/symfony/translation/Dumper/YamlFileDumper.php create mode 100644 vendor/symfony/translation/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/translation/Exception/InvalidResourceException.php create mode 100644 vendor/symfony/translation/Exception/NotFoundResourceException.php create mode 100644 vendor/symfony/translation/Extractor/AbstractFileExtractor.php create mode 100644 vendor/symfony/translation/Extractor/ChainExtractor.php create mode 100644 vendor/symfony/translation/Extractor/ExtractorInterface.php create mode 100644 vendor/symfony/translation/IdentityTranslator.php create mode 100644 vendor/symfony/translation/Interval.php create mode 100644 vendor/symfony/translation/LICENSE create mode 100644 vendor/symfony/translation/Loader/ArrayLoader.php create mode 100644 vendor/symfony/translation/Loader/CsvFileLoader.php create mode 100644 vendor/symfony/translation/Loader/IcuDatFileLoader.php create mode 100644 vendor/symfony/translation/Loader/IcuResFileLoader.php create mode 100644 vendor/symfony/translation/Loader/IniFileLoader.php create mode 100644 vendor/symfony/translation/Loader/JsonFileLoader.php create mode 100644 vendor/symfony/translation/Loader/LoaderInterface.php create mode 100644 vendor/symfony/translation/Loader/MoFileLoader.php create mode 100644 vendor/symfony/translation/Loader/PhpFileLoader.php create mode 100644 vendor/symfony/translation/Loader/PoFileLoader.php create mode 100644 vendor/symfony/translation/Loader/QtFileLoader.php create mode 100644 vendor/symfony/translation/Loader/XliffFileLoader.php create mode 100644 vendor/symfony/translation/Loader/YamlFileLoader.php create mode 100644 vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd create mode 100644 vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd create mode 100644 vendor/symfony/translation/LoggingTranslator.php create mode 100644 vendor/symfony/translation/MessageCatalogue.php create mode 100644 vendor/symfony/translation/MessageCatalogueInterface.php create mode 100644 vendor/symfony/translation/MessageSelector.php create mode 100644 vendor/symfony/translation/MetadataAwareInterface.php create mode 100644 vendor/symfony/translation/PluralizationRules.php create mode 100644 vendor/symfony/translation/README.md create mode 100644 vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php create mode 100644 vendor/symfony/translation/Tests/Catalogue/DiffOperationTest.php create mode 100644 vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php create mode 100644 vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php create mode 100644 vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/CsvFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/FileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/IcuResFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/IniFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/MoFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/PhpFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/Dumper/YamlFileDumperTest.php create mode 100644 vendor/symfony/translation/Tests/IdentityTranslatorTest.php create mode 100644 vendor/symfony/translation/Tests/IntervalTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/CsvFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/IcuDatFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/IcuResFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/IniFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php create mode 100644 vendor/symfony/translation/Tests/Loader/MoFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/PhpFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/PoFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/Loader/YamlFileLoaderTest.php create mode 100644 vendor/symfony/translation/Tests/LoggingTranslatorTest.php create mode 100644 vendor/symfony/translation/Tests/MessageCatalogueTest.php create mode 100644 vendor/symfony/translation/Tests/MessageSelectorTest.php create mode 100644 vendor/symfony/translation/Tests/PluralizationRulesTest.php create mode 100644 vendor/symfony/translation/Tests/TranslatorCacheTest.php create mode 100644 vendor/symfony/translation/Tests/TranslatorTest.php create mode 100644 vendor/symfony/translation/Tests/fixtures/empty-translation.mo create mode 100644 vendor/symfony/translation/Tests/fixtures/empty-translation.po create mode 100644 vendor/symfony/translation/Tests/fixtures/empty.csv create mode 100644 vendor/symfony/translation/Tests/fixtures/empty.ini create mode 100644 vendor/symfony/translation/Tests/fixtures/empty.json create mode 100644 vendor/symfony/translation/Tests/fixtures/empty.mo create mode 100644 vendor/symfony/translation/Tests/fixtures/empty.po create mode 100644 vendor/symfony/translation/Tests/fixtures/empty.xlf create mode 100644 vendor/symfony/translation/Tests/fixtures/empty.yml create mode 100644 vendor/symfony/translation/Tests/fixtures/encoding.xlf create mode 100644 vendor/symfony/translation/Tests/fixtures/escaped-id-plurals.po create mode 100644 vendor/symfony/translation/Tests/fixtures/escaped-id.po create mode 100644 vendor/symfony/translation/Tests/fixtures/invalid-xml-resources.xlf create mode 100644 vendor/symfony/translation/Tests/fixtures/malformed.json create mode 100644 vendor/symfony/translation/Tests/fixtures/non-valid.xlf create mode 100644 vendor/symfony/translation/Tests/fixtures/non-valid.yml create mode 100644 vendor/symfony/translation/Tests/fixtures/plurals.mo create mode 100644 vendor/symfony/translation/Tests/fixtures/plurals.po create mode 100644 vendor/symfony/translation/Tests/fixtures/resname.xlf create mode 100644 vendor/symfony/translation/Tests/fixtures/resourcebundle/corrupted/resources.dat create mode 100644 vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.res create mode 100644 vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.txt create mode 100644 vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.res create mode 100644 vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.txt create mode 100644 vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/packagelist.txt create mode 100644 vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/resources.dat create mode 100644 vendor/symfony/translation/Tests/fixtures/resourcebundle/res/en.res create mode 100644 vendor/symfony/translation/Tests/fixtures/resources-clean.xlf create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.csv create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.ini create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.json create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.mo create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.php create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.po create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.ts create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.xlf create mode 100644 vendor/symfony/translation/Tests/fixtures/resources.yml create mode 100644 vendor/symfony/translation/Tests/fixtures/valid.csv create mode 100644 vendor/symfony/translation/Tests/fixtures/withdoctype.xlf create mode 100644 vendor/symfony/translation/Tests/fixtures/withnote.xlf create mode 100644 vendor/symfony/translation/Translator.php create mode 100644 vendor/symfony/translation/TranslatorBagInterface.php create mode 100644 vendor/symfony/translation/TranslatorInterface.php create mode 100644 vendor/symfony/translation/Writer/TranslationWriter.php create mode 100644 vendor/symfony/translation/composer.json create mode 100644 vendor/symfony/translation/phpunit.xml.dist create mode 100644 vendor/symfony/var-dumper/.gitignore create mode 100644 vendor/symfony/var-dumper/CHANGELOG.md create mode 100644 vendor/symfony/var-dumper/Caster/AmqpCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/Caster.php create mode 100644 vendor/symfony/var-dumper/Caster/ConstStub.php create mode 100644 vendor/symfony/var-dumper/Caster/CutStub.php create mode 100644 vendor/symfony/var-dumper/Caster/DOMCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/DoctrineCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/ExceptionCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/MongoCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/PdoCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/ReflectionCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/ResourceCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/SplCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/StubCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/XmlResourceCaster.php create mode 100644 vendor/symfony/var-dumper/Cloner/AbstractCloner.php create mode 100644 vendor/symfony/var-dumper/Cloner/ClonerInterface.php create mode 100644 vendor/symfony/var-dumper/Cloner/Cursor.php create mode 100644 vendor/symfony/var-dumper/Cloner/Data.php create mode 100644 vendor/symfony/var-dumper/Cloner/DumperInterface.php create mode 100644 vendor/symfony/var-dumper/Cloner/Stub.php create mode 100644 vendor/symfony/var-dumper/Cloner/VarCloner.php create mode 100644 vendor/symfony/var-dumper/Dumper/AbstractDumper.php create mode 100644 vendor/symfony/var-dumper/Dumper/CliDumper.php create mode 100644 vendor/symfony/var-dumper/Dumper/DataDumperInterface.php create mode 100644 vendor/symfony/var-dumper/Dumper/HtmlDumper.php create mode 100644 vendor/symfony/var-dumper/Exception/ThrowingCasterException.php create mode 100644 vendor/symfony/var-dumper/LICENSE create mode 100644 vendor/symfony/var-dumper/README.md create mode 100644 vendor/symfony/var-dumper/Resources/functions/dump.php create mode 100644 vendor/symfony/var-dumper/Test/VarDumperTestCase.php create mode 100644 vendor/symfony/var-dumper/Test/VarDumperTestTrait.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/CasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/PdoCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/CliDumperTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/dumb-var.php create mode 100644 vendor/symfony/var-dumper/Tests/HtmlDumperTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Test/VarDumpTestTraitRequire54.php create mode 100644 vendor/symfony/var-dumper/Tests/Test/VarDumpTestTraitTest.php create mode 100644 vendor/symfony/var-dumper/Tests/VarClonerTest.php create mode 100644 vendor/symfony/var-dumper/VarDumper.php create mode 100644 vendor/symfony/var-dumper/composer.json create mode 100644 vendor/symfony/var-dumper/phpunit.xml.dist create mode 100644 vendor/symfony/yaml/.gitignore create mode 100644 vendor/symfony/yaml/CHANGELOG.md create mode 100644 vendor/symfony/yaml/Dumper.php create mode 100644 vendor/symfony/yaml/Escaper.php create mode 100644 vendor/symfony/yaml/Exception/DumpException.php create mode 100644 vendor/symfony/yaml/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/yaml/Exception/ParseException.php create mode 100644 vendor/symfony/yaml/Exception/RuntimeException.php create mode 100644 vendor/symfony/yaml/Inline.php create mode 100644 vendor/symfony/yaml/LICENSE create mode 100644 vendor/symfony/yaml/Parser.php create mode 100644 vendor/symfony/yaml/README.md create mode 100644 vendor/symfony/yaml/Tests/DumperTest.php create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/index.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/sfComments.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/sfTests.yml create mode 100644 vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml create mode 100644 vendor/symfony/yaml/Tests/InlineTest.php create mode 100644 vendor/symfony/yaml/Tests/ParseExceptionTest.php create mode 100644 vendor/symfony/yaml/Tests/ParserTest.php create mode 100644 vendor/symfony/yaml/Tests/YamlTest.php create mode 100644 vendor/symfony/yaml/Unescaper.php create mode 100644 vendor/symfony/yaml/Yaml.php create mode 100644 vendor/symfony/yaml/composer.json create mode 100644 vendor/symfony/yaml/phpunit.xml.dist create mode 100644 vendor/twig/twig/.editorconfig create mode 100644 vendor/twig/twig/.gitignore create mode 100644 vendor/twig/twig/.travis.yml create mode 100644 vendor/twig/twig/CHANGELOG create mode 100644 vendor/twig/twig/LICENSE create mode 100644 vendor/twig/twig/README.rst create mode 100644 vendor/twig/twig/composer.json create mode 100644 vendor/twig/twig/doc/advanced.rst create mode 100644 vendor/twig/twig/doc/advanced_legacy.rst create mode 100644 vendor/twig/twig/doc/api.rst create mode 100644 vendor/twig/twig/doc/coding_standards.rst create mode 100644 vendor/twig/twig/doc/deprecated.rst create mode 100644 vendor/twig/twig/doc/filters/abs.rst create mode 100644 vendor/twig/twig/doc/filters/batch.rst create mode 100644 vendor/twig/twig/doc/filters/capitalize.rst create mode 100644 vendor/twig/twig/doc/filters/convert_encoding.rst create mode 100644 vendor/twig/twig/doc/filters/date.rst create mode 100644 vendor/twig/twig/doc/filters/date_modify.rst create mode 100644 vendor/twig/twig/doc/filters/default.rst create mode 100644 vendor/twig/twig/doc/filters/escape.rst create mode 100644 vendor/twig/twig/doc/filters/first.rst create mode 100644 vendor/twig/twig/doc/filters/format.rst create mode 100644 vendor/twig/twig/doc/filters/index.rst create mode 100644 vendor/twig/twig/doc/filters/join.rst create mode 100644 vendor/twig/twig/doc/filters/json_encode.rst create mode 100644 vendor/twig/twig/doc/filters/keys.rst create mode 100644 vendor/twig/twig/doc/filters/last.rst create mode 100644 vendor/twig/twig/doc/filters/length.rst create mode 100644 vendor/twig/twig/doc/filters/lower.rst create mode 100644 vendor/twig/twig/doc/filters/merge.rst create mode 100644 vendor/twig/twig/doc/filters/nl2br.rst create mode 100644 vendor/twig/twig/doc/filters/number_format.rst create mode 100644 vendor/twig/twig/doc/filters/raw.rst create mode 100644 vendor/twig/twig/doc/filters/replace.rst create mode 100644 vendor/twig/twig/doc/filters/reverse.rst create mode 100644 vendor/twig/twig/doc/filters/round.rst create mode 100644 vendor/twig/twig/doc/filters/slice.rst create mode 100644 vendor/twig/twig/doc/filters/sort.rst create mode 100644 vendor/twig/twig/doc/filters/split.rst create mode 100644 vendor/twig/twig/doc/filters/striptags.rst create mode 100644 vendor/twig/twig/doc/filters/title.rst create mode 100644 vendor/twig/twig/doc/filters/trim.rst create mode 100644 vendor/twig/twig/doc/filters/upper.rst create mode 100644 vendor/twig/twig/doc/filters/url_encode.rst create mode 100644 vendor/twig/twig/doc/functions/attribute.rst create mode 100644 vendor/twig/twig/doc/functions/block.rst create mode 100644 vendor/twig/twig/doc/functions/constant.rst create mode 100644 vendor/twig/twig/doc/functions/cycle.rst create mode 100644 vendor/twig/twig/doc/functions/date.rst create mode 100644 vendor/twig/twig/doc/functions/dump.rst create mode 100644 vendor/twig/twig/doc/functions/include.rst create mode 100644 vendor/twig/twig/doc/functions/index.rst create mode 100644 vendor/twig/twig/doc/functions/max.rst create mode 100644 vendor/twig/twig/doc/functions/min.rst create mode 100644 vendor/twig/twig/doc/functions/parent.rst create mode 100644 vendor/twig/twig/doc/functions/random.rst create mode 100644 vendor/twig/twig/doc/functions/range.rst create mode 100644 vendor/twig/twig/doc/functions/source.rst create mode 100644 vendor/twig/twig/doc/functions/template_from_string.rst create mode 100644 vendor/twig/twig/doc/index.rst create mode 100644 vendor/twig/twig/doc/installation.rst create mode 100644 vendor/twig/twig/doc/internals.rst create mode 100644 vendor/twig/twig/doc/intro.rst create mode 100644 vendor/twig/twig/doc/recipes.rst create mode 100644 vendor/twig/twig/doc/tags/autoescape.rst create mode 100644 vendor/twig/twig/doc/tags/block.rst create mode 100644 vendor/twig/twig/doc/tags/do.rst create mode 100644 vendor/twig/twig/doc/tags/embed.rst create mode 100644 vendor/twig/twig/doc/tags/extends.rst create mode 100644 vendor/twig/twig/doc/tags/filter.rst create mode 100644 vendor/twig/twig/doc/tags/flush.rst create mode 100644 vendor/twig/twig/doc/tags/for.rst create mode 100644 vendor/twig/twig/doc/tags/from.rst create mode 100644 vendor/twig/twig/doc/tags/if.rst create mode 100644 vendor/twig/twig/doc/tags/import.rst create mode 100644 vendor/twig/twig/doc/tags/include.rst create mode 100644 vendor/twig/twig/doc/tags/index.rst create mode 100644 vendor/twig/twig/doc/tags/macro.rst create mode 100644 vendor/twig/twig/doc/tags/sandbox.rst create mode 100644 vendor/twig/twig/doc/tags/set.rst create mode 100644 vendor/twig/twig/doc/tags/spaceless.rst create mode 100644 vendor/twig/twig/doc/tags/use.rst create mode 100644 vendor/twig/twig/doc/tags/verbatim.rst create mode 100644 vendor/twig/twig/doc/templates.rst create mode 100644 vendor/twig/twig/doc/tests/constant.rst create mode 100644 vendor/twig/twig/doc/tests/defined.rst create mode 100644 vendor/twig/twig/doc/tests/divisibleby.rst create mode 100644 vendor/twig/twig/doc/tests/empty.rst create mode 100644 vendor/twig/twig/doc/tests/even.rst create mode 100644 vendor/twig/twig/doc/tests/index.rst create mode 100644 vendor/twig/twig/doc/tests/iterable.rst create mode 100644 vendor/twig/twig/doc/tests/null.rst create mode 100644 vendor/twig/twig/doc/tests/odd.rst create mode 100644 vendor/twig/twig/doc/tests/sameas.rst create mode 100644 vendor/twig/twig/ext/twig/.gitignore create mode 100644 vendor/twig/twig/ext/twig/config.m4 create mode 100644 vendor/twig/twig/ext/twig/config.w32 create mode 100644 vendor/twig/twig/ext/twig/php_twig.h create mode 100644 vendor/twig/twig/ext/twig/twig.c create mode 100644 vendor/twig/twig/lib/Twig/Autoloader.php create mode 100644 vendor/twig/twig/lib/Twig/BaseNodeVisitor.php create mode 100644 vendor/twig/twig/lib/Twig/Cache/Filesystem.php create mode 100644 vendor/twig/twig/lib/Twig/Cache/Null.php create mode 100644 vendor/twig/twig/lib/Twig/CacheInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Compiler.php create mode 100644 vendor/twig/twig/lib/Twig/CompilerInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Environment.php create mode 100644 vendor/twig/twig/lib/Twig/Error.php create mode 100644 vendor/twig/twig/lib/Twig/Error/Loader.php create mode 100644 vendor/twig/twig/lib/Twig/Error/Runtime.php create mode 100644 vendor/twig/twig/lib/Twig/Error/Syntax.php create mode 100644 vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php create mode 100644 vendor/twig/twig/lib/Twig/ExpressionParser.php create mode 100644 vendor/twig/twig/lib/Twig/Extension.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Core.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Debug.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Escaper.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Optimizer.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Profiler.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Sandbox.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/Staging.php create mode 100644 vendor/twig/twig/lib/Twig/Extension/StringLoader.php create mode 100644 vendor/twig/twig/lib/Twig/ExtensionInterface.php create mode 100644 vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php create mode 100644 vendor/twig/twig/lib/Twig/Filter.php create mode 100644 vendor/twig/twig/lib/Twig/Filter/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Filter/Method.php create mode 100644 vendor/twig/twig/lib/Twig/Filter/Node.php create mode 100644 vendor/twig/twig/lib/Twig/FilterCallableInterface.php create mode 100644 vendor/twig/twig/lib/Twig/FilterInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Function/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Function/Method.php create mode 100644 vendor/twig/twig/lib/Twig/Function/Node.php create mode 100644 vendor/twig/twig/lib/Twig/FunctionCallableInterface.php create mode 100644 vendor/twig/twig/lib/Twig/FunctionInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Lexer.php create mode 100644 vendor/twig/twig/lib/Twig/LexerInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Loader/Array.php create mode 100644 vendor/twig/twig/lib/Twig/Loader/Chain.php create mode 100644 vendor/twig/twig/lib/Twig/Loader/Filesystem.php create mode 100644 vendor/twig/twig/lib/Twig/Loader/String.php create mode 100644 vendor/twig/twig/lib/Twig/LoaderInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Markup.php create mode 100644 vendor/twig/twig/lib/Twig/Node.php create mode 100644 vendor/twig/twig/lib/Twig/Node/AutoEscape.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Block.php create mode 100644 vendor/twig/twig/lib/Twig/Node/BlockReference.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Body.php create mode 100644 vendor/twig/twig/lib/Twig/Node/CheckSecurity.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Do.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Embed.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Array.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Call.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Constant.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Filter.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Name.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Parent.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/TempName.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Unary.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Flush.php create mode 100644 vendor/twig/twig/lib/Twig/Node/For.php create mode 100644 vendor/twig/twig/lib/Twig/Node/ForLoop.php create mode 100644 vendor/twig/twig/lib/Twig/Node/If.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Import.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Include.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Macro.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Module.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Print.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Sandbox.php create mode 100644 vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Set.php create mode 100644 vendor/twig/twig/lib/Twig/Node/SetTemp.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Spaceless.php create mode 100644 vendor/twig/twig/lib/Twig/Node/Text.php create mode 100644 vendor/twig/twig/lib/Twig/NodeInterface.php create mode 100644 vendor/twig/twig/lib/Twig/NodeOutputInterface.php create mode 100644 vendor/twig/twig/lib/Twig/NodeTraverser.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php create mode 100644 vendor/twig/twig/lib/Twig/NodeVisitorInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Parser.php create mode 100644 vendor/twig/twig/lib/Twig/ParserInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php create mode 100644 vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php create mode 100644 vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php create mode 100644 vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php create mode 100644 vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php create mode 100644 vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php create mode 100644 vendor/twig/twig/lib/Twig/Profiler/Profile.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php create mode 100644 vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php create mode 100644 vendor/twig/twig/lib/Twig/SimpleFilter.php create mode 100644 vendor/twig/twig/lib/Twig/SimpleFunction.php create mode 100644 vendor/twig/twig/lib/Twig/SimpleTest.php create mode 100644 vendor/twig/twig/lib/Twig/Template.php create mode 100644 vendor/twig/twig/lib/Twig/TemplateInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Test.php create mode 100644 vendor/twig/twig/lib/Twig/Test/Function.php create mode 100644 vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php create mode 100644 vendor/twig/twig/lib/Twig/Test/Method.php create mode 100644 vendor/twig/twig/lib/Twig/Test/Node.php create mode 100644 vendor/twig/twig/lib/Twig/Test/NodeTestCase.php create mode 100644 vendor/twig/twig/lib/Twig/TestCallableInterface.php create mode 100644 vendor/twig/twig/lib/Twig/TestInterface.php create mode 100644 vendor/twig/twig/lib/Twig/Token.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Block.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Do.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Embed.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Extends.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Filter.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Flush.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/For.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/From.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/If.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Import.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Include.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Macro.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Set.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParser/Use.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParserBroker.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php create mode 100644 vendor/twig/twig/lib/Twig/TokenParserInterface.php create mode 100644 vendor/twig/twig/lib/Twig/TokenStream.php create mode 100644 vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php create mode 100644 vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php create mode 100644 vendor/twig/twig/phpunit.xml.dist create mode 100644 vendor/twig/twig/test/Twig/Tests/AutoloaderTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/CompilerTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/ErrorTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/FileCachingTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/FileExtensionEscapingStrategyTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/filename.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/errors/base.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/errors/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable_again.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_undefined_variable.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_unknown_argument.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_tag_with_undefined_variable.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/syntax_error_in_reused_template.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_parent.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_template_in_child_template.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_trait.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/array.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/array_call.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/binary.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/bitwise.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/comparison.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/divisibleby.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/dotdot.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ends_with.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/grouping.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/literals.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/matches.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/method_call.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/negative_numbers.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/operators_as_variables.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/postfix.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/sameas.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/starts_with.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/strings.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_noelse.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_nothen.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/two_word_operators_as_variables.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary_macro_arguments.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary_precedence.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/abs.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_float.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_empty_fill.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_exact_elements.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_fill.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_keys.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_zero_elements.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/convert_encoding.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_immutable.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_interval.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_modify.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_namedargs.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/default.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/dynamic_filter.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_html_attr.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_non_supported_charset.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/first.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/force_escape.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/format.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/join.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/json_encode.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/last.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/length.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/length_utf8.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/merge.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/nl2br.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace_invalid_arg.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/reverse.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/round.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/slice.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/sort.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/special_chars.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/split.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/split_utf8.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/trim.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/urlencode.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/filters/urlencode_deprecated.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/attribute.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/constant.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/cycle.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date_namedargs.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dump.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dump_array.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dynamic_function.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/assignment.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/autoescaping.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/expression.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/ignore_missing.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing_nested.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling_ignore_missing.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/template_instance.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/templates_as_array.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_context.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_variables.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/max.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/min.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/range.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/source.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/special_chars.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/functions/template_from_string.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/macros/default_values.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/macros/nested_calls.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/macros/reserved_variables.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/macros/simple.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/macros/with_filters.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/regression/empty_token.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/regression/issue_1143.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/regression/multi_word_tests.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/regression/simple_xml_element.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/regression/strings_like_numbers.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/blocks.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/double_escaping.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/literal.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/nested.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/objects.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/raw.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.legacy.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters_arguments.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_pre_escape_filters.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_preserves_safety_filters.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/block_unique_name.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/special_chars.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/error_line.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/multiple.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/nested.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/with_extends.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/json_encode.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/multiple.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/nested.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/with_for_tag.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/with_if_tag.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/condition.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/context.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/else.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/inner_variables.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/keys.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/keys_and_values.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_context.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_context_local.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/nested_else.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/objects.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/objects_countable.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/recursive.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/values.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/from.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/if/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/if/expression.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/expression.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/ignore_missing.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/missing.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/missing_nested.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/only.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/template_instance.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/templates_as_array.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/with_variables.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/block_expr.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/block_expr2.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/conditional.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/dynamic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/empty.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array_with_empty_name.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array_with_null_name.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple_dynamic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_blocks.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_blocks_parent_only.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_inheritance.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_change.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_isolation.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_nested.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends_but_traits.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/template_instance.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/use.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/endmacro_name.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/external.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/from.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/from_with_reserved_name.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/global.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/import_with_reserved_nam.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/reserved_name.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/self_import.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/special_chars.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/super_globals.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/basic.legacy.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/mixed_usage_with_raw.legacy.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/whitespace_control.legacy.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid1.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid2.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/simple.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/capture-empty.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/capture.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/expression.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/spaceless/simple.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/special_chars.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/trim_block.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/aliases.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/deep.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/deep_empty.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance2.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/multiple.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/multiple_aliases.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block2.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block3.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/basic.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/whitespace_control.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/array.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/constant.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/empty.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/even.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/in.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/in_with_objects.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/iterable.test create mode 100644 vendor/twig/twig/test/Twig/Tests/Fixtures/tests/odd.test create mode 100644 vendor/twig/twig/test/Twig/Tests/IntegrationTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/LegacyFixtures/test.legacy.test create mode 100644 vendor/twig/twig/test/Twig/Tests/LegacyIntegrationTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/LexerTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/ArrayTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/ChainTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/FilesystemTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_empty_parent.html.twig create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_nonexistent_parent.html.twig create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_null_parent.html.twig create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_valid_parent.html.twig create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/parent.html.twig create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/spare_parent.html.twig create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_bis/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_final/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_ter/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_bis/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_final/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_ter/index.html create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/themes/theme1/blocks.html.twig create mode 100644 vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/themes/theme2/blocks.html.twig create mode 100644 vendor/twig/twig/test/Twig/Tests/NativeExtensionTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/AutoEscapeTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/BlockReferenceTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/BlockTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/DoTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/ArrayTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/AssignNameTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/AddTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/AndTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/ConcatTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/DivTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/FloorDivTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/ModTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/MulTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/OrTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/SubTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/CallTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/ConditionalTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/ConstantTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/FilterTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/FunctionTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/GetAttrTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/NameTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FilterInclude.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FunctionInclude.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/TestInclude.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/ParentTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/TestTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/NegTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/NotTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/PosTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/ForTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/IfTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/ImportTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/IncludeTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/PrintTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/SandboxTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/SandboxedPrintTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/SetTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/SpacelessTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Node/TextTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/ParserTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/AbstractTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/BlackfireTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/HtmlTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/TextTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/Profiler/ProfileTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/TemplateTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php create mode 100644 vendor/twig/twig/test/Twig/Tests/escapingTest.php create mode 100644 vendor/twig/twig/test/bootstrap.php create mode 100644 vendor/vlucas/phpdotenv/LICENSE.txt create mode 100644 vendor/vlucas/phpdotenv/README.md create mode 100644 vendor/vlucas/phpdotenv/composer.json create mode 100644 vendor/vlucas/phpdotenv/src/Dotenv.php diff --git a/.gitignore b/.gitignore index fadc7c1..06a7631 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -/vendor +#/vendor .env diff --git a/composer.json b/composer.json index c469e2e..3aec6b5 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { - "name": "laravel/lumen", - "description": "The Laravel Lumen Framework.", - "keywords": ["framework", "laravel", "lumen"], - "license": "MIT", + "name": "cydrobolt/polr", + "description": "The Polr URL Shortener.", + "keywords": ["url-shortener", "url", "cms"], + "license": "GPLv2+", "type": "project", "require": { "php": ">=5.5.9", diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000..71cff00 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0 class loader + * + * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + + private $classMapAuthoritative = false; + + 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; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + 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 + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-0 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $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) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + 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; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative) { + return false; + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if ($file === null && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if ($file === null) { + // Remember that this class does not exist. + return $this->classMap[$class] = false; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { + if (0 === strpos($class, $prefix)) { + foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $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; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 0000000..c8d57af --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) 2015 Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..c1a06ef --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,454 @@ + $baseDir . '/database/seeds/DatabaseSeeder.php', + 'ExampleTest' => $baseDir . '/tests/ExampleTest.php', + 'File_Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', + 'IlluminateQueueClosure' => $vendorDir . '/illuminate/queue/IlluminateQueueClosure.php', + 'Illuminate\\Foundation\\Composer' => $vendorDir . '/laravel/lumen-framework/src/Foundation/Composer.php', + 'Illuminate\\Foundation\\Support\\Providers\\EventServiceProvider' => $vendorDir . '/laravel/lumen-framework/src/Foundation/Support/Providers/EventServiceProvider.php', + 'Illuminate\\Foundation\\Testing\\DatabaseMigrations' => $vendorDir . '/laravel/lumen-framework/src/Foundation/Testing/DatabaseMigrations.php', + 'Illuminate\\Foundation\\Testing\\DatabaseTransactions' => $vendorDir . '/laravel/lumen-framework/src/Foundation/Testing/DatabaseTransactions.php', + 'Illuminate\\Foundation\\Testing\\WithoutMiddleware' => $vendorDir . '/laravel/lumen-framework/src/Foundation/Testing/WithoutMiddleware.php', + 'PHPUnit_Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit_Extensions_GroupTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php', + 'PHPUnit_Extensions_PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestCase.php', + 'PHPUnit_Extensions_PhptTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php', + 'PHPUnit_Extensions_RepeatedTest' => $vendorDir . '/phpunit/phpunit/src/Extensions/RepeatedTest.php', + 'PHPUnit_Extensions_TestDecorator' => $vendorDir . '/phpunit/phpunit/src/Extensions/TestDecorator.php', + 'PHPUnit_Extensions_TicketListener' => $vendorDir . '/phpunit/phpunit/src/Extensions/TicketListener.php', + 'PHPUnit_Framework_Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit_Framework_AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit_Framework_BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit_Framework_CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit_Framework_Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint.php', + 'PHPUnit_Framework_Constraint_And' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/And.php', + 'PHPUnit_Framework_Constraint_ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit_Framework_Constraint_ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit_Framework_Constraint_Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit_Framework_Constraint_Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit_Framework_Constraint_ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit_Framework_Constraint_Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit_Framework_Constraint_Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit_Framework_Constraint_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit_Framework_Constraint_ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit_Framework_Constraint_ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php', + 'PHPUnit_Framework_Constraint_FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit_Framework_Constraint_GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit_Framework_Constraint_IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit_Framework_Constraint_IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit_Framework_Constraint_IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit_Framework_Constraint_IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit_Framework_Constraint_IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit_Framework_Constraint_IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit_Framework_Constraint_IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit_Framework_Constraint_IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit_Framework_Constraint_IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit_Framework_Constraint_IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit_Framework_Constraint_JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', + 'PHPUnit_Framework_Constraint_LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit_Framework_Constraint_Not' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Not.php', + 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit_Framework_Constraint_Or' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Or.php', + 'PHPUnit_Framework_Constraint_PCREMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php', + 'PHPUnit_Framework_Constraint_SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit_Framework_Constraint_StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit_Framework_Constraint_StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit_Framework_Constraint_StringMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php', + 'PHPUnit_Framework_Constraint_StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit_Framework_Constraint_TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit_Framework_Constraint_Xor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Xor.php', + 'PHPUnit_Framework_Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error.php', + 'PHPUnit_Framework_Error_Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit_Framework_Error_Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit_Framework_Error_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit_Framework_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit_Framework_ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit_Framework_ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit_Framework_IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit_Framework_IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit_Framework_IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit_Framework_InvalidCoversTargetError' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetError.php', + 'PHPUnit_Framework_InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit_Framework_MockObject_BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit_Framework_MockObject_Builder_Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Builder_Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Namespace' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php', + 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit_Framework_MockObject_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit_Framework_MockObject_Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php', + 'PHPUnit_Framework_MockObject_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php', + 'PHPUnit_Framework_MockObject_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Invocation_Object' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php', + 'PHPUnit_Framework_MockObject_Invocation_Static' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php', + 'PHPUnit_Framework_MockObject_Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php', + 'PHPUnit_Framework_MockObject_Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php', + 'PHPUnit_Framework_MockObject_Matcher_MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php', + 'PHPUnit_Framework_MockObject_Matcher_Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php', + 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php', + 'PHPUnit_Framework_MockObject_MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php', + 'PHPUnit_Framework_MockObject_RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit_Framework_MockObject_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php', + 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit_Framework_MockObject_Stub_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php', + 'PHPUnit_Framework_MockObject_Stub_Return' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit_Framework_MockObject_Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php', + 'PHPUnit_Framework_OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit_Framework_RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit_Framework_RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit_Framework_SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit_Framework_SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit_Framework_SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit_Framework_SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit_Framework_SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit_Framework_SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit_Framework_Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit_Framework_TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit_Framework_TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit_Framework_TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit_Framework_TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit_Framework_TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit_Framework_TestSuite_DataProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php', + 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit_Framework_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit_Runner_BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit_Runner_Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit_Runner_Filter_Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit_Runner_Filter_GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group.php', + 'PHPUnit_Runner_Filter_Group_Exclude' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php', + 'PHPUnit_Runner_Filter_Group_Include' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php', + 'PHPUnit_Runner_Filter_Test' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Test.php', + 'PHPUnit_Runner_StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit_Runner_TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit_Runner_Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit_TextUI_Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit_TextUI_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit_TextUI_TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit_Util_Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit_Util_Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit_Util_ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit_Util_Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit_Util_Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit_Util_Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit_Util_Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit_Util_GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit_Util_Log_JSON' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JSON.php', + 'PHPUnit_Util_Log_JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit_Util_Log_TAP' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TAP.php', + 'PHPUnit_Util_PHP' => $vendorDir . '/phpunit/phpunit/src/Util/PHP.php', + 'PHPUnit_Util_PHP_Default' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Default.php', + 'PHPUnit_Util_PHP_Windows' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Windows.php', + 'PHPUnit_Util_Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit_Util_Regex' => $vendorDir . '/phpunit/phpunit/src/Util/Regex.php', + 'PHPUnit_Util_String' => $vendorDir . '/phpunit/phpunit/src/Util/String.php', + 'PHPUnit_Util_Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit_Util_TestDox_NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit_Util_TestDox_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php', + 'PHPUnit_Util_TestDox_ResultPrinter_Text' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php', + 'PHPUnit_Util_TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Util/TestSuiteIterator.php', + 'PHPUnit_Util_Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit_Util_XML' => $vendorDir . '/phpunit/phpunit/src/Util/XML.php', + 'PHP_CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'PHP_CodeCoverage_Driver' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver.php', + 'PHP_CodeCoverage_Driver_HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php', + 'PHP_CodeCoverage_Driver_PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/PHPDBG.php', + 'PHP_CodeCoverage_Driver_Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php', + 'PHP_CodeCoverage_Exception' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception.php', + 'PHP_CodeCoverage_Exception_UnintentionallyCoveredCode' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCode.php', + 'PHP_CodeCoverage_Filter' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Filter.php', + 'PHP_CodeCoverage_Report_Clover' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php', + 'PHP_CodeCoverage_Report_Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php', + 'PHP_CodeCoverage_Report_Factory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php', + 'PHP_CodeCoverage_Report_HTML' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php', + 'PHP_CodeCoverage_Report_HTML_Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php', + 'PHP_CodeCoverage_Report_Node' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node.php', + 'PHP_CodeCoverage_Report_Node_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Directory.php', + 'PHP_CodeCoverage_Report_Node_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/File.php', + 'PHP_CodeCoverage_Report_Node_Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Iterator.php', + 'PHP_CodeCoverage_Report_PHP' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/PHP.php', + 'PHP_CodeCoverage_Report_Text' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Text.php', + 'PHP_CodeCoverage_Report_XML' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML.php', + 'PHP_CodeCoverage_Report_XML_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Directory.php', + 'PHP_CodeCoverage_Report_XML_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File.php', + 'PHP_CodeCoverage_Report_XML_File_Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Coverage.php', + 'PHP_CodeCoverage_Report_XML_File_Method' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Method.php', + 'PHP_CodeCoverage_Report_XML_File_Report' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Report.php', + 'PHP_CodeCoverage_Report_XML_File_Unit' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Unit.php', + 'PHP_CodeCoverage_Report_XML_Node' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Node.php', + 'PHP_CodeCoverage_Report_XML_Project' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Project.php', + 'PHP_CodeCoverage_Report_XML_Tests' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Tests.php', + 'PHP_CodeCoverage_Report_XML_Totals' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Totals.php', + 'PHP_CodeCoverage_Util' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Util.php', + 'PHP_CodeCoverage_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Util/InvalidArgumentHelper.php', + 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => $vendorDir . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php', + 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', + 'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Resources/stubs/SessionHandlerInterface.php', + 'TestCase' => $baseDir . '/tests/TestCase.php', + 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 0000000..bf84a18 --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,15 @@ + array($vendorDir . '/phpdocumentor/reflection-docblock/src'), + 'Twig_' => array($vendorDir . '/twig/twig/lib'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log'), + 'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'), + 'Dotenv' => array($vendorDir . '/vlucas/phpdotenv/src'), + 'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib'), + 'Cron' => array($vendorDir . '/mtdowling/cron-expression/src'), + 'Carbon' => array($vendorDir . '/nesbot/carbon/src'), +); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php new file mode 100644 index 0000000..747ba43 --- /dev/null +++ b/vendor/composer/autoload_psr4.php @@ -0,0 +1,53 @@ + array($vendorDir . '/rcrowe/twigbridge/tests'), + 'TwigBridge\\' => array($vendorDir . '/rcrowe/twigbridge/src'), + 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), + 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), + 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'), + 'Symfony\\Component\\Security\\Core\\' => array($vendorDir . '/symfony/security-core'), + 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'), + 'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'), + 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'), + 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'), + 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'), + 'Symfony\\Component\\DomCrawler\\' => array($vendorDir . '/symfony/dom-crawler'), + 'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'), + 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'), + 'Stringy\\' => array($vendorDir . '/danielstjules/stringy/src'), + 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), + 'Laravel\\Lumen\\' => array($vendorDir . '/laravel/lumen-framework/src'), + 'Illuminate\\View\\' => array($vendorDir . '/illuminate/view'), + 'Illuminate\\Validation\\' => array($vendorDir . '/illuminate/validation'), + 'Illuminate\\Translation\\' => array($vendorDir . '/illuminate/translation'), + 'Illuminate\\Support\\' => array($vendorDir . '/illuminate/support'), + 'Illuminate\\Session\\' => array($vendorDir . '/illuminate/session'), + 'Illuminate\\Queue\\' => array($vendorDir . '/illuminate/queue'), + 'Illuminate\\Pipeline\\' => array($vendorDir . '/illuminate/pipeline'), + 'Illuminate\\Pagination\\' => array($vendorDir . '/illuminate/pagination'), + 'Illuminate\\Http\\' => array($vendorDir . '/illuminate/http'), + 'Illuminate\\Hashing\\' => array($vendorDir . '/illuminate/hashing'), + 'Illuminate\\Filesystem\\' => array($vendorDir . '/illuminate/filesystem'), + 'Illuminate\\Events\\' => array($vendorDir . '/illuminate/events'), + 'Illuminate\\Encryption\\' => array($vendorDir . '/illuminate/encryption'), + 'Illuminate\\Database\\' => array($vendorDir . '/illuminate/database'), + 'Illuminate\\Cookie\\' => array($vendorDir . '/illuminate/cookie'), + 'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'), + 'Illuminate\\Container\\' => array($vendorDir . '/illuminate/container'), + 'Illuminate\\Console\\' => array($vendorDir . '/illuminate/console'), + 'Illuminate\\Config\\' => array($vendorDir . '/illuminate/config'), + 'Illuminate\\Cache\\' => array($vendorDir . '/illuminate/cache'), + 'Illuminate\\Bus\\' => array($vendorDir . '/illuminate/bus'), + 'Illuminate\\Broadcasting\\' => array($vendorDir . '/illuminate/broadcasting'), + 'Illuminate\\Auth\\' => array($vendorDir . '/illuminate/auth'), + 'FastRoute\\' => array($vendorDir . '/nikic/fast-route/src'), + 'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'), + 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), + 'App\\' => array($baseDir . '/app'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..e82b030 --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,55 @@ + $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); + + $includeFiles = require __DIR__ . '/autoload_files.php'; + foreach ($includeFiles as $file) { + composerRequire1022d009db9f708df68c1991f93b734b($file); + } + + return $loader; + } +} + +function composerRequire1022d009db9f708df68c1991f93b734b($file) +{ + require $file; +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..41e344b --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,3530 @@ +[ + { + "name": "symfony/var-dumper", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "eb033050050916b6bfa51be71009ef67b16046c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/eb033050050916b6bfa51be71009ef67b16046c9", + "reference": "eb033050050916b6bfa51be71009ef67b16046c9", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "suggest": { + "ext-symfony_debug": "" + }, + "time": "2015-10-25 17:17:38", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ] + }, + { + "name": "symfony/security-core", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-core.git", + "reference": "677af9aa5a497f768bf23ba84a466be060dc7509" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-core/zipball/677af9aa5a497f768bf23ba84a466be060dc7509", + "reference": "677af9aa5a497f768bf23ba84a466be060dc7509", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "ircmaxell/password-compat": "1.0.*", + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/expression-language": "~2.6", + "symfony/http-foundation": "~2.4", + "symfony/translation": "~2.0,>=2.0.5", + "symfony/validator": "~2.5,>=2.5.5" + }, + "suggest": { + "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5", + "symfony/event-dispatcher": "", + "symfony/expression-language": "For using the expression voter", + "symfony/http-foundation": "", + "symfony/validator": "For using the user password constraint" + }, + "time": "2015-10-11 09:39:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Core\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - Core Library", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/http-foundation", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "7598eea151ae3d4134df1f9957364b17809eea75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/7598eea151ae3d4134df1f9957364b17809eea75", + "reference": "7598eea151ae3d4134df1f9957364b17809eea75", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/expression-language": "~2.4" + }, + "time": "2015-10-23 14:47:27", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com" + }, + { + "name": "psr/log", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "time": "2012-12-21 11:40:51", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "symfony/debug", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "fb9e6887db716939f41af0ba8ef38a1582eb501b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/fb9e6887db716939f41af0ba8ef38a1582eb501b", + "reference": "fb9e6887db716939f41af0ba8ef38a1582eb501b", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/class-loader": "~2.2", + "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2" + }, + "time": "2015-10-11 09:39:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87a5db5ea887763fa3a31a5471b512ff1596d9b8", + "reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.6", + "symfony/expression-language": "~2.6", + "symfony/stopwatch": "~2.3" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "time": "2015-10-11 09:39:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/http-kernel", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "4260f2273a446a6715063dc9ca89fd0c475c2f77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4260f2273a446a6715063dc9ca89fd0c475c2f77", + "reference": "4260f2273a446a6715063dc9ca89fd0c475c2f77", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "psr/log": "~1.0", + "symfony/debug": "~2.6,>=2.6.2", + "symfony/event-dispatcher": "~2.6,>=2.6.7", + "symfony/http-foundation": "~2.5,>=2.5.4" + }, + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "symfony/browser-kit": "~2.3", + "symfony/class-loader": "~2.1", + "symfony/config": "~2.7", + "symfony/console": "~2.3", + "symfony/css-selector": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.2", + "symfony/dom-crawler": "~2.0,>=2.0.5", + "symfony/expression-language": "~2.4", + "symfony/finder": "~2.0,>=2.0.5", + "symfony/process": "~2.0,>=2.0.5", + "symfony/routing": "~2.2", + "symfony/stopwatch": "~2.3", + "symfony/templating": "~2.2", + "symfony/translation": "~2.0,>=2.0.5", + "symfony/var-dumper": "~2.6" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/class-loader": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" + }, + "time": "2015-10-27 19:07:21", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/dom-crawler", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "5fef7d8b80d8f9992df99d8ee283f420484c9612" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/5fef7d8b80d8f9992df99d8ee283f420484c9612", + "reference": "5fef7d8b80d8f9992df99d8ee283f420484c9612", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/css-selector": "~2.3" + }, + "suggest": { + "symfony/css-selector": "" + }, + "time": "2015-10-11 09:39:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "https://symfony.com" + }, + { + "name": "paragonie/random_compat", + "version": "1.0.10", + "version_normalized": "1.0.10.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "2fa50aa2f17066fa74ba00d943e8cee1a98284af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/2fa50aa2f17066fa74ba00d943e8cee1a98284af", + "reference": "2fa50aa2f17066fa74ba00d943e8cee1a98284af", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2015-10-23 13:21:37", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ] + }, + { + "name": "nikic/fast-route", + "version": "v0.4.0", + "version_normalized": "0.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/FastRoute.git", + "reference": "f26a8f7788f25c0e3e9b1579d38d7ccab2755320" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/FastRoute/zipball/f26a8f7788f25c0e3e9b1579d38d7ccab2755320", + "reference": "f26a8f7788f25c0e3e9b1579d38d7ccab2755320", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "time": "2015-02-26 15:33:07", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "FastRoute\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } + ], + "description": "Fast request router for PHP", + "keywords": [ + "router", + "routing" + ] + }, + { + "name": "mtdowling/cron-expression", + "version": "v1.0.4", + "version_normalized": "1.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/mtdowling/cron-expression.git", + "reference": "fd92e883195e5dfa77720b1868cf084b08be4412" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/fd92e883195e5dfa77720b1868cf084b08be4412", + "reference": "fd92e883195e5dfa77720b1868cf084b08be4412", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "time": "2015-01-11 23:07:46", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Cron": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ] + }, + { + "name": "monolog/monolog", + "version": "1.17.2", + "version_normalized": "1.17.2.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bee7f0dc9c3e0b69a6039697533dca1e845c8c24", + "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "raven/raven": "^0.13", + "ruflin/elastica": ">=0.90 <3.0", + "swiftmailer/swiftmailer": "~5.3", + "videlalvaro/php-amqplib": "~2.4" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "raven/raven": "Allow sending log messages to a Sentry server", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib" + }, + "time": "2015-10-14 12:51:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.16.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ] + }, + { + "name": "danielstjules/stringy", + "version": "1.10.0", + "version_normalized": "1.10.0.0", + "source": { + "type": "git", + "url": "https://github.com/danielstjules/Stringy.git", + "reference": "4749c205db47ee5b32e8d1adf6d9aff8db6caf3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danielstjules/Stringy/zipball/4749c205db47ee5b32e8d1adf6d9aff8db6caf3b", + "reference": "4749c205db47ee5b32e8d1adf6d9aff8db6caf3b", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "time": "2015-07-23 00:54:12", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Stringy\\": "src/" + }, + "files": [ + "src/Create.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel St. Jules", + "email": "danielst.jules@gmail.com", + "homepage": "http://www.danielstjules.com" + } + ], + "description": "A string manipulation library with multibyte support", + "homepage": "https://github.com/danielstjules/Stringy", + "keywords": [ + "UTF", + "helpers", + "manipulation", + "methods", + "multibyte", + "string", + "utf-8", + "utility", + "utils" + ] + }, + { + "name": "doctrine/inflector", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", + "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "time": "2014-12-20 21:24:13", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ] + }, + { + "name": "illuminate/contracts", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/contracts.git", + "reference": "e2b71fdbeeb3438748dca5f497e205888788a883" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/e2b71fdbeeb3438748dca5f497e205888788a883", + "reference": "e2b71fdbeeb3438748dca5f497e205888788a883", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "time": "2015-09-24 11:16:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Contracts\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Contracts package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/support", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/support.git", + "reference": "d52a832d3f4b025b82f954cbdef8ee24f6a77e77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/support/zipball/d52a832d3f4b025b82f954cbdef8ee24f6a77e77", + "reference": "d52a832d3f4b025b82f954cbdef8ee24f6a77e77", + "shasum": "" + }, + "require": { + "danielstjules/stringy": "~1.8", + "doctrine/inflector": "~1.0", + "ext-mbstring": "*", + "illuminate/contracts": "5.1.*", + "php": ">=5.5.9" + }, + "suggest": { + "jeremeamia/superclosure": "Required to be able to serialize closures (~2.0).", + "paragonie/random_compat": "Provides a compatible interface like PHP7's random_bytes() in PHP 5 projects (^1.0.6).", + "symfony/var-dumper": "Required to use the dd function (2.7.*)." + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + }, + "files": [ + "helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Support package.", + "homepage": "http://laravel.com" + }, + { + "name": "symfony/finder", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d", + "reference": "2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "time": "2015-10-11 09:39:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com" + }, + { + "name": "illuminate/filesystem", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/filesystem.git", + "reference": "d2df6ede91e6af495674f2def38170330319819f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/filesystem/zipball/d2df6ede91e6af495674f2def38170330319819f", + "reference": "d2df6ede91e6af495674f2def38170330319819f", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9", + "symfony/finder": "2.7.*" + }, + "suggest": { + "league/flysystem": "Required to use the Flysystem local and FTP drivers (~1.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", + "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0)." + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Filesystem\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Filesystem package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/container", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/container.git", + "reference": "bb2cd1d9c6cb7c4ce80b8d89f899e086f5a4f65b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/container/zipball/bb2cd1d9c6cb7c4ce80b8d89f899e086f5a4f65b", + "reference": "bb2cd1d9c6cb7c4ce80b8d89f899e086f5a4f65b", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "php": ">=5.5.9" + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Container\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Container package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/events", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/events.git", + "reference": "fdb64e091b635bf1525c157f1cfdd19cbca508c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/events/zipball/fdb64e091b635bf1525c157f1cfdd19cbca508c9", + "reference": "fdb64e091b635bf1525c157f1cfdd19cbca508c9", + "shasum": "" + }, + "require": { + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "time": "2015-09-23 13:19:23", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Events\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Events package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/view", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/view.git", + "reference": "50e3027b470c8d92d433b6de0b1f227c232eda46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/view/zipball/50e3027b470c8d92d433b6de0b1f227c232eda46", + "reference": "50e3027b470c8d92d433b6de0b1f227c232eda46", + "shasum": "" + }, + "require": { + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/events": "5.1.*", + "illuminate/filesystem": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\View\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate View package.", + "homepage": "http://laravel.com" + }, + { + "name": "symfony/translation", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "6ccd9289ec1c71d01a49d83480de3b5293ce30c8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/6ccd9289ec1c71d01a49d83480de3b5293ce30c8", + "reference": "6ccd9289ec1c71d01a49d83480de3b5293ce30c8", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.7", + "symfony/intl": "~2.4", + "symfony/yaml": "~2.2" + }, + "suggest": { + "psr/log": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "time": "2015-10-27 15:38:06", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com" + }, + { + "name": "illuminate/validation", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/validation.git", + "reference": "66151dde43b34fc2800f8201a73f61f889c77084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/validation/zipball/66151dde43b34fc2800f8201a73f61f889c77084", + "reference": "66151dde43b34fc2800f8201a73f61f889c77084", + "shasum": "" + }, + "require": { + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9", + "symfony/http-foundation": "2.7.*", + "symfony/translation": "2.7.*" + }, + "suggest": { + "illuminate/database": "Required to use the database presence verifier (5.1.*)." + }, + "time": "2015-10-23 08:21:26", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Validation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Validation package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/translation", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/translation.git", + "reference": "81bf81fcb3ccc18e7aeabaefdbb7306581439fcc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/translation/zipball/81bf81fcb3ccc18e7aeabaefdbb7306581439fcc", + "reference": "81bf81fcb3ccc18e7aeabaefdbb7306581439fcc", + "shasum": "" + }, + "require": { + "illuminate/filesystem": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9", + "symfony/translation": "2.7.*" + }, + "time": "2015-08-01 00:02:33", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Translation package.", + "homepage": "http://laravel.com" + }, + { + "name": "nesbot/carbon", + "version": "1.20.0", + "version_normalized": "1.20.0.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", + "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/translation": "~2.6|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "time": "2015-06-25 04:19:39", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Carbon": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "http://nesbot.com" + } + ], + "description": "A simple API extension for DateTime.", + "homepage": "http://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ] + }, + { + "name": "illuminate/session", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/session.git", + "reference": "a719532f1ba75c352e1254743f4a9ed9a2b8412c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/session/zipball/a719532f1ba75c352e1254743f4a9ed9a2b8412c", + "reference": "a719532f1ba75c352e1254743f4a9ed9a2b8412c", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19", + "php": ">=5.5.9", + "symfony/finder": "2.7.*", + "symfony/http-foundation": "2.7.*" + }, + "suggest": { + "illuminate/console": "Required to use the session:table command (5.1.*)." + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Session\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Session package.", + "homepage": "http://laravel.com" + }, + { + "name": "symfony/process", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "4a959dd4e19c2c5d7512689413921e0a74386ec7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/4a959dd4e19c2c5d7512689413921e0a74386ec7", + "reference": "4a959dd4e19c2c5d7512689413921e0a74386ec7", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "time": "2015-10-23 14:47:27", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com" + }, + { + "name": "illuminate/http", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/http.git", + "reference": "b30fa1af5d1a7b525cc801ac41436179e43d52ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/http/zipball/b30fa1af5d1a7b525cc801ac41436179e43d52ee", + "reference": "b30fa1af5d1a7b525cc801ac41436179e43d52ee", + "shasum": "" + }, + "require": { + "illuminate/session": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9", + "symfony/http-foundation": "2.7.*", + "symfony/http-kernel": "2.7.*" + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Http\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Http package.", + "homepage": "http://laravel.com" + }, + { + "name": "symfony/console", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "5efd632294c8320ea52492db22292ff853a43766" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/5efd632294c8320ea52492db22292ff853a43766", + "reference": "5efd632294c8320ea52492db22292ff853a43766", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "time": "2015-10-20 14:38:46", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com" + }, + { + "name": "illuminate/console", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/console.git", + "reference": "c712f03ce8fdfbc90ff3587ba31a0b8e3914ddb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/console/zipball/c712f03ce8fdfbc90ff3587ba31a0b8e3914ddb0", + "reference": "c712f03ce8fdfbc90ff3587ba31a0b8e3914ddb0", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19", + "php": ">=5.5.9", + "symfony/console": "2.7.*" + }, + "suggest": { + "guzzlehttp/guzzle": "Required to use the thenPing method on schedules (~5.3|~6.0).", + "mtdowling/cron-expression": "Required to use scheduling component (~1.0).", + "symfony/process": "Required to use scheduling component (2.7.*)." + }, + "time": "2015-10-20 21:16:46", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Console package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/queue", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/queue.git", + "reference": "189b1cfaf7f08dce381b4ebbf16b0602a1efcdda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/queue/zipball/189b1cfaf7f08dce381b4ebbf16b0602a1efcdda", + "reference": "189b1cfaf7f08dce381b4ebbf16b0602a1efcdda", + "shasum": "" + }, + "require": { + "illuminate/console": "5.1.*", + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/http": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19", + "php": ">=5.5.9", + "symfony/process": "2.7.*" + }, + "suggest": { + "aws/aws-sdk-php": "Required to use the SQS queue driver (~3.0).", + "illuminate/redis": "Required to use the redis queue driver (5.1.*).", + "iron-io/iron_mq": "Required to use the iron queue driver (~2.0).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0)." + }, + "time": "2015-10-28 19:38:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Queue\\": "" + }, + "classmap": [ + "IlluminateQueueClosure.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Queue package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/pagination", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/pagination.git", + "reference": "3ed65ae58f191f2819a44c1b0e1408dcc847948f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/pagination/zipball/3ed65ae58f191f2819a44c1b0e1408dcc847948f", + "reference": "3ed65ae58f191f2819a44c1b0e1408dcc847948f", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Pagination\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Pagination package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/hashing", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/hashing.git", + "reference": "86d12970c19823809314eae180939de62d4fab2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/hashing/zipball/86d12970c19823809314eae180939de62d4fab2c", + "reference": "86d12970c19823809314eae180939de62d4fab2c", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "time": "2015-07-16 20:28:10", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Hashing\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Hashing package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/encryption", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/encryption.git", + "reference": "c10405ee5ec354b1d888e52dca6adeee6bac8476" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/encryption/zipball/c10405ee5ec354b1d888e52dca6adeee6bac8476", + "reference": "c10405ee5ec354b1d888e52dca6adeee6bac8476", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-openssl": "*", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "suggest": { + "paragonie/random_compat": "Provides a compatible interface like PHP7's random_bytes() in PHP 5 projects (^1.0.6)." + }, + "time": "2015-10-16 21:40:18", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Encryption\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Encryption package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/database", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/database.git", + "reference": "f82f4009e5776a8b0a580fca881694a778b229e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/database/zipball/f82f4009e5776a8b0a580fca881694a778b229e6", + "reference": "f82f4009e5776a8b0a580fca881694a778b229e6", + "shasum": "" + }, + "require": { + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19", + "php": ">=5.5.9" + }, + "suggest": { + "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", + "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", + "illuminate/console": "Required to use the database commands (5.1.*).", + "illuminate/events": "Required to use the observers with Eloquent (5.1.*).", + "illuminate/filesystem": "Required to use the migrations (5.1.*)." + }, + "time": "2015-10-28 21:57:04", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Database\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Database package.", + "homepage": "http://laravel.com", + "keywords": [ + "database", + "laravel", + "orm", + "sql" + ] + }, + { + "name": "illuminate/cookie", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/cookie.git", + "reference": "8ded782fcb8f0affa9fc53bc6646a88b9acb615a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/cookie/zipball/8ded782fcb8f0affa9fc53bc6646a88b9acb615a", + "reference": "8ded782fcb8f0affa9fc53bc6646a88b9acb615a", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9", + "symfony/http-foundation": "2.7.*", + "symfony/http-kernel": "2.7.*" + }, + "time": "2015-09-22 11:44:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Cookie\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Cookie package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/cache", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/cache.git", + "reference": "6ffa99bbc2c6dccb1e50ed5219a30aea6d02f0d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/cache/zipball/6ffa99bbc2c6dccb1e50ed5219a30aea6d02f0d3", + "reference": "6ffa99bbc2c6dccb1e50ed5219a30aea6d02f0d3", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19", + "php": ">=5.5.9" + }, + "suggest": { + "illuminate/database": "Required to use the database cache driver (5.1.*).", + "illuminate/filesystem": "Required to use the file cache driver (5.1.*).", + "illuminate/redis": "Required to use the redis cache driver (5.1.*)." + }, + "time": "2015-10-06 17:04:59", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Cache package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/config", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/config.git", + "reference": "de6c1cc0f2745645dec3f8bab0e43a3aa141d12d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/config/zipball/de6c1cc0f2745645dec3f8bab0e43a3aa141d12d", + "reference": "de6c1cc0f2745645dec3f8bab0e43a3aa141d12d", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/filesystem": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "time": "2015-06-18 02:16:31", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Config\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Config package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/broadcasting", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/broadcasting.git", + "reference": "c5eb4e0730dbe34aabff238507d3e8144c6625a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/broadcasting/zipball/c5eb4e0730dbe34aabff238507d3e8144c6625a2", + "reference": "c5eb4e0730dbe34aabff238507d3e8144c6625a2", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "suggest": { + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0)." + }, + "time": "2015-10-08 01:12:55", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Broadcasting\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Broadcasting package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/pipeline", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/pipeline.git", + "reference": "2725b0523b50415e1d20aea7297d205f65b53e27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/pipeline/zipball/2725b0523b50415e1d20aea7297d205f65b53e27", + "reference": "2725b0523b50415e1d20aea7297d205f65b53e27", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "time": "2015-10-05 21:58:27", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Pipeline\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Pipeline package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/bus", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/bus.git", + "reference": "83fecbefb010c30e1cd2fef1290316000cdc742d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/bus/zipball/83fecbefb010c30e1cd2fef1290316000cdc742d", + "reference": "83fecbefb010c30e1cd2fef1290316000cdc742d", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/pipeline": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Bus\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Bus package.", + "homepage": "http://laravel.com" + }, + { + "name": "illuminate/auth", + "version": "v5.1.22", + "version_normalized": "5.1.22.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/auth.git", + "reference": "ed926c9ad2b54164c0183a3a63f77f5f0ea0986a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/auth/zipball/ed926c9ad2b54164c0183a3a63f77f5f0ea0986a", + "reference": "ed926c9ad2b54164c0183a3a63f77f5f0ea0986a", + "shasum": "" + }, + "require": { + "illuminate/contracts": "5.1.*", + "illuminate/http": "5.1.*", + "illuminate/session": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19", + "php": ">=5.5.9" + }, + "suggest": { + "illuminate/console": "Required to use the auth:clear-resets command (5.1.*)." + }, + "time": "2015-10-19 06:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Auth\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Illuminate Auth package.", + "homepage": "http://laravel.com" + }, + { + "name": "laravel/lumen-framework", + "version": "v5.1.6", + "version_normalized": "5.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/lumen-framework.git", + "reference": "caf37c0b556f3bb52dad3ef0efff7b297c9ad6cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/lumen-framework/zipball/caf37c0b556f3bb52dad3ef0efff7b297c9ad6cd", + "reference": "caf37c0b556f3bb52dad3ef0efff7b297c9ad6cd", + "shasum": "" + }, + "require": { + "illuminate/auth": "5.1.*", + "illuminate/broadcasting": "5.1.*", + "illuminate/bus": "5.1.*", + "illuminate/cache": "5.1.*", + "illuminate/config": "5.1.*", + "illuminate/console": "5.1.*", + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/cookie": "5.1.*", + "illuminate/database": "5.1.*", + "illuminate/encryption": "5.1.*", + "illuminate/events": "5.1.*", + "illuminate/filesystem": "5.1.*", + "illuminate/hashing": "5.1.*", + "illuminate/http": "5.1.*", + "illuminate/pagination": "5.1.*", + "illuminate/queue": "5.1.*", + "illuminate/session": "5.1.*", + "illuminate/support": "5.1.*", + "illuminate/translation": "5.1.*", + "illuminate/validation": "5.1.*", + "illuminate/view": "5.1.*", + "monolog/monolog": "~1.0", + "mtdowling/cron-expression": "~1.0", + "nikic/fast-route": "0.4.*", + "paragonie/random_compat": "^1.0.6", + "php": ">=5.5.9", + "symfony/dom-crawler": "2.7.*", + "symfony/http-foundation": "2.7.*", + "symfony/http-kernel": "2.7.*", + "symfony/security-core": "2.7.*", + "symfony/var-dumper": "2.7.*" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "vlucas/phpdotenv": "Required to use .env files (~1.0)." + }, + "time": "2015-10-28 22:19:15", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Laravel\\Lumen\\": "src/" + }, + "classmap": [ + "src/Foundation" + ], + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "The Laravel Lumen Framework.", + "homepage": "http://laravel.com", + "keywords": [ + "framework", + "laravel", + "lumen" + ] + }, + { + "name": "vlucas/phpdotenv", + "version": "v1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "0cac554ce06277e33ddf9f0b7ade4b8bbf2af3fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/0cac554ce06277e33ddf9f0b7ade4b8bbf2af3fa", + "reference": "0cac554ce06277e33ddf9f0b7ade4b8bbf2af3fa", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "time": "2015-05-30 15:59:26", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Dotenv": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "authors": [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "homepage": "http://github.com/vlucas/phpdotenv", + "keywords": [ + "dotenv", + "env", + "environment" + ] + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "version_normalized": "1.0.6.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "time": "2015-06-21 13:59:46", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "time": "2015-10-12 03:26:01", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ] + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2015-06-21 08:04:50", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context" + }, + { + "name": "sebastian/exporter", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "7ae5513327cb536431847bcc0c10edba2701064e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", + "reference": "7ae5513327cb536431847bcc0c10edba2701064e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2015-06-21 07:55:53", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ] + }, + { + "name": "sebastian/environment", + "version": "1.3.2", + "version_normalized": "1.3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", + "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2015-08-03 06:14:51", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ] + }, + { + "name": "sebastian/diff", + "version": "1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "time": "2015-02-22 15:13:53", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ] + }, + { + "name": "sebastian/comparator", + "version": "1.2.0", + "version_normalized": "1.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2015-07-26 15:48:44", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ] + }, + { + "name": "symfony/yaml", + "version": "v2.7.6", + "version_normalized": "2.7.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "eca9019c88fbe250164affd107bc8057771f3f4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/eca9019c88fbe250164affd107bc8057771f3f4d", + "reference": "eca9019c88fbe250164affd107bc8057771f3f4d", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "time": "2015-10-11 09:39:48", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "version_normalized": "1.0.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "time": "2015-06-14 21:17:01", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ] + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "version_normalized": "2.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "time": "2015-02-03 12:10:50", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ] + }, + { + "name": "phpspec/prophecy", + "version": "v1.5.0", + "version_normalized": "1.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", + "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "time": "2015-08-13 10:07:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ] + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-06-21 13:50:34", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ] + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.8", + "version_normalized": "2.3.8.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "time": "2015-10-02 06:51:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ] + }, + { + "name": "phpunit/php-timer", + "version": "1.0.7", + "version_normalized": "1.0.7.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-06-21 08:01:12", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ] + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.8", + "version_normalized": "1.4.8.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "time": "2015-09-15 10:49:45", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ] + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-06-21 13:08:43", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ] + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.2.4", + "version_normalized": "2.2.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "time": "2015-10-06 15:47:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ] + }, + { + "name": "phpunit/phpunit", + "version": "4.8.16", + "version_normalized": "4.8.16.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "625f8c345606ed0f3a141dfb88f4116f0e22978e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/625f8c345606ed0f3a141dfb88f4116f0e22978e", + "reference": "625f8c345606ed0f3a141dfb88f4116f0e22978e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": ">=1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "time": "2015-10-23 06:48:33", + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ] + }, + { + "name": "fzaninotto/faker", + "version": "v1.5.0", + "version_normalized": "1.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "d0190b156bcca848d401fb80f31f504f37141c8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/d0190b156bcca848d401fb80f31f504f37141c8d", + "reference": "d0190b156bcca848d401fb80f31f504f37141c8d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5" + }, + "suggest": { + "ext-intl": "*" + }, + "time": "2015-05-29 06:29:14", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ] + }, + { + "name": "twig/twig", + "version": "v1.23.0", + "version_normalized": "1.23.0.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "5868cd822fd6cf626d5f805439575f9c323cee2a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/5868cd822fd6cf626d5f805439575f9c323cee2a", + "reference": "5868cd822fd6cf626d5f805439575f9c323cee2a", + "shasum": "" + }, + "require": { + "php": ">=5.2.7" + }, + "require-dev": { + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~2.7" + }, + "time": "2015-10-29 23:29:01", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.23-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + }, + { + "name": "Twig Team", + "homepage": "http://twig.sensiolabs.org/contributors", + "role": "Contributors" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ] + }, + { + "name": "rcrowe/twigbridge", + "version": "v0.8.2", + "version_normalized": "0.8.2.0", + "source": { + "type": "git", + "url": "https://github.com/rcrowe/TwigBridge.git", + "reference": "ef9ba9aadf63f48fd20d9b57a352a124d4320e4f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/ef9ba9aadf63f48fd20d9b57a352a124d4320e4f", + "reference": "ef9ba9aadf63f48fd20d9b57a352a124d4320e4f", + "shasum": "" + }, + "require": { + "illuminate/support": "5.0.*|5.1.*", + "illuminate/view": "5.0.*|5.1.*", + "php": ">=5.4.0", + "twig/twig": "~1.15|~2.0" + }, + "require-dev": { + "laravel/framework": "5.0.*", + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "~0.6", + "squizlabs/php_codesniffer": "~1.5" + }, + "suggest": { + "laravelcollective/html": "For bringing back html/form in Laravel 5.x", + "twig/extensions": "~1.0" + }, + "time": "2015-10-19 09:52:54", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.8-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "TwigBridge\\": "src", + "TwigBridge\\Tests\\": "tests" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + }, + { + "name": "Rob Crowe", + "email": "hello@vivalacrowe.com" + } + ], + "description": "Adds the power of Twig to Laravel", + "keywords": [ + "laravel", + "twig" + ] + } +] diff --git a/vendor/danielstjules/stringy/.gitignore b/vendor/danielstjules/stringy/.gitignore new file mode 100644 index 0000000..8db156e --- /dev/null +++ b/vendor/danielstjules/stringy/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +.DS_Store diff --git a/vendor/danielstjules/stringy/.travis.yml b/vendor/danielstjules/stringy/.travis.yml new file mode 100644 index 0000000..f7637c8 --- /dev/null +++ b/vendor/danielstjules/stringy/.travis.yml @@ -0,0 +1,7 @@ +language: php +php: + - 5.6 + - 5.5 + - 5.4 + - 5.3 + - hhvm diff --git a/vendor/danielstjules/stringy/CHANGELOG.md b/vendor/danielstjules/stringy/CHANGELOG.md new file mode 100644 index 0000000..379c629 --- /dev/null +++ b/vendor/danielstjules/stringy/CHANGELOG.md @@ -0,0 +1,119 @@ +### 1.10.0 (2015-07-22) + + * Added trimLeft, trimRight + * Added support for unicode whitespace to trim + * Added delimit + * Added indexOf and indexOfLast + * Added htmlEncode and htmlDecode + * Added "Ç" in toAscii() + +### 1.9.0 (2015-02-09) + + * Added hasUpperCase and hasLowerCase + * Added $removeUnsupported parameter to toAscii() + * Improved toAscii support with additional Unicode spaces, Vietnamese chars, + and numerous other characters + * Separated the charsArray from toAscii as a protected method that may be + extended by inheriting classes + * Chars array is cached for better performance + +### 1.8.1 (2015-01-08) + + * Optimized chars() + * Added "ä Ä Ö Ü"" in toAscii() + * Added support for Unicode spaces in toAscii() + * Replaced instances of self::create() with static::create() + * Added missing test cases for safeTruncate() and longestCommonSuffix() + * Updated Stringy\create() to avoid collision when it already exists + +### 1.8.0 (2015-01-03) + + * Listed ext-mbstring in composer.json + * Added Stringy\create function for PHP 5.6 + +### 1.7.0 (2014-10-14) + + * Added containsAll and containsAny + * Light cleanup + +### 1.6.0 (2014-09-14) + + * Added toTitleCase + +### 1.5.2 (2014-07-09) + + * Announced support for HHVM + +### 1.5.1 (2014-04-19) + + * Fixed toAscii() failing to remove remaining non-ascii characters + * Updated slugify() to treat dash and underscore as delimiters by default + * Updated slugify() to remove leading and trailing delimiter, if present + +### 1.5.0 (2014-03-19) + + * Made both str and encoding protected, giving property access to subclasses + * Added getEncoding() + * Fixed isJSON() giving false negatives + * Cleaned up and simplified: replace(), collapseWhitespace(), underscored(), + dasherize(), pad(), padLeft(), padRight() and padBoth() + * Fixed handling consecutive invalid chars in slugify() + * Removed conflicting hard sign transliteration in toAscii() + +### 1.4.0 (2014-02-12) + + * Implemented the IteratorAggregate interface, added chars() + * Renamed count() to countSubstr() + * Updated count() to implement Countable interface + * Implemented the ArrayAccess interface with positive and negative indices + * Switched from PSR-0 to PSR-4 autoloading + +### 1.3.0 (2013-12-16) + + * Additional Bulgarian support for toAscii + * str property made private + * Constructor casts first argument to string + * Constructor throws an InvalidArgumentException when given an array + * Constructor throws an InvalidArgumentException when given an object without + a __toString method + +### 1.2.2 (2013-12-04) + + * Updated create function to use late static binding + * Added optional $replacement param to slugify + +### 1.2.1 (2013-10-11) + + * Cleaned up tests + * Added homepage to composer.json + +### 1.2.0 (2013-09-15) + + * Fixed pad's use of InvalidArgumentException + * Fixed replace(). It now correctly treats regex special chars as normal chars + * Added additional Cyrillic letters to toAscii + * Added $caseSensitive to contains() and count() + * Added toLowerCase() + * Added toUpperCase() + * Added regexReplace() + +### 1.1.0 (2013-08-31) + + * Fix for collapseWhitespace() + * Added isHexadecimal() + * Added constructor to Stringy\Stringy + * Added isSerialized() + * Added isJson() + +### 1.0.0 (2013-08-1) + + * 1.0.0 release + * Added test coverage for Stringy::create and method chaining + * Added tests for returned type + * Fixed StaticStringy::replace(). It was returning a Stringy object instead of string + * Renamed standardize() to the more appropriate toAscii() + * Cleaned up comments and README + +### 1.0.0-rc.1 (2013-07-28) + + * Release candidate diff --git a/vendor/danielstjules/stringy/LICENSE.txt b/vendor/danielstjules/stringy/LICENSE.txt new file mode 100644 index 0000000..0b70302 --- /dev/null +++ b/vendor/danielstjules/stringy/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (C) 2013 Daniel St. Jules + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/danielstjules/stringy/README.md b/vendor/danielstjules/stringy/README.md new file mode 100644 index 0000000..ab09bdc --- /dev/null +++ b/vendor/danielstjules/stringy/README.md @@ -0,0 +1,1190 @@ +![Stringy](http://danielstjules.com/github/stringy-logo.png) + +A PHP string manipulation library with multibyte support. Offers both OO method +chaining and a procedural-style static wrapper. Tested and compatible with +PHP 5.3+ and HHVM. Inspired by underscore.string.js. + +[![Build Status](https://api.travis-ci.org/danielstjules/Stringy.svg?branch=master)](https://travis-ci.org/danielstjules/Stringy) + +* [Requiring/Loading](#requiringloading) +* [OO and Procedural](#oo-and-procedural) +* [Implemented Interfaces](#implemented-interfaces) +* [PHP 5.6 Creation](#php-56-creation) +* [Methods](#methods) + * [at](#at) + * [camelize](#camelize) + * [chars](#chars) + * [collapseWhitespace](#collapsewhitespace) + * [contains](#contains) + * [containsAll](#containsall) + * [containsAny](#containsany) + * [countSubstr](#countsubstr) + * [create](#create) + * [dasherize](#dasherize) + * [delimit](#delimit) + * [endsWith](#endswith) + * [ensureLeft](#ensureleft) + * [ensureRight](#ensureright) + * [first](#first) + * [getEncoding](#getencoding) + * [hasLowerCase](#haslowercase) + * [hasUpperCase](#hasuppercase) + * [htmlDecode](#htmldecode) + * [htmlEncode](#htmlencode) + * [humanize](#humanize) + * [indexOf](#indexof) + * [indexOfLast](#indexoflast) + * [insert](#insert) + * [isAlpha](#isalpha) + * [isAlphanumeric](#isalphanumeric) + * [isBlank](#isblank) + * [isHexadecimal](#ishexadecimal) + * [isJson](#isjson) + * [isLowerCase](#islowercase) + * [isSerialized](#isserialized) + * [isUpperCase](#isuppercase) + * [last](#last) + * [length](#length) + * [longestCommonPrefix](#longestcommonprefix) + * [longestCommonSuffix](#longestcommonsuffix) + * [longestCommonSubstring](#longestcommonsubstring) + * [lowerCaseFirst](#lowercasefirst) + * [pad](#pad) + * [padBoth](#padboth) + * [padLeft](#padleft) + * [padRight](#padright) + * [regexReplace](#regexreplace) + * [removeLeft](#removeleft) + * [removeRight](#removeright) + * [replace](#replace) + * [reverse](#reverse) + * [safeTruncate](#safetruncate) + * [shuffle](#shuffle) + * [slugify](#slugify) + * [startsWith](#startswith) + * [substr](#substr) + * [surround](#surround) + * [swapCase](#swapcase) + * [tidy](#tidy) + * [titleize](#titleize) + * [toAscii](#toascii) + * [toLowerCase](#tolowercase) + * [toSpaces](#tospaces) + * [toTabs](#totabs) + * [toTitleCase](#totitlecase) + * [toUpperCase](#touppercase) + * [trim](#trim) + * [trimLeft](#trimLeft) + * [trimRight](#trimRight) + * [truncate](#truncate) + * [underscored](#underscored) + * [upperCamelize](#uppercamelize) + * [upperCaseFirst](#uppercasefirst) +* [Links](#links) +* [Tests](#tests) +* [License](#license) + +## Requiring/Loading + +If you're using Composer to manage dependencies, you can include the following +in your composer.json file: + +```json +{ + "require": { + "danielstjules/stringy": "~1.10" + } +} +``` + +Then, after running `composer update` or `php composer.phar update`, you can +load the class using Composer's autoloading: + +```php +require 'vendor/autoload.php'; +``` + +Otherwise, you can simply require the file directly: + +```php +require_once 'path/to/Stringy/src/Stringy.php'; +// or +require_once 'path/to/Stringy/src/StaticStringy.php'; +``` + +And in either case, I'd suggest using an alias. + +```php +use Stringy\Stringy as S; +// or +use Stringy\StaticStringy as S; +``` + +## OO and Procedural + +The library offers both OO method chaining with `Stringy\Stringy`, as well as +procedural-style static method calls with `Stringy\StaticStringy`. An example +of the former is the following: + +```php +use Stringy\Stringy as S; +echo S::create('Fòô Bàř', 'UTF-8')->collapseWhitespace()->swapCase(); // 'fÒÔ bÀŘ' +``` + +`Stringy\Stringy` has a __toString() method, which returns the current string +when the object is used in a string context, ie: +`(string) S::create('foo') // 'foo'` + +Using the static wrapper, an alternative is the following: + +```php +use Stringy\StaticStringy as S; +$string = S::collapseWhitespace('Fòô Bàř', 'UTF-8'); +echo S::swapCase($string, 'UTF-8'); // 'fÒÔ bÀŘ' +``` + +## Implemented Interfaces + +`Stringy\Stringy` implements the `IteratorAggregate` interface, meaning that +`foreach` can be used with an instance of the class: + +``` php +$stringy = S::create('Fòô Bàř', 'UTF-8'); +foreach ($stringy as $char) { + echo $char; +} +// 'Fòô Bàř' +``` + +It implements the `Countable` interface, enabling the use of `count()` to +retrieve the number of characters in the string: + +``` php +$stringy = S::create('Fòô', 'UTF-8'); +count($stringy); // 3 +``` + +Furthermore, the `ArrayAccess` interface has been implemented. As a result, +`isset()` can be used to check if a character at a specific index exists. And +since `Stringy\Stringy` is immutable, any call to `offsetSet` or `offsetUnset` +will throw an exception. `offsetGet` has been implemented, however, and accepts +both positive and negative indexes. Invalid indexes result in an +`OutOfBoundsException`. + +``` php +$stringy = S::create('Bàř', 'UTF-8'); +echo $stringy[2]; // 'ř' +echo $stringy[-2]; // 'à' +isset($stringy[-4]); // false + +$stringy[3]; // OutOfBoundsException +$stringy[2] = 'a'; // Exception +``` + +## PHP 5.6 Creation + +As of PHP 5.6, [`use function`](https://wiki.php.net/rfc/use_function) is +available for importing functions. Stringy exposes a namespaced function, +`Stringy\create`, which emits the same behaviour as `Stringy\Stringy::create()`. +If running PHP 5.6, or another runtime that supports the `use function` syntax, +you can take advantage of an even simpler API as seen below: + +``` php +use function Stringy\create as s; + +// Instead of: S::create('Fòô Bàř', 'UTF-8') +s('Fòô Bàř', 'UTF-8')->collapseWhitespace()->swapCase(); +``` + +## Methods + +In the list below, any static method other than S::create refers to a method in +`Stringy\StaticStringy`. For all others, they're found in `Stringy\Stringy`. +Furthermore, all methods that return a Stringy object or string do not modify +the original. Stringy objects are immutable. + +*Note: If `$encoding` is not given, it defaults to `mb_internal_encoding()`.* + +#### at + +$stringy->at(int $index) + +S::at(int $index [, string $encoding ]) + +Returns the character at $index, with indexes starting at 0. + +```php +S::create('fòô bàř', 'UTF-8')->at(6); +S::at('fòô bàř', 6, 'UTF-8'); // 'ř' +``` + +#### camelize + +$stringy->camelize(); + +S::camelize(string $str [, string $encoding ]) + +Returns a camelCase version of the string. Trims surrounding spaces, +capitalizes letters following digits, spaces, dashes and underscores, +and removes spaces, dashes, as well as underscores. + +```php +S::create('Camel-Case')->camelize(); +S::camelize('Camel-Case'); // 'camelCase' +``` + +#### chars + +$stringy->chars(); + +S::chars(string $str [, string $encoding ]) + +Returns an array consisting of the characters in the string. + +```php +S::create('Fòô Bàř', 'UTF-8')->chars(); +S::chars('Fòô Bàř', 'UTF-8'); // array(F', 'ò', 'ô', ' ', 'B', 'à', 'ř') +``` + +#### collapseWhitespace + +$stringy->collapseWhitespace() + +S::collapseWhitespace(string $str [, string $encoding ]) + +Trims the string and replaces consecutive whitespace characters with a +single space. This includes tabs and newline characters, as well as +multibyte whitespace such as the thin space and ideographic space. + +```php +S::create(' Ο συγγραφέας ')->collapseWhitespace(); +S::collapseWhitespace(' Ο συγγραφέας '); // 'Ο συγγραφέας' +``` + +#### contains + +$stringy->contains(string $needle [, boolean $caseSensitive = true ]) + +S::contains(string $haystack, string $needle [, boolean $caseSensitive = true [, string $encoding ]]) + +Returns true if the string contains $needle, false otherwise. By default, +the comparison is case-sensitive, but can be made insensitive +by setting $caseSensitive to false. + +```php +S::create('Ο συγγραφέας είπε', 'UTF-8')->contains('συγγραφέας'); +S::contains('Ο συγγραφέας είπε', 'συγγραφέας', 'UTF-8'); // true +``` + +#### containsAll + +$stringy->containsAll(array $needles [, boolean $caseSensitive = true ]) + +S::containsAll(string $haystack, array $needles [, boolean $caseSensitive = true [, string $encoding ]]) + +Returns true if the string contains all $needles, false otherwise. By +default the comparison is case-sensitive, but can be made insensitive by +setting $caseSensitive to false. + +```php +S::create('Str contains foo and bar')->containsAll(array('foo', 'bar')); +S::containsAll('Str contains foo and bar', array('foo', 'bar')); // true +``` + +#### containsAny + +$stringy->containsAny(array $needles [, boolean $caseSensitive = true ]) + +S::containsAny(string $haystack, array $needles [, boolean $caseSensitive = true [, string $encoding ]]) + +Returns true if the string contains any $needles, false otherwise. By +default the comparison is case-sensitive, but can be made insensitive by +setting $caseSensitive to false. + +```php +S::create('Str contains foo')->containsAny(array('foo', 'bar')); +S::containsAny('Str contains foo', array('foo', 'bar')); // true +``` + +#### countSubstr + +$stringy->countSubstr(string $substring [, boolean $caseSensitive = true ]) + +S::countSubstr(string $str, string $substring [, boolean $caseSensitive = true [, string $encoding ]]) + +Returns the number of occurrences of $substring in the given string. +By default, the comparison is case-sensitive, but can be made insensitive +by setting $caseSensitive to false. + +```php +S::create('Ο συγγραφέας είπε', 'UTF-8')->countSubstr('α'); +S::countSubstr('Ο συγγραφέας είπε', 'α', 'UTF-8'); // 2 +``` + +#### create + +S::create(mixed $str [, $encoding ]) + +Creates a Stringy object and assigns both str and encoding properties +the supplied values. $str is cast to a string prior to assignment, and if +$encoding is not specified, it defaults to mb_internal_encoding(). It +then returns the initialized object. Throws an InvalidArgumentException +if the first argument is an array or object without a __toString method. + +```php +$stringy = S::create('fòô bàř', 'UTF-8'); // 'fòô bàř' +``` + +#### dasherize + +$stringy->dasherize(); + +S::dasherize(string $str [, string $encoding ]) + +Returns a lowercase and trimmed string separated by dashes. Dashes are +inserted before uppercase characters (with the exception of the first +character of the string), and in place of spaces as well as underscores. + +```php +S::create('TestDCase')->dasherize(); +S::dasherize('TestDCase'); // 'test-d-case' +``` + +#### delimit + +$stringy->delimit($delimiter); + +S::delimit(string $str [, string $delimiter, string $encoding ]) + +Returns a lowercase and trimmed string separated by the given delimiter. +Delimiters are inserted before uppercase characters (with the exception +of the first character of the string), and in place of spaces, dashes, +and underscores. Alpha delimiters are not converted to lowercase. + +```php +S::create('TestDCase')->delimit('>>'); +S::delimit('TestCase', '>>'); // 'test>>case' +``` + +#### endsWith + +$stringy->endsWith(string $substring [, boolean $caseSensitive = true ]) + +S::endsWith(string $str, string $substring [, boolean $caseSensitive = true [, string $encoding ]]) + +Returns true if the string ends with $substring, false otherwise. By +default, the comparison is case-sensitive, but can be made insensitive by +setting $caseSensitive to false. + +```php +S::create('FÒÔ bàřs', 'UTF-8')->endsWith('àřs', true); +S::endsWith('FÒÔ bàřs', 'àřs', true, 'UTF-8'); // true +``` + +#### ensureLeft + +$stringy->ensureLeft(string $substring) + +S::ensureLeft(string $substring [, string $encoding ]) + +Ensures that the string begins with $substring. If it doesn't, it's prepended. + +```php +S::create('foobar')->ensureLeft('http://'); +S::ensureLeft('foobar', 'http://'); // 'http://foobar' +``` + +#### ensureRight + +$stringy->ensureRight(string $substring) + +S::ensureRight(string $substring [, string $encoding ]) + +Ensures that the string begins with $substring. If it doesn't, it's appended. + +```php +S::create('foobar')->ensureRight('.com'); +S::ensureRight('foobar', '.com'); // 'foobar.com' +``` + +#### first + +$stringy->first(int $n) + +S::first(int $n [, string $encoding ]) + +Returns the first $n characters of the string. + +```php +S::create('fòô bàř', 'UTF-8')->first(3); +S::first('fòô bàř', 3, 'UTF-8'); // 'fòô' +``` + +#### getEncoding + +$stringy->getEncoding() + +Returns the encoding used by the Stringy object. + +```php +S::create('fòô bàř', 'UTF-8')->getEncoding(); // 'UTF-8' +``` + +#### hasLowerCase + +$stringy->hasLowerCase() + +S::hasLowerCase(string $str [, string $encoding ]) + +Returns true if the string contains a lower case char, false otherwise. + +```php +S::create('fòô bàř', 'UTF-8')->hasLowerCase(); +S::hasLowerCase('fòô bàř', 'UTF-8'); // true +``` + +#### hasUpperCase + +$stringy->hasUpperCase() + +S::hasUpperCase(string $str [, string $encoding ]) + +Returns true if the string contains an upper case char, false otherwise. + +```php +S::create('fòô bàř', 'UTF-8')->hasUpperCase(); +S::hasUpperCase('fòô bàř', 'UTF-8'); // false +``` + +#### htmlDecode + +$stringy->htmlDecode() + +S::htmlDecode(string $str [, int $flags, string $encoding ]) + +Convert all HTML entities to their applicable characters. + +```php +S::create('&')->htmlDecode(); +S::htmlDecode('&'); // '&' +``` + +#### htmlEncode + +$stringy->htmlEncode() + +S::htmlEncode(string $str [, int $flags, string $encoding ]) + +Convert all applicable characters to HTML entities. + +```php +S::create('&')->htmlEncode(); +S::htmlEncode('&'); // '&' +``` + +#### humanize + +$stringy->humanize() + +S::humanize(string $str [, string $encoding ]) + +Capitalizes the first word of the string, replaces underscores with +spaces, and strips '_id'. + +```php +S::create('author_id')->humanize(); +S::humanize('author_id'); // 'Author' +``` + +#### indexOf + +$stringy->indexOf(string $needle [, $offset = 0 ]); + +S::indexOf(string $haystack , string $needle [, $offset = 0 [, $encoding = null ]]) + +Returns the index of the first occurrence of $needle in the string, +and false if not found. Accepts an optional offset from which to begin +the search. + +```php +S::create('string', 'UTF-8')->indexOf('ing'); +S::indexOf('string', 'ing'); // 3 +``` + +#### indexOfLast + +$stringy->indexOfLast(string $needle [, $offset = 0 ]); + +S::indexOfLast(string $haystack , string $needle [, $offset = 0 [, $encoding = null ]]) + +Returns the index of the last occurrence of $needle in the string, +and false if not found. Accepts an optional offset from which to begin +the search. + +```php +S::create('string', 'UTF-8')->indexOfLast('ing'); +S::indexOfLast('string string', 'ing'); // 10 +``` + +#### insert + +$stringy->insert(int $index, string $substring) + +S::insert(string $str, int $index, string $substring [, string $encoding ]) + +Inserts $substring into the string at the $index provided. + +```php +S::create('fòô bà', 'UTF-8')->insert('ř', 6); +S::insert('fòô bà', 'ř', 6, 'UTF-8'); // 'fòô bàř' +``` + +#### isAlpha + +$stringy->isAlpha() + +S::isAlpha(string $str [, string $encoding ]) + +Returns true if the string contains only alphabetic chars, false otherwise. + +```php +S::create('丹尼爾', 'UTF-8')->isAlpha(); +S::isAlpha('丹尼爾', 'UTF-8'); // true +``` + +#### isAlphanumeric + +$stringy->isAlphanumeric() + +S::isAlphanumeric(string $str [, string $encoding ]) + +Returns true if the string contains only alphabetic and numeric chars, false +otherwise. + +```php +S::create('دانيال1', 'UTF-8')->isAlphanumeric(); +S::isAlphanumeric('دانيال1', 'UTF-8'); // true +``` + +#### isBlank + +$stringy->isBlank() + +S::isBlank(string $str [, string $encoding ]) + +Returns true if the string contains only whitespace chars, false otherwise. + +```php +S::create("\n\t \v\f")->isBlank(); +S::isBlank("\n\t \v\f"); // true +``` + +#### isHexadecimal + +$stringy->isHexadecimal() + +S::isHexadecimal(string $str [, string $encoding ]) + +Returns true if the string contains only hexadecimal chars, false otherwise. + +```php +S::create('A102F')->isHexadecimal(); +S::isHexadecimal('A102F'); // true +``` + +#### isJson + +$stringy->isJson() + +S::isJson(string $str [, string $encoding ]) + +Returns true if the string is JSON, false otherwise. + +```php +S::create('{"foo":"bar"}')->isJson(); +S::isJson('{"foo":"bar"}'); // true +``` + +#### isLowerCase + +$stringy->isLowerCase() + +S::isLowerCase(string $str [, string $encoding ]) + +Returns true if the string contains only lower case chars, false otherwise. + +```php +S::create('fòô bàř', 'UTF-8')->isLowerCase(); +S::isLowerCase('fòô bàř', 'UTF-8'); // true +``` + +#### isSerialized + +$stringy->isSerialized() + +S::isSerialized(string $str [, string $encoding ]) + +Returns true if the string is serialized, false otherwise. + +```php +S::create('a:1:{s:3:"foo";s:3:"bar";}', 'UTF-8')->isSerialized(); +S::isSerialized('a:1:{s:3:"foo";s:3:"bar";}', 'UTF-8'); // true +``` + +#### isUpperCase + +$stringy->isUpperCase() + +S::isUpperCase(string $str [, string $encoding ]) + +Returns true if the string contains only upper case chars, false otherwise. + +```php +S::create('FÒÔBÀŘ', 'UTF-8')->isUpperCase(); +S::isUpperCase('FÒÔBÀŘ', 'UTF-8'); // true +``` + +#### last + +$stringy->last(int $n) + +S::last(int $n [, string $encoding ]) + +Returns the last $n characters of the string. + +```php +S::create('fòô bàř', 'UTF-8')->last(3); +S::last('fòô bàř', 3, 'UTF-8'); // 'bàř' +``` + +#### length + +$stringy->length() + +S::length(string $str [, string $encoding ]) + +Returns the length of the string. An alias for PHP's mb_strlen() function. + +```php +S::create('fòô bàř', 'UTF-8')->length(); +S::length('fòô bàř', 'UTF-8'); // 7 +``` + +#### longestCommonPrefix + +$stringy->longestCommonPrefix(string $otherStr) + +S::longestCommonPrefix(string $str, string $otherStr [, $encoding ]) + +Returns the longest common prefix between the string and $otherStr. + +```php +S::create('fòô bar', 'UTF-8')->longestCommonPrefix('fòr bar'); +S::longestCommonPrefix('fòô bar', 'fòr bar', 'UTF-8'); // 'fò' +``` + +#### longestCommonSuffix + +$stringy->longestCommonSuffix(string $otherStr) + +S::longestCommonSuffix(string $str, string $otherStr [, $encoding ]) + +Returns the longest common suffix between the string and $otherStr. + +```php +S::create('fòô bàř', 'UTF-8')->longestCommonSuffix('fòr bàř'); +S::longestCommonSuffix('fòô bàř', 'fòr bàř', 'UTF-8'); // ' bàř' +``` + +#### longestCommonSubstring + +$stringy->longestCommonSubstring(string $otherStr) + +S::longestCommonSubstring(string $str, string $otherStr [, $encoding ]) + +Returns the longest common substring between the string and $otherStr. In the +case of ties, it returns that which occurs first. + +```php +S::create('foo bar')->longestCommonSubstring('boo far'); +S::longestCommonSubstring('foo bar', 'boo far'); // 'oo ' +``` + +#### lowerCaseFirst + +$stringy->lowerCaseFirst(); + +S::lowerCaseFirst(string $str [, string $encoding ]) + +Converts the first character of the supplied string to lower case. + +```php +S::create('Σ test', 'UTF-8')->lowerCaseFirst(); +S::lowerCaseFirst('Σ test', 'UTF-8'); // 'σ test' +``` + +#### pad + +$stringy->pad(int $length [, string $padStr = ' ' [, string $padType = 'right' ]]) + +S::pad(string $str , int $length [, string $padStr = ' ' [, string $padType = 'right' [, string $encoding ]]]) + +Pads the string to a given length with $padStr. If length is less than +or equal to the length of the string, no padding takes places. The default +string used for padding is a space, and the default type (one of 'left', +'right', 'both') is 'right'. Throws an InvalidArgumentException if +$padType isn't one of those 3 values. + +```php +S::create('fòô bàř', 'UTF-8')->pad( 10, '¬ø', 'left'); +S::pad('fòô bàř', 10, '¬ø', 'left', 'UTF-8'); // '¬ø¬fòô bàř' +``` + +#### padBoth + +$stringy->padBoth(int $length [, string $padStr = ' ' ]) + +S::padBoth(string $str , int $length [, string $padStr = ' ' [, string $encoding ]]) + +Returns a new string of a given length such that both sides of the string +string are padded. Alias for pad() with a $padType of 'both'. + +```php +S::create('foo bar')->padBoth(9, ' '); +S::padBoth('foo bar', 9, ' '); // ' foo bar ' +``` + +#### padLeft + +$stringy->padLeft(int $length [, string $padStr = ' ' ]) + +S::padLeft(string $str , int $length [, string $padStr = ' ' [, string $encoding ]]) + +Returns a new string of a given length such that the beginning of the +string is padded. Alias for pad() with a $padType of 'left'. + +```php +S::create($str, $encoding)->padLeft($length, $padStr); +S::padLeft('foo bar', 9, ' '); // ' foo bar' +``` + +#### padRight + +$stringy->padRight(int $length [, string $padStr = ' ' ]) + +S::padRight(string $str , int $length [, string $padStr = ' ' [, string $encoding ]]) + +Returns a new string of a given length such that the end of the string is +padded. Alias for pad() with a $padType of 'right'. + +```php +S::create('foo bar')->padRight(10, '_*'); +S::padRight('foo bar', 10, '_*'); // 'foo bar_*_' +``` + +#### regexReplace + +$stringy->regexReplace(string $pattern, string $replacement [, string $options = 'msr']) + +S::regexReplace(string $str, string $pattern, string $replacement [, string $options = 'msr' [, string $encoding ]]) + +Replaces all occurrences of $pattern in $str by $replacement. An alias +for mb_ereg_replace(). Note that the 'i' option with multibyte patterns +in mb_ereg_replace() requires PHP 5.4+. This is due to a lack of support +in the bundled version of Oniguruma in PHP 5.3. + +```php +S::create('fòô ', 'UTF-8')->regexReplace('f[òô]+\s', 'bàř', 'msr'); +S::regexReplace('fòô ', 'f[òô]+\s', 'bàř', 'msr', 'UTF-8'); // 'bàř' +``` + +#### removeLeft + +$stringy->removeLeft(string $substring) + +S::removeLeft(string $str, string $substring [, string $encoding ]) + +Returns a new string with the prefix $substring removed, if present. + +```php +S::create('fòô bàř', 'UTF-8')->removeLeft('fòô '); +S::removeLeft('fòô bàř', 'fòô ', 'UTF-8'); // 'bàř' +``` + +#### removeRight + +$stringy->removeRight(string $substring) + +S::removeRight(string $str, string $substring [, string $encoding ]) + +Returns a new string with the suffix $substring removed, if present. + +```php +S::create('fòô bàř', 'UTF-8')->removeRight(' bàř'); +S::removeRight('fòô bàř', ' bàř', 'UTF-8'); // 'fòô' +``` + +#### replace + +$stringy->replace(string $search, string $replacement) + +S::replace(string $str, string $search, string $replacement [, string $encoding ]) + +Replaces all occurrences of $search in $str by $replacement. + +```php +S::create('fòô bàř fòô bàř', 'UTF-8')->replace('fòô ', ''); +S::replace('fòô bàř fòô bàř', 'fòô ', '', 'UTF-8'); // 'bàř bàř' +``` + +#### reverse + +$stringy->reverse() + +S::reverse(string $str [, string $encoding ]) + +Returns a reversed string. A multibyte version of strrev(). + +```php +S::create('fòô bàř', 'UTF-8')->reverse(); +S::reverse('fòô bàř', 'UTF-8'); // 'řàb ôòf' +``` + +#### safeTruncate + +$stringy->safeTruncate(int $length [, string $substring = '' ]) + +S::safeTruncate(string $str, int $length [, string $substring = '' [, string $encoding ]]) + +Truncates the string to a given length, while ensuring that it does not +split words. If $substring is provided, and truncating occurs, the +string is further truncated so that the substring may be appended without +exceeding the desired length. + +```php +S::create('What are your plans today?')->safeTruncate(22, '...'); +S::safeTruncate('What are your plans today?', 22, '...'); // 'What are your plans...' +``` + +#### shuffle + +$stringy->shuffle() + +S::shuffle(string $str [, string $encoding ]) + +A multibyte str_shuffle() function. It returns a string with its characters in +random order. + +```php +S::create('fòô bàř', 'UTF-8')->shuffle(); +S::shuffle('fòô bàř', 'UTF-8'); // 'àôřb òf' +``` + +#### slugify + +$stringy->slugify([ string $replacement = '-' ]) + +S::slugify(string $str [, string $replacement = '-' ]) + +Converts the string into an URL slug. This includes replacing non-ASCII +characters with their closest ASCII equivalents, removing remaining +non-ASCII and non-alphanumeric characters, and replacing whitespace with +$replacement. The replacement defaults to a single dash, and the string +is also converted to lowercase. + +```php +S::create('Using strings like fòô bàř')->slugify(); +S::slugify('Using strings like fòô bàř'); // 'using-strings-like-foo-bar' +``` + +#### startsWith + +$stringy->startsWith(string $substring [, boolean $caseSensitive = true ]) + +S::startsWith(string $str, string $substring [, boolean $caseSensitive = true [, string $encoding ]]) + +Returns true if the string begins with $substring, false otherwise. +By default, the comparison is case-sensitive, but can be made insensitive +by setting $caseSensitive to false. + +```php +S::create('FÒÔ bàřs', 'UTF-8')->startsWith('fòô bàř', false); +S::startsWith('FÒÔ bàřs', 'fòô bàř', false, 'UTF-8'); // true +``` + +#### substr + +$stringy->substr(int $start [, int $length ]) + +S::substr(string $str, int $start [, int $length [, string $encoding ]]) + +Returns the substring beginning at $start with the specified $length. +It differs from the mb_substr() function in that providing a $length of +null will return the rest of the string, rather than an empty string. + +```php +S::create('fòô bàř', 'UTF-8')->substr(2, 3); +S::substr('fòô bàř', 2, 3, 'UTF-8'); // 'ô b' +``` + +#### surround + +$stringy->surround(string $substring) + +S::surround(string $str, string $substring) + +Surrounds a string with the given substring. + +```php +S::create(' ͜ ')->surround('ʘ'); +S::surround(' ͜ ', 'ʘ'); // 'ʘ ͜ ʘ' +``` + +#### swapCase + +$stringy->swapCase(); + +S::swapCase(string $str [, string $encoding ]) + +Returns a case swapped version of the string. + +```php +S::create('Ντανιλ', 'UTF-8')->swapCase(); +S::swapCase('Ντανιλ', 'UTF-8'); // 'νΤΑΝΙΛ' +``` + +#### tidy + +$stringy->tidy() + +S::tidy(string $str) + +Returns a string with smart quotes, ellipsis characters, and dashes from +Windows-1252 (commonly used in Word documents) replaced by their ASCII equivalents. + +```php +S::create('“I see…”')->tidy(); +S::tidy('“I see…”'); // '"I see..."' +``` + +#### titleize + +$stringy->titleize([ string $encoding ]) + +S::titleize(string $str [, array $ignore [, string $encoding ]]) + +Returns a trimmed string with the first letter of each word capitalized. +Ignores the case of other letters, preserving any acronyms. Also accepts +an array, $ignore, allowing you to list words not to be capitalized. + +```php +$ignore = array('at', 'by', 'for', 'in', 'of', 'on', 'out', 'to', 'the'); +S::create('i like to watch DVDs at home', 'UTF-8')->titleize($ignore); +S::titleize('i like to watch DVDs at home', $ignore, 'UTF-8'); +// 'I Like to Watch DVDs at Home' +``` + +#### toAscii + +$stringy->toAscii() + +S::toAscii(string $str [, boolean $removeUnsupported = true]) + +Returns an ASCII version of the string. A set of non-ASCII characters are +replaced with their closest ASCII counterparts, and the rest are removed +unless instructed otherwise. + +```php +S::create('fòô bàř')->toAscii(); +S::toAscii('fòô bàř'); // 'foo bar' +``` + +#### toLowerCase + +$stringy->toLowerCase() + +S::toLowerCase(string $str [, string $encoding ]) + +Converts all characters in the string to lowercase. An alias for PHP's +mb_strtolower(). + +```php +S::create('FÒÔ BÀŘ', 'UTF-8')->toLowerCase(); +S::toLowerCase('FÒÔ BÀŘ', 'UTF-8'); // 'fòô bàř' +``` + +#### toSpaces + +$stringy->toSpaces([ tabLength = 4 ]) + +S::toSpaces(string $str [, int $tabLength = 4 ]) + +Converts each tab in the string to some number of spaces, as defined by +$tabLength. By default, each tab is converted to 4 consecutive spaces. + +```php +S::create(' String speech = "Hi"')->toSpaces(); +S::toSpaces(' String speech = "Hi"'); // ' String speech = "Hi"' +``` + +#### toTabs + +$stringy->toTabs([ tabLength = 4 ]) + +S::toTabs(string $str [, int $tabLength = 4 ]) + +Converts each occurrence of some consecutive number of spaces, as defined +by $tabLength, to a tab. By default, each 4 consecutive spaces are +converted to a tab. + +```php +S::create(' fòô bàř')->toTabs(); +S::toTabs(' fòô bàř'); // ' fòô bàř' +``` + +#### toTitleCase + +$stringy->toTitleCase() + +S::toTitleCase(string $str [, string $encoding ]) + +Converts the first character of each word in the string to uppercase. + +```php +S::create('fòô bàř', 'UTF-8')->toTitleCase(); +S::toTitleCase('fòô bàř', 'UTF-8'); // 'Fòô Bàř' +``` + +#### toUpperCase + +$stringy->toUpperCase() + +S::toUpperCase(string $str [, string $encoding ]) + +Converts all characters in the string to uppercase. An alias for PHP's +mb_strtoupper(). + +```php +S::create('fòô bàř', 'UTF-8')->toUpperCase(); +S::toUpperCase('fòô bàř', 'UTF-8'); // 'FÒÔ BÀŘ' +``` + +#### trim + +$stringy->trim([, string $chars]) + +S::trim(string $str [, string $chars [, string $encoding ]]) + +Returns a string with whitespace removed from the start and end of the +string. Supports the removal of unicode whitespace. Accepts an optional +string of characters to strip instead of the defaults. + +```php +S::create(' fòô bàř ', 'UTF-8')->trim(); +S::trim(' fòô bàř '); // 'fòô bàř' +``` + +#### trimLeft + +$stringy->trimLeft([, string $chars]) + +S::trimLeft(string $str [, string $chars [, string $encoding ]]) + +Returns a string with whitespace removed from the start of the string. +Supports the removal of unicode whitespace. Accepts an optional +string of characters to strip instead of the defaults. + +```php +S::create(' fòô bàř ', 'UTF-8')->trimLeft(); +S::trimLeft(' fòô bàř '); // 'fòô bàř ' +``` + +#### trimRight + +$stringy->trimRight([, string $chars]) + +S::trimRight(string $str [, string $chars [, string $encoding ]]) + +Returns a string with whitespace removed from the end of the string. +Supports the removal of unicode whitespace. Accepts an optional +string of characters to strip instead of the defaults. + +```php +S::create(' fòô bàř ', 'UTF-8')->trimRight(); +S::trimRight(' fòô bàř '); // ' fòô bàř' +``` + +#### truncate + +$stringy->truncate(int $length [, string $substring = '' ]) + +S::truncate(string $str, int $length [, string $substring = '' [, string $encoding ]]) + +Truncates the string to a given length. If $substring is provided, and +truncating occurs, the string is further truncated so that the substring +may be appended without exceeding the desired length. + +```php +S::create('What are your plans today?')->truncate(19, '...'); +S::truncate('What are your plans today?', 19, '...'); // 'What are your pl...' +``` + +#### underscored + +$stringy->underscored(); + +S::underscored(string $str [, string $encoding ]) + +Returns a lowercase and trimmed string separated by underscores. +Underscores are inserted before uppercase characters (with the exception +of the first character of the string), and in place of spaces as well as dashes. + +```php +S::create('TestUCase')->underscored(); +S::underscored('TestUCase'); // 'test_u_case' +``` + +#### upperCamelize + +$stringy->upperCamelize(); + +S::upperCamelize(string $str [, string $encoding ]) + +Returns an UpperCamelCase version of the supplied string. It trims +surrounding spaces, capitalizes letters following digits, spaces, dashes +and underscores, and removes spaces, dashes, underscores. + +```php +S::create('Upper Camel-Case')->upperCamelize(); +S::upperCamelize('Upper Camel-Case'); // 'UpperCamelCase' +``` + +#### upperCaseFirst + +$stringy->upperCaseFirst(); + +S::upperCaseFirst(string $str [, string $encoding ]) + +Converts the first character of the supplied string to upper case. + +```php +S::create('σ test', 'UTF-8')->upperCaseFirst(); +S::upperCaseFirst('σ test', 'UTF-8'); // 'Σ test' +``` + +## Links + +The following is a list of libraries that extend Stringy: + + * [SliceableStringy](https://github.com/danielstjules/SliceableStringy): +Python-like string slices in PHP + * [SubStringy](https://github.com/TCB13/SubStringy): +Advanced substring methods + +## Tests + +From the project directory, tests can be ran using `phpunit` + +## License + +Released under the MIT License - see `LICENSE.txt` for details. diff --git a/vendor/danielstjules/stringy/composer.json b/vendor/danielstjules/stringy/composer.json new file mode 100644 index 0000000..f71f252 --- /dev/null +++ b/vendor/danielstjules/stringy/composer.json @@ -0,0 +1,35 @@ +{ + "name": "danielstjules/stringy", + "description": "A string manipulation library with multibyte support", + "keywords": [ + "multibyte", "string", "manipulation", "utility", "methods", "utf-8", + "helpers", "utils", "utf" + ], + "homepage": "https://github.com/danielstjules/Stringy", + "license": "MIT", + "authors": [ + { + "name": "Daniel St. Jules", + "email": "danielst.jules@gmail.com", + "homepage": "http://www.danielstjules.com" + } + ], + "require": { + "php": ">=5.3.0", + "ext-mbstring": "*" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "support": { + "issues": "https://github.com/danielstjules/Stringy/issues", + "source": "https://github.com/danielstjules/Stringy" + }, + "autoload": { + "psr-4": { "Stringy\\": "src/" }, + "files": ["src/Create.php"] + }, + "autoload-dev": { + "classmap": [ "tests" ] + } +} diff --git a/vendor/danielstjules/stringy/phpunit.xml.dist b/vendor/danielstjules/stringy/phpunit.xml.dist new file mode 100644 index 0000000..987dbbf --- /dev/null +++ b/vendor/danielstjules/stringy/phpunit.xml.dist @@ -0,0 +1,14 @@ + + + + + + tests/CommonTest.php + tests/StringyTest.php + tests/StaticStringyTest.php + tests/CreateTest.php + + + diff --git a/vendor/danielstjules/stringy/src/Create.php b/vendor/danielstjules/stringy/src/Create.php new file mode 100644 index 0000000..c6a2f44 --- /dev/null +++ b/vendor/danielstjules/stringy/src/Create.php @@ -0,0 +1,19 @@ +chars(); + } + + /** + * Converts the first character of the supplied string to upper case. + * + * @param string $str String to modify + * @param string $encoding The character encoding + * @return string String with the first character being upper case + */ + public static function upperCaseFirst($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->upperCaseFirst(); + } + + /** + * Converts the first character of the supplied string to lower case. + * + * @param string $str String to modify + * @param string $encoding The character encoding + * @return string String with the first character being lower case + */ + public static function lowerCaseFirst($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->lowerCaseFirst(); + } + + /** + * Returns a camelCase version of the string. Trims surrounding spaces, + * capitalizes letters following digits, spaces, dashes and underscores, + * and removes spaces, dashes, as well as underscores. + * + * @param string $str String to convert to camelCase + * @param string $encoding The character encoding + * @return string String in camelCase + */ + public static function camelize($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->camelize(); + } + + /** + * Returns an UpperCamelCase version of the supplied string. It trims + * surrounding spaces, capitalizes letters following digits, spaces, dashes + * and underscores, and removes spaces, dashes, underscores. + * + * @param string $str String to convert to UpperCamelCase + * @param string $encoding The character encoding + * @return string String in UpperCamelCase + */ + public static function upperCamelize($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->upperCamelize(); + } + + /** + * Returns a lowercase and trimmed string separated by dashes. Dashes are + * inserted before uppercase characters (with the exception of the first + * character of the string), and in place of spaces as well as underscores. + * + * @param string $str String to convert + * @param string $encoding The character encoding + * @return string Dasherized string + */ + public static function dasherize($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->dasherize(); + } + + /** + * Returns a lowercase and trimmed string separated by underscores. + * Underscores are inserted before uppercase characters (with the exception + * of the first character of the string), and in place of spaces as well as + * dashes. + * + * @param string $str String to convert + * @param string $encoding The character encoding + * @return string Underscored string + */ + public static function underscored($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->underscored(); + } + + /** + * Returns a lowercase and trimmed string separated by the given delimiter. + * Delimiters are inserted before uppercase characters (with the exception + * of the first character of the string), and in place of spaces, dashes, + * and underscores. Alpha delimiters are not converted to lowercase. + * + * @param string $str String to convert + * @param string $delimiter Sequence used to separate parts of the string + * @param string $encoding The character encoding + * @return string String with delimiter + */ + public static function delimit($str, $delimiter, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->delimit($delimiter); + } + + /** + * Returns a case swapped version of the string. + * + * @param string $str String to swap case + * @param string $encoding The character encoding + * @return string String with each character's case swapped + */ + public static function swapCase($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->swapCase(); + } + + /** + * Returns a trimmed string with the first letter of each word capitalized. + * Ignores the case of other letters, preserving any acronyms. Also accepts + * an array, $ignore, allowing you to list words not to be capitalized. + * + * @param string $str String to titleize + * @param string $encoding The character encoding + * @param array $ignore An array of words not to capitalize + * @return string Titleized string + */ + public static function titleize($str, $ignore = null, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->titleize($ignore); + } + + /** + * Capitalizes the first word of the string, replaces underscores with + * spaces, and strips '_id'. + * + * @param string $str String to humanize + * @param string $encoding The character encoding + * @return string A humanized string + */ + public static function humanize($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->humanize(); + } + + /** + * Returns a string with smart quotes, ellipsis characters, and dashes from + * Windows-1252 (commonly used in Word documents) replaced by their ASCII + * equivalents. + * + * @param string $str String to remove special chars + * @return string String with those characters removed + */ + public static function tidy($str) + { + return (string) Stringy::create($str)->tidy(); + } + + /** + * Trims the string and replaces consecutive whitespace characters with a + * single space. This includes tabs and newline characters, as well as + * multibyte whitespace such as the thin space and ideographic space. + * + * @param string $str The string to cleanup whitespace + * @param string $encoding The character encoding + * @return string The trimmed string with condensed whitespace + */ + public static function collapseWhitespace($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->collapseWhitespace(); + } + + /** + * Returns an ASCII version of the string. A set of non-ASCII characters are + * replaced with their closest ASCII counterparts, and the rest are removed + * unless instructed otherwise. + * + * @param string $str A string with non-ASCII characters + * @param bool $removeUnsupported Whether or not to remove the + * unsupported characters + * @return string A string containing only ASCII characters + */ + public static function toAscii($str, $removeUnsupported = true) + { + return (string) Stringy::create($str)->toAscii($removeUnsupported); + } + + /** + * Pads the string to a given length with $padStr. If length is less than + * or equal to the length of the string, no padding takes places. The + * default string used for padding is a space, and the default type (one of + * 'left', 'right', 'both') is 'right'. Throws an InvalidArgumentException + * if $padType isn't one of those 3 values. + * + * @param string $str String to pad + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @param string $padType One of 'left', 'right', 'both' + * @param string $encoding The character encoding + * @return string The padded string + * @throws \InvalidArgumentException If $padType isn't one of 'right', + * 'left' or 'both' + */ + public static function pad($str, $length, $padStr = ' ', $padType = 'right', + $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->pad($length, $padStr, $padType); + } + + /** + * Returns a new string of a given length such that the beginning of the + * string is padded. Alias for pad() with a $padType of 'left'. + * + * @param string $str String to pad + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @param string $encoding The character encoding + * @return string The padded string + */ + public static function padLeft($str, $length, $padStr = ' ', $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->padLeft($length, $padStr); + } + + /** + * Returns a new string of a given length such that the end of the string + * is padded. Alias for pad() with a $padType of 'right'. + * + * @param string $str String to pad + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @param string $encoding The character encoding + * @return string The padded string + */ + public static function padRight($str, $length, $padStr = ' ', $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->padRight($length, $padStr); + } + + /** + * Returns a new string of a given length such that both sides of the + * string are padded. Alias for pad() with a $padType of 'both'. + * + * @param string $str String to pad + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @param string $encoding The character encoding + * @return string The padded string + */ + public static function padBoth($str, $length, $padStr = ' ', $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->padBoth($length, $padStr); + } + + /** + * Returns true if the string begins with $substring, false otherwise. By + * default, the comparison is case-sensitive, but can be made insensitive + * by setting $caseSensitive to false. + * + * @param string $str String to check the start of + * @param string $substring The substring to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @param string $encoding The character encoding + * @return bool Whether or not $str starts with $substring + */ + public static function startsWith($str, $substring, $caseSensitive = true, + $encoding = null) + { + return Stringy::create($str, $encoding) + ->startsWith($substring, $caseSensitive); + } + + /** + * Returns true if the string ends with $substring, false otherwise. By + * default, the comparison is case-sensitive, but can be made insensitive + * by setting $caseSensitive to false. + * + * @param string $str String to check the end of + * @param string $substring The substring to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @param string $encoding The character encoding + * @return bool Whether or not $str ends with $substring + */ + public static function endsWith($str, $substring, $caseSensitive = true, + $encoding = null) + { + return Stringy::create($str, $encoding) + ->endsWith($substring, $caseSensitive); + } + + /** + * Converts each tab in the string to some number of spaces, as defined by + * $tabLength. By default, each tab is converted to 4 consecutive spaces. + * + * @param string $str String to convert tabs to spaces + * @param int $tabLength Number of spaces to replace each tab with + * @return string String with tabs switched to spaces + */ + public static function toSpaces($str, $tabLength = 4) + { + return (string) Stringy::create($str)->toSpaces($tabLength); + } + + /** + * Converts each occurrence of some consecutive number of spaces, as + * defined by $tabLength, to a tab. By default, each 4 consecutive spaces + * are converted to a tab. + * + * @param string $str String to convert spaces to tabs + * @param int $tabLength Number of spaces to replace with a tab + * @return string String with spaces switched to tabs + */ + public static function toTabs($str, $tabLength = 4) + { + return (string) Stringy::create($str)->toTabs($tabLength); + } + + /** + * Converts all characters in the string to lowercase. An alias for PHP's + * mb_strtolower(). + * + * @param string $str String to convert case + * @param string $encoding The character encoding + * @return string The lowercase string + */ + public static function toLowerCase($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->toLowerCase(); + } + + /** + * Converts the first character of each word in the string to uppercase. + * + * @param string $str String to convert case + * @param string $encoding The character encoding + * @return string The title-cased string + */ + public static function toTitleCase($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->toTitleCase(); + } + + /** + * Converts all characters in the string to uppercase. An alias for PHP's + * mb_strtoupper(). + * + * @param string $str String to convert case + * @param string $encoding The character encoding + * @return string The uppercase string + */ + public static function toUpperCase($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->toUpperCase(); + } + + /** + * Converts the string into an URL slug. This includes replacing non-ASCII + * characters with their closest ASCII equivalents, removing remaining + * non-ASCII and non-alphanumeric characters, and replacing whitespace with + * $replacement. The replacement defaults to a single dash, and the string + * is also converted to lowercase. + * + * @param string $str Text to transform into an URL slug + * @param string $replacement The string used to replace whitespace + * @return string The corresponding URL slug + */ + public static function slugify($str, $replacement = '-') + { + return (string) Stringy::create($str)->slugify($replacement); + } + + /** + * Returns true if the string contains $needle, false otherwise. By default, + * the comparison is case-sensitive, but can be made insensitive by setting + * $caseSensitive to false. + * + * @param string $haystack String being checked + * @param string $needle Substring to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @param string $encoding The character encoding + * @return bool Whether or not $haystack contains $needle + */ + public static function contains($haystack, $needle, $caseSensitive = true, + $encoding = null) + { + return Stringy::create($haystack, $encoding) + ->contains($needle, $caseSensitive); + } + + /** + * Returns true if the string contains any $needles, false otherwise. By + * default, the comparison is case-sensitive, but can be made insensitive + * by setting $caseSensitive to false. + * + * @param string $haystack String being checked + * @param array $needles Substrings to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @param string $encoding The character encoding + * @return bool Whether or not $haystack contains any $needles + */ + public static function containsAny($haystack, $needles, + $caseSensitive = true, $encoding = null) + { + return Stringy::create($haystack, $encoding) + ->containsAny($needles, $caseSensitive); + } + + /** + * Returns true if the string contains all $needles, false otherwise. By + * default, the comparison is case-sensitive, but can be made insensitive + * by setting $caseSensitive to false. + * + * @param string $haystack String being checked + * @param array $needles Substrings to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @param string $encoding The character encoding + * @return bool Whether or not $haystack contains all $needles + */ + public static function containsAll($haystack, $needles, + $caseSensitive = true, $encoding = null) + { + return Stringy::create($haystack, $encoding) + ->containsAll($needles, $caseSensitive); + } + + /** + * Returns the index of the first occurrence of $needle in the string, + * and false if not found. Accepts an optional offset from which to begin + * the search. + * + * @param string $haystack String to search + * @param string $needle Substring to look for + * @param int $offset Offset from which to search + * @return int|bool The occurrence's index if found, otherwise false + */ + public static function indexOf($haystack, $needle, $offset = 0, + $encoding = null) + { + return Stringy::create($haystack, $encoding) + ->indexOf($needle, $offset); + } + + /** + * Returns the index of the last occurrence of $needle in the string, + * and false if not found. Accepts an optional offset from which to begin + * the search. + * + * @param string $haystack String to search + * @param string $needle Substring to look for + * @param int $offset Offset from which to search + * @return int|bool The last occurrence's index if found, otherwise false + */ + public static function indexOfLast($haystack, $needle, $offset = 0, + $encoding = null) + { + return Stringy::create($haystack, $encoding) + ->indexOfLast($needle, $offset); + } + + /** + * Surrounds a string with the given substring. + * + * @param string $str The string to surround + * @param string $substring The substring to add to both sides + * @return string The string with the substring prepended and appended + */ + public static function surround($str, $substring) + { + return (string) Stringy::create($str)->surround($substring); + } + + /** + * Inserts $substring into the string at the $index provided. + * + * @param string $str String to insert into + * @param string $substring String to be inserted + * @param int $index The index at which to insert the substring + * @param string $encoding The character encoding + * @return string The resulting string after the insertion + */ + public static function insert($str, $substring, $index, $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->insert($substring, $index); + } + + /** + * Truncates the string to a given length. If $substring is provided, and + * truncating occurs, the string is further truncated so that the substring + * may be appended without exceeding the desired length. + * + * @param string $str String to truncate + * @param int $length Desired length of the truncated string + * @param string $substring The substring to append if it can fit + * @param string $encoding The character encoding + * @return string The resulting string after truncating + */ + public static function truncate($str, $length, $substring = '', + $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->truncate($length, $substring); + } + + /** + * Truncates the string to a given length, while ensuring that it does not + * split words. If $substring is provided, and truncating occurs, the + * string is further truncated so that the substring may be appended without + * exceeding the desired length. + * + * @param string $str String to truncate + * @param int $length Desired length of the truncated string + * @param string $substring The substring to append if it can fit + * @param string $encoding The character encoding + * @return string The resulting string after truncating + */ + public static function safeTruncate($str, $length, $substring = '', + $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->safeTruncate($length, $substring); + } + + /** + * Returns a reversed string. A multibyte version of strrev(). + * + * @param string $str String to reverse + * @param string $encoding The character encoding + * @return string The reversed string + */ + public static function reverse($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->reverse(); + } + + /** + * A multibyte str_shuffle() function. It returns a string with its + * characters in random order. + * + * @param string $str String to shuffle + * @param string $encoding The character encoding + * @return string The shuffled string + */ + public static function shuffle($str, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->shuffle(); + } + + /** + * Returns a string with whitespace removed from the start and end of the + * string. Supports the removal of unicode whitespace. Accepts an optional + * string of characters to strip instead of the defaults. + * + * @param string $str String to trim + * @param string $chars Optional string of characters to strip + * @param string $encoding The character encoding + * @return string Trimmed $str + */ + public static function trim($str, $chars = null, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->trim($chars); + } + + /** + * Returns a string with whitespace removed from the start of the string. + * Supports the removal of unicode whitespace. Accepts an optional + * string of characters to strip instead of the defaults. + * + * @param string $str String to trim + * @param string $chars Optional string of characters to strip + * @param string $encoding The character encoding + * @return string Trimmed $str + */ + public static function trimLeft($str, $chars = null, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->trimLeft($chars); + } + + /** + * Returns a string with whitespace removed from the end of the string. + * Supports the removal of unicode whitespace. Accepts an optional + * string of characters to strip instead of the defaults. + * + * @param string $str String to trim + * @param string $chars Optional string of characters to strip + * @param string $encoding The character encoding + * @return string Trimmed $str + */ + public static function trimRight($str, $chars = null, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->trimRight($chars); + } + + /** + * Returns the longest common prefix between the string and $otherStr. + * + * @param string $str First string for comparison + * @param string $otherStr Second string for comparison + * @param string $encoding The character encoding + * @return string The longest common prefix + */ + public static function longestCommonPrefix($str, $otherStr, $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->longestCommonPrefix($otherStr); + } + + /** + * Returns the longest common suffix between the string and $otherStr. + * + * @param string $str First string for comparison + * @param string $otherStr Second string for comparison + * @param string $encoding The character encoding + * @return string The longest common suffix + */ + public static function longestCommonSuffix($str, $otherStr, $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->longestCommonSuffix($otherStr); + } + + /** + * Returns the longest common substring between the string and $otherStr. + * In the case of ties, it returns that which occurs first. + * + * @param string $str First string for comparison + * @param string $otherStr Second string for comparison + * @param string $encoding The character encoding + * @return string The longest common substring + */ + public static function longestCommonSubstring($str, $otherStr, + $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->longestCommonSubstring($otherStr); + } + + /** + * Returns the length of the string. An alias for PHP's mb_strlen() function. + * + * @param string $str The string to get the length of + * @param string $encoding The character encoding + * @return int The number of characters in $str given the encoding + */ + public static function length($str, $encoding = null) + { + return Stringy::create($str, $encoding)->length(); + } + + /** + * Returns the substring beginning at $start with the specified $length. + * It differs from the mb_substr() function in that providing a $length of + * null will return the rest of the string, rather than an empty string. + * + * @param string $str The string to get the length of + * @param int $start Position of the first character to use + * @param int $length Maximum number of characters used + * @param string $encoding The character encoding + * @return string The substring of $str + */ + public static function substr($str, $start, $length = null, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->substr($start, $length); + } + + /** + * Returns the character at $index, with indexes starting at 0. + * + * @param string $str The string from which to get the char + * @param int $index Position of the character + * @param string $encoding The character encoding + * @return string The character at $index + */ + public static function at($str, $index, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->at($index); + } + + /** + * Returns the first $n characters of the string. + * + * @param string $str The string from which to get the substring + * @param int $n Number of chars to retrieve from the start + * @param string $encoding The character encoding + * @return string The first $n characters + */ + public static function first($str, $n, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->first($n); + } + + /** + * Returns the last $n characters of the string. + * + * @param string $str The string from which to get the substring + * @param int $n Number of chars to retrieve from the end + * @param string $encoding The character encoding + * @return string The last $n characters + */ + public static function last($str, $n, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->last($n); + } + + /** + * Ensures that the string begins with $substring. If it doesn't, it's + * prepended. + * + * @param string $str The string to modify + * @param string $substring The substring to add if not present + * @param string $encoding The character encoding + * @return string The string prefixed by the $substring + */ + public static function ensureLeft($str, $substring, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->ensureLeft($substring); + } + + /** + * Ensures that the string begins with $substring. If it doesn't, it's + * appended. + * + * @param string $str The string to modify + * @param string $substring The substring to add if not present + * @param string $encoding The character encoding + * @return string The string suffixed by the $substring + */ + public static function ensureRight($str, $substring, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->ensureRight($substring); + } + + /** + * Returns a new string with the prefix $substring removed, if present. + * + * @param string $str String from which to remove the prefix + * @param string $substring The prefix to remove + * @param string $encoding The character encoding + * @return string The string without the prefix $substring + */ + public static function removeLeft($str, $substring, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->removeLeft($substring); + } + + /** + * Returns a new string with the suffix $substring removed, if present. + * + * @param string $str String from which to remove the suffix + * @param string $substring The suffix to remove + * @param string $encoding The character encoding + * @return string The string without the suffix $substring + */ + public static function removeRight($str, $substring, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->removeRight($substring); + } + + /** + * Returns true if the string contains a lower case char, false + * otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str contains a lower case character. + */ + public static function hasLowerCase($str, $encoding = null) + { + return Stringy::create($str, $encoding)->hasLowerCase(); + } + + /** + * Returns true if the string contains an upper case char, false + * otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str contains an upper case character. + */ + public static function hasUpperCase($str, $encoding = null) + { + return Stringy::create($str, $encoding)->hasUpperCase(); + } + + /** + * Returns true if the string contains only alphabetic chars, false + * otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str contains only alphabetic chars + */ + public static function isAlpha($str, $encoding = null) + { + return Stringy::create($str, $encoding)->isAlpha(); + } + + /** + * Returns true if the string contains only alphabetic and numeric chars, + * false otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str contains only alphanumeric chars + */ + public static function isAlphanumeric($str, $encoding = null) + { + return Stringy::create($str, $encoding)->isAlphanumeric(); + } + + /** + * Returns true if the string contains only whitespace chars, false + * otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str contains only whitespace characters + */ + public static function isBlank($str, $encoding = null) + { + return Stringy::create($str, $encoding)->isBlank(); + } + + /** + * Returns true if the string is JSON, false otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str is JSON + */ + public static function isJson($str, $encoding = null) + { + return Stringy::create($str, $encoding)->isJson(); + } + + /** + * Returns true if the string contains only lower case chars, false + * otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str contains only lower case characters + */ + public static function isLowerCase($str, $encoding = null) + { + return Stringy::create($str, $encoding)->isLowerCase(); + } + + /** + * Returns true if the string is serialized, false otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str is serialized + */ + public static function isSerialized($str, $encoding = null) + { + return Stringy::create($str, $encoding)->isSerialized(); + } + + /** + * Returns true if the string contains only upper case chars, false + * otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str contains only upper case characters + */ + public static function isUpperCase($str, $encoding = null) + { + return Stringy::create($str, $encoding)->isUpperCase(); + } + + /** + * Returns true if the string contains only hexadecimal chars, false + * otherwise. + * + * @param string $str String to check + * @param string $encoding The character encoding + * @return bool Whether or not $str contains only hexadecimal characters + */ + public static function isHexadecimal($str, $encoding = null) + { + return Stringy::create($str, $encoding)->isHexadecimal(); + } + + /** + * Returns the number of occurrences of $substring in the given string. + * By default, the comparison is case-sensitive, but can be made insensitive + * by setting $caseSensitive to false. + * + * @param string $str The string to search through + * @param string $substring The substring to search for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @param string $encoding The character encoding + * @return int The number of $substring occurrences + */ + public static function countSubstr($str, $substring, $caseSensitive = true, + $encoding = null) + { + return Stringy::create($str, $encoding) + ->countSubstr($substring, $caseSensitive); + } + + /** + * Replaces all occurrences of $search in $str by $replacement. + * + * @param string $str The haystack to search through + * @param string $search The needle to search for + * @param string $replacement The string to replace with + * @param string $encoding The character encoding + * @return string The resulting string after the replacements + */ + public static function replace($str, $search, $replacement, $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->replace($search, $replacement); + } + + /** + * Replaces all occurrences of $pattern in $str by $replacement. An alias + * for mb_ereg_replace(). Note that the 'i' option with multibyte patterns + * in mb_ereg_replace() requires PHP 5.4+. This is due to a lack of support + * in the bundled version of Oniguruma in PHP 5.3. + * + * @param string $str The haystack to search through + * @param string $pattern The regular expression pattern + * @param string $replacement The string to replace with + * @param string $options Matching conditions to be used + * @param string $encoding The character encoding + * @return string The resulting string after the replacements + */ + public static function regexReplace($str, $pattern, $replacement, + $options = 'msr', $encoding = null) + { + return (string) Stringy::create($str, $encoding) + ->regexReplace($pattern, $replacement, $options, $encoding); + } + + /** + * Convert all applicable characters to HTML entities. + * + * @param string $str The string to encode. + * @param int|null $flags See http://php.net/manual/en/function.htmlentities.php + * @param string $encoding The character encoding + * @return Stringy Object with the resulting $str after being html encoded. + */ + public static function htmlEncode($str, $flags = ENT_COMPAT, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->htmlEncode($flags); + } + + /** + * Convert all HTML entities to their applicable characters. + * + * @param string $str The string to decode. + * @param int|null $flags See http://php.net/manual/en/function.html-entity-decode.php + * @param string $encoding The character encoding + * @return Stringy Object with the resulting $str after being html decoded. + */ + public static function htmlDecode($str, $flags = ENT_COMPAT, $encoding = null) + { + return (string) Stringy::create($str, $encoding)->htmlDecode($flags); + } +} diff --git a/vendor/danielstjules/stringy/src/Stringy.php b/vendor/danielstjules/stringy/src/Stringy.php new file mode 100644 index 0000000..60b0694 --- /dev/null +++ b/vendor/danielstjules/stringy/src/Stringy.php @@ -0,0 +1,1558 @@ +str = (string) $str; + $this->encoding = $encoding ?: mb_internal_encoding(); + } + + /** + * Creates a Stringy object and assigns both str and encoding properties + * the supplied values. $str is cast to a string prior to assignment, and if + * $encoding is not specified, it defaults to mb_internal_encoding(). It + * then returns the initialized object. Throws an InvalidArgumentException + * if the first argument is an array or object without a __toString method. + * + * @param mixed $str Value to modify, after being cast to string + * @param string $encoding The character encoding + * @return Stringy A Stringy object + * @throws \InvalidArgumentException if an array or object without a + * __toString method is passed as the first argument + */ + public static function create($str, $encoding = null) + { + return new static($str, $encoding); + } + + /** + * Returns the value in $str. + * + * @return string The current value of the $str property + */ + public function __toString() + { + return $this->str; + } + + /** + * Returns the encoding used by the Stringy object. + * + * @return string The current value of the $encoding property + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * Returns the length of the string, implementing the countable interface. + * + * @return int The number of characters in the string, given the encoding + */ + public function count() + { + return $this->length(); + } + + /** + * Returns a new ArrayIterator, thus implementing the IteratorAggregate + * interface. The ArrayIterator's constructor is passed an array of chars + * in the multibyte string. This enables the use of foreach with instances + * of Stringy\Stringy. + * + * @return \ArrayIterator An iterator for the characters in the string + */ + public function getIterator() + { + return new \ArrayIterator($this->chars()); + } + + /** + * Returns whether or not a character exists at an index. Offsets may be + * negative to count from the last character in the string. Implements + * part of the ArrayAccess interface. + * + * @param mixed $offset The index to check + * @return boolean Whether or not the index exists + */ + public function offsetExists($offset) + { + $length = $this->length(); + $offset = (int) $offset; + + if ($offset >= 0) { + return ($length > $offset); + } + + return ($length >= abs($offset)); + } + + /** + * Returns the character at the given index. Offsets may be negative to + * count from the last character in the string. Implements part of the + * ArrayAccess interface, and throws an OutOfBoundsException if the index + * does not exist. + * + * @param mixed $offset The index from which to retrieve the char + * @return mixed The character at the specified index + * @throws \OutOfBoundsException If the positive or negative offset does + * not exist + */ + public function offsetGet($offset) + { + $offset = (int) $offset; + $length = $this->length(); + + if (($offset >= 0 && $length <= $offset) || $length < abs($offset)) { + throw new \OutOfBoundsException('No character exists at the index'); + } + + return mb_substr($this->str, $offset, 1, $this->encoding); + } + + /** + * Implements part of the ArrayAccess interface, but throws an exception + * when called. This maintains the immutability of Stringy objects. + * + * @param mixed $offset The index of the character + * @param mixed $value Value to set + * @throws \Exception When called + */ + public function offsetSet($offset, $value) + { + // Stringy is immutable, cannot directly set char + throw new \Exception('Stringy object is immutable, cannot modify char'); + } + + /** + * Implements part of the ArrayAccess interface, but throws an exception + * when called. This maintains the immutability of Stringy objects. + * + * @param mixed $offset The index of the character + * @throws \Exception When called + */ + public function offsetUnset($offset) + { + // Don't allow directly modifying the string + throw new \Exception('Stringy object is immutable, cannot unset char'); + } + + /** + * Returns an array consisting of the characters in the string. + * + * @return array An array of string chars + */ + public function chars() + { + $chars = array(); + for ($i = 0, $l = $this->length(); $i < $l; $i++) { + $chars[] = $this->at($i)->str; + } + + return $chars; + } + + /** + * Converts the first character of the supplied string to upper case. + * + * @return Stringy Object with the first character of $str being upper case + */ + public function upperCaseFirst() + { + $first = mb_substr($this->str, 0, 1, $this->encoding); + $rest = mb_substr($this->str, 1, $this->length() - 1, + $this->encoding); + + $str = mb_strtoupper($first, $this->encoding) . $rest; + + return static::create($str, $this->encoding); + } + + /** + * Converts the first character of the string to lower case. + * + * @return Stringy Object with the first character of $str being lower case + */ + public function lowerCaseFirst() + { + $first = mb_substr($this->str, 0, 1, $this->encoding); + $rest = mb_substr($this->str, 1, $this->length() - 1, + $this->encoding); + + $str = mb_strtolower($first, $this->encoding) . $rest; + + return static::create($str, $this->encoding); + } + + /** + * Returns a camelCase version of the string. Trims surrounding spaces, + * capitalizes letters following digits, spaces, dashes and underscores, + * and removes spaces, dashes, as well as underscores. + * + * @return Stringy Object with $str in camelCase + */ + public function camelize() + { + $encoding = $this->encoding; + $stringy = $this->trim()->lowerCaseFirst(); + + $camelCase = preg_replace_callback( + '/[-_\s]+(.)?/u', + function ($match) use ($encoding) { + return $match[1] ? mb_strtoupper($match[1], $encoding) : ''; + }, + $stringy->str + ); + + $stringy->str = preg_replace_callback( + '/[\d]+(.)?/u', + function ($match) use ($encoding) { + return mb_strtoupper($match[0], $encoding); + }, + $camelCase + ); + + return $stringy; + } + + /** + * Returns an UpperCamelCase version of the supplied string. It trims + * surrounding spaces, capitalizes letters following digits, spaces, dashes + * and underscores, and removes spaces, dashes, underscores. + * + * @return Stringy Object with $str in UpperCamelCase + */ + public function upperCamelize() + { + return $this->camelize()->upperCaseFirst(); + } + + /** + * Returns a lowercase and trimmed string separated by dashes. Dashes are + * inserted before uppercase characters (with the exception of the first + * character of the string), and in place of spaces as well as underscores. + * + * @return Stringy Object with a dasherized $str + */ + public function dasherize() + { + return $this->delimit('-'); + } + + /** + * Returns a lowercase and trimmed string separated by underscores. + * Underscores are inserted before uppercase characters (with the exception + * of the first character of the string), and in place of spaces as well as + * dashes. + * + * @return Stringy Object with an underscored $str + */ + public function underscored() + { + return $this->delimit('_'); + } + + /** + * Returns a lowercase and trimmed string separated by the given delimiter. + * Delimiters are inserted before uppercase characters (with the exception + * of the first character of the string), and in place of spaces, dashes, + * and underscores. Alpha delimiters are not converted to lowercase. + * + * @param string $delimiter Sequence used to separate parts of the string + * @return Stringy Object with a delimited $str + */ + public function delimit($delimiter) + { + // Save current regex encoding so we can reset it after + $regexEncoding = mb_regex_encoding(); + mb_regex_encoding($this->encoding); + + $str = mb_ereg_replace('\B([A-Z])', '-\1', $this->trim()); + $str = mb_strtolower($str, $this->encoding); + $str = mb_ereg_replace('[-_\s]+', $delimiter, $str); + + mb_regex_encoding($regexEncoding); + + return static::create($str, $this->encoding); + } + + /** + * Returns a case swapped version of the string. + * + * @return Stringy Object whose $str has each character's case swapped + */ + public function swapCase() + { + $stringy = static::create($this->str, $this->encoding); + $encoding = $stringy->encoding; + + $stringy->str = preg_replace_callback( + '/[\S]/u', + function ($match) use ($encoding) { + if ($match[0] == mb_strtoupper($match[0], $encoding)) { + return mb_strtolower($match[0], $encoding); + } else { + return mb_strtoupper($match[0], $encoding); + } + }, + $stringy->str + ); + + return $stringy; + } + + /** + * Returns a trimmed string with the first letter of each word capitalized. + * Ignores the case of other letters, preserving any acronyms. Also accepts + * an array, $ignore, allowing you to list words not to be capitalized. + * + * @param array $ignore An array of words not to capitalize + * @return Stringy Object with a titleized $str + */ + public function titleize($ignore = null) + { + $buffer = $this->trim(); + $encoding = $this->encoding; + + $buffer = preg_replace_callback( + '/([\S]+)/u', + function ($match) use ($encoding, $ignore) { + if ($ignore && in_array($match[0], $ignore)) { + return $match[0]; + } else { + $stringy = new Stringy($match[0], $encoding); + return (string) $stringy->upperCaseFirst(); + } + }, + $buffer + ); + + return new Stringy($buffer, $encoding); + } + + /** + * Capitalizes the first word of the string, replaces underscores with + * spaces, and strips '_id'. + * + * @return Stringy Object with a humanized $str + */ + public function humanize() + { + $str = str_replace(array('_id', '_'), array('', ' '), $this->str); + + return static::create($str, $this->encoding)->trim()->upperCaseFirst(); + } + + /** + * Returns a string with smart quotes, ellipsis characters, and dashes from + * Windows-1252 (commonly used in Word documents) replaced by their ASCII + * equivalents. + * + * @return Stringy Object whose $str has those characters removed + */ + public function tidy() + { + $str = preg_replace(array( + '/\x{2026}/u', + '/[\x{201C}\x{201D}]/u', + '/[\x{2018}\x{2019}]/u', + '/[\x{2013}\x{2014}]/u', + ), array( + '...', + '"', + "'", + '-', + ), $this->str); + + return static::create($str, $this->encoding); + } + + /** + * Trims the string and replaces consecutive whitespace characters with a + * single space. This includes tabs and newline characters, as well as + * multibyte whitespace such as the thin space and ideographic space. + * + * @return Stringy Object with a trimmed $str and condensed whitespace + */ + public function collapseWhitespace() + { + return $this->regexReplace('[[:space:]]+', ' ')->trim(); + } + + /** + * Returns an ASCII version of the string. A set of non-ASCII characters are + * replaced with their closest ASCII counterparts, and the rest are removed + * unless instructed otherwise. + * + * @param bool $removeUnsupported Whether or not to remove the + * unsupported characters + * @return Stringy Object whose $str contains only ASCII characters + */ + public function toAscii($removeUnsupported = true) + { + $str = $this->str; + + foreach ($this->charsArray() as $key => $value) { + $str = str_replace($value, $key, $str); + } + + if ($removeUnsupported) { + $str = preg_replace('/[^\x20-\x7E]/u', '', $str); + } + + return static::create($str, $this->encoding); + } + + /** + * Returns the replacements for the toAscii() method. + * + * @return array An array of replacements. + */ + protected function charsArray() + { + static $charsArray; + if (isset($charsArray)) return $charsArray; + + return $charsArray = array( + 'a' => array( + 'à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ', + 'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ä', 'ā', 'ą', + 'å', 'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ', + 'ἇ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ', + 'ά', 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ'), + 'b' => array('б', 'β', 'Ъ', 'Ь', 'ب'), + 'c' => array('ç', 'ć', 'č', 'ĉ', 'ċ'), + 'd' => array('ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', + 'д', 'δ', 'د', 'ض'), + 'e' => array('é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ', + 'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ', + 'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э', + 'є', 'ə'), + 'f' => array('ф', 'φ', 'ف'), + 'g' => array('ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ج'), + 'h' => array('ĥ', 'ħ', 'η', 'ή', 'ح', 'ه'), + 'i' => array('í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į', + 'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ', + 'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ', + 'ῗ', 'і', 'ї', 'и'), + 'j' => array('ĵ', 'ј', 'Ј'), + 'k' => array('ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك'), + 'l' => array('ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل'), + 'm' => array('м', 'μ', 'م'), + 'n' => array('ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن'), + 'o' => array('ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ', + 'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő', + 'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό', + 'ö', 'о', 'و', 'θ'), + 'p' => array('п', 'π'), + 'r' => array('ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر'), + 's' => array('ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص'), + 't' => array('ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط'), + 'u' => array('ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ', + 'ự', 'ü', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у'), + 'v' => array('в'), + 'w' => array('ŵ', 'ω', 'ώ'), + 'x' => array('χ'), + 'y' => array('ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', + 'ϋ', 'ύ', 'ΰ', 'ي'), + 'z' => array('ź', 'ž', 'ż', 'з', 'ζ', 'ز'), + 'aa' => array('ع'), + 'ae' => array('æ'), + 'ch' => array('ч'), + 'dj' => array('ђ', 'đ'), + 'dz' => array('џ'), + 'gh' => array('غ'), + 'kh' => array('х', 'خ'), + 'lj' => array('љ'), + 'nj' => array('њ'), + 'oe' => array('œ'), + 'ps' => array('ψ'), + 'sh' => array('ш'), + 'shch' => array('щ'), + 'ss' => array('ß'), + 'th' => array('þ', 'ث', 'ذ', 'ظ'), + 'ts' => array('ц'), + 'ya' => array('я'), + 'yu' => array('ю'), + 'zh' => array('ж'), + '(c)' => array('©'), + 'A' => array('Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ', + 'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Ä', 'Å', 'Ā', + 'Ą', 'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ', + 'Ἇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ', + 'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 'А'), + 'B' => array('Б', 'Β'), + 'C' => array('Ç','Ć', 'Č', 'Ĉ', 'Ċ'), + 'D' => array('Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ'), + 'E' => array('É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ', + 'Ệ', 'Ë', 'Ē', 'Ę', 'Ě', 'Ĕ', 'Ė', 'Ε', 'Έ', 'Ἐ', + 'Ἑ', 'Ἒ', 'Ἓ', 'Ἔ', 'Ἕ', 'Έ', 'Ὲ', 'Е', 'Ё', 'Э', + 'Є', 'Ə'), + 'F' => array('Ф', 'Φ'), + 'G' => array('Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ'), + 'H' => array('Η', 'Ή'), + 'I' => array('Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į', + 'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ', + 'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї'), + 'K' => array('К', 'Κ'), + 'L' => array('Ĺ', 'Ł', 'Л', 'Λ', 'Ļ'), + 'M' => array('М', 'Μ'), + 'N' => array('Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν'), + 'O' => array('Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ', + 'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ö', 'Ø', 'Ō', + 'Ő', 'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ', + 'Ὸ', 'Ό', 'О', 'Θ', 'Ө'), + 'P' => array('П', 'Π'), + 'R' => array('Ř', 'Ŕ', 'Р', 'Ρ'), + 'S' => array('Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ'), + 'T' => array('Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ'), + 'U' => array('Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ', + 'Ự', 'Û', 'Ü', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У'), + 'V' => array('В'), + 'W' => array('Ω', 'Ώ'), + 'X' => array('Χ'), + 'Y' => array('Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', + 'Ы', 'Й', 'Υ', 'Ϋ'), + 'Z' => array('Ź', 'Ž', 'Ż', 'З', 'Ζ'), + 'AE' => array('Æ'), + 'CH' => array('Ч'), + 'DJ' => array('Ђ'), + 'DZ' => array('Џ'), + 'KH' => array('Х'), + 'LJ' => array('Љ'), + 'NJ' => array('Њ'), + 'PS' => array('Ψ'), + 'SH' => array('Ш'), + 'SHCH' => array('Щ'), + 'SS' => array('ẞ'), + 'TH' => array('Þ'), + 'TS' => array('Ц'), + 'YA' => array('Я'), + 'YU' => array('Ю'), + 'ZH' => array('Ж'), + ' ' => array("\xC2\xA0", "\xE2\x80\x80", "\xE2\x80\x81", + "\xE2\x80\x82", "\xE2\x80\x83", "\xE2\x80\x84", + "\xE2\x80\x85", "\xE2\x80\x86", "\xE2\x80\x87", + "\xE2\x80\x88", "\xE2\x80\x89", "\xE2\x80\x8A", + "\xE2\x80\xAF", "\xE2\x81\x9F", "\xE3\x80\x80"), + ); + } + + /** + * Pads the string to a given length with $padStr. If length is less than + * or equal to the length of the string, no padding takes places. The + * default string used for padding is a space, and the default type (one of + * 'left', 'right', 'both') is 'right'. Throws an InvalidArgumentException + * if $padType isn't one of those 3 values. + * + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @param string $padType One of 'left', 'right', 'both' + * @return Stringy Object with a padded $str + * @throws InvalidArgumentException If $padType isn't one of 'right', + * 'left' or 'both' + */ + public function pad($length, $padStr = ' ', $padType = 'right') + { + if (!in_array($padType, array('left', 'right', 'both'))) { + throw new \InvalidArgumentException('Pad expects $padType ' . + "to be one of 'left', 'right' or 'both'"); + } + + switch ($padType) { + case 'left': + return $this->padLeft($length, $padStr); + case 'right': + return $this->padRight($length, $padStr); + default: + return $this->padBoth($length, $padStr); + } + } + + /** + * Returns a new string of a given length such that the beginning of the + * string is padded. Alias for pad() with a $padType of 'left'. + * + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @return Stringy String with left padding + */ + public function padLeft($length, $padStr = ' ') + { + return $this->applyPadding($length - $this->length(), 0, $padStr); + } + + /** + * Returns a new string of a given length such that the end of the string + * is padded. Alias for pad() with a $padType of 'right'. + * + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @return Stringy String with right padding + */ + public function padRight($length, $padStr = ' ') + { + return $this->applyPadding(0, $length - $this->length(), $padStr); + } + + /** + * Returns a new string of a given length such that both sides of the + * string are padded. Alias for pad() with a $padType of 'both'. + * + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @return Stringy String with padding applied + */ + public function padBoth($length, $padStr = ' ') + { + $padding = $length - $this->length(); + + return $this->applyPadding(floor($padding / 2), ceil($padding / 2), + $padStr); + } + + /** + * Adds the specified amount of left and right padding to the given string. + * The default character used is a space. + * + * @param int $left Length of left padding + * @param int $right Length of right padding + * @param string $padStr String used to pad + * @return Stringy String with padding applied + */ + private function applyPadding($left = 0, $right = 0, $padStr = ' ') + { + $stringy = static::create($this->str, $this->encoding); + $length = mb_strlen($padStr, $stringy->encoding); + + $strLength = $stringy->length(); + $paddedLength = $strLength + $left + $right; + + if (!$length || $paddedLength <= $strLength) { + return $stringy; + } + + $leftPadding = mb_substr(str_repeat($padStr, ceil($left / $length)), 0, + $left, $stringy->encoding); + $rightPadding = mb_substr(str_repeat($padStr, ceil($right / $length)), + 0, $right, $stringy->encoding); + + $stringy->str = $leftPadding . $stringy->str . $rightPadding; + + return $stringy; + } + + /** + * Returns true if the string begins with $substring, false otherwise. By + * default, the comparison is case-sensitive, but can be made insensitive + * by setting $caseSensitive to false. + * + * @param string $substring The substring to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @return bool Whether or not $str starts with $substring + */ + public function startsWith($substring, $caseSensitive = true) + { + $substringLength = mb_strlen($substring, $this->encoding); + $startOfStr = mb_substr($this->str, 0, $substringLength, + $this->encoding); + + if (!$caseSensitive) { + $substring = mb_strtolower($substring, $this->encoding); + $startOfStr = mb_strtolower($startOfStr, $this->encoding); + } + + return (string) $substring === $startOfStr; + } + + /** + * Returns true if the string ends with $substring, false otherwise. By + * default, the comparison is case-sensitive, but can be made insensitive + * by setting $caseSensitive to false. + * + * @param string $substring The substring to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @return bool Whether or not $str ends with $substring + */ + public function endsWith($substring, $caseSensitive = true) + { + $substringLength = mb_strlen($substring, $this->encoding); + $strLength = $this->length(); + + $endOfStr = mb_substr($this->str, $strLength - $substringLength, + $substringLength, $this->encoding); + + if (!$caseSensitive) { + $substring = mb_strtolower($substring, $this->encoding); + $endOfStr = mb_strtolower($endOfStr, $this->encoding); + } + + return (string) $substring === $endOfStr; + } + + /** + * Converts each tab in the string to some number of spaces, as defined by + * $tabLength. By default, each tab is converted to 4 consecutive spaces. + * + * @param int $tabLength Number of spaces to replace each tab with + * @return Stringy Object whose $str has had tabs switched to spaces + */ + public function toSpaces($tabLength = 4) + { + $spaces = str_repeat(' ', $tabLength); + $str = str_replace("\t", $spaces, $this->str); + + return static::create($str, $this->encoding); + } + + /** + * Converts each occurrence of some consecutive number of spaces, as + * defined by $tabLength, to a tab. By default, each 4 consecutive spaces + * are converted to a tab. + * + * @param int $tabLength Number of spaces to replace with a tab + * @return Stringy Object whose $str has had spaces switched to tabs + */ + public function toTabs($tabLength = 4) + { + $spaces = str_repeat(' ', $tabLength); + $str = str_replace($spaces, "\t", $this->str); + + return static::create($str, $this->encoding); + } + + /** + * Converts the first character of each word in the string to uppercase. + * + * @return Stringy Object with all characters of $str being title-cased + */ + public function toTitleCase() + { + $str = mb_convert_case($this->str, MB_CASE_TITLE, $this->encoding); + + return static::create($str, $this->encoding); + } + + /** + * Converts all characters in the string to lowercase. An alias for PHP's + * mb_strtolower(). + * + * @return Stringy Object with all characters of $str being lowercase + */ + public function toLowerCase() + { + $str = mb_strtolower($this->str, $this->encoding); + + return static::create($str, $this->encoding); + } + + /** + * Converts all characters in the string to uppercase. An alias for PHP's + * mb_strtoupper(). + * + * @return Stringy Object with all characters of $str being uppercase + */ + public function toUpperCase() + { + $str = mb_strtoupper($this->str, $this->encoding); + + return static::create($str, $this->encoding); + } + + /** + * Converts the string into an URL slug. This includes replacing non-ASCII + * characters with their closest ASCII equivalents, removing remaining + * non-ASCII and non-alphanumeric characters, and replacing whitespace with + * $replacement. The replacement defaults to a single dash, and the string + * is also converted to lowercase. + * + * @param string $replacement The string used to replace whitespace + * @return Stringy Object whose $str has been converted to an URL slug + */ + public function slugify($replacement = '-') + { + $stringy = $this->toAscii(); + + $quotedReplacement = preg_quote($replacement); + $pattern = "/[^a-zA-Z\d\s-_$quotedReplacement]/u"; + $stringy->str = preg_replace($pattern, '', $stringy); + + return $stringy->toLowerCase()->delimit($replacement) + ->removeLeft($replacement)->removeRight($replacement); + } + + /** + * Returns true if the string contains $needle, false otherwise. By default + * the comparison is case-sensitive, but can be made insensitive by setting + * $caseSensitive to false. + * + * @param string $needle Substring to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @return bool Whether or not $str contains $needle + */ + public function contains($needle, $caseSensitive = true) + { + $encoding = $this->encoding; + + if ($caseSensitive) { + return (mb_strpos($this->str, $needle, 0, $encoding) !== false); + } else { + return (mb_stripos($this->str, $needle, 0, $encoding) !== false); + } + } + + /** + * Returns true if the string contains any $needles, false otherwise. By + * default the comparison is case-sensitive, but can be made insensitive by + * setting $caseSensitive to false. + * + * @param array $needles Substrings to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @return bool Whether or not $str contains $needle + */ + public function containsAny($needles, $caseSensitive = true) + { + if (empty($needles)) { + return false; + } + + foreach ($needles as $needle) { + if ($this->contains($needle, $caseSensitive)) { + return true; + } + } + + return false; + } + + /** + * Returns true if the string contains all $needles, false otherwise. By + * default the comparison is case-sensitive, but can be made insensitive by + * setting $caseSensitive to false. + * + * @param array $needles Substrings to look for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @return bool Whether or not $str contains $needle + */ + public function containsAll($needles, $caseSensitive = true) + { + if (empty($needles)) { + return false; + } + + foreach ($needles as $needle) { + if (!$this->contains($needle, $caseSensitive)) { + return false; + } + } + + return true; + } + + /** + * Returns the index of the first occurrence of $needle in the string, + * and false if not found. Accepts an optional offset from which to begin + * the search. + * + * @param string $needle Substring to look for + * @param int $offset Offset from which to search + * @return int|bool The occurrence's index if found, otherwise false + */ + public function indexOf($needle, $offset = 0) + { + return mb_strpos($this->str, (string) $needle, + (int) $offset, $this->encoding); + } + + /** + * Returns the index of the last occurrence of $needle in the string, + * and false if not found. Accepts an optional offset from which to begin + * the search. + * + * @param string $needle Substring to look for + * @param int $offset Offset from which to search + * @return int|bool The last occurrence's index if found, otherwise false + */ + public function indexOfLast($needle, $offset = 0) + { + return mb_strrpos($this->str, (string) $needle, + (int) $offset, $this->encoding); + } + + /** + * Surrounds $str with the given substring. + * + * @param string $substring The substring to add to both sides + * @return Stringy Object whose $str had the substring both prepended and + * appended + */ + public function surround($substring) + { + $str = implode('', array($substring, $this->str, $substring)); + + return static::create($str, $this->encoding); + } + + /** + * Inserts $substring into the string at the $index provided. + * + * @param string $substring String to be inserted + * @param int $index The index at which to insert the substring + * @return Stringy Object with the resulting $str after the insertion + */ + public function insert($substring, $index) + { + $stringy = static::create($this->str, $this->encoding); + if ($index > $stringy->length()) { + return $stringy; + } + + $start = mb_substr($stringy->str, 0, $index, $stringy->encoding); + $end = mb_substr($stringy->str, $index, $stringy->length(), + $stringy->encoding); + + $stringy->str = $start . $substring . $end; + + return $stringy; + } + + /** + * Truncates the string to a given length. If $substring is provided, and + * truncating occurs, the string is further truncated so that the substring + * may be appended without exceeding the desired length. + * + * @param int $length Desired length of the truncated string + * @param string $substring The substring to append if it can fit + * @return Stringy Object with the resulting $str after truncating + */ + public function truncate($length, $substring = '') + { + $stringy = static::create($this->str, $this->encoding); + if ($length >= $stringy->length()) { + return $stringy; + } + + // Need to further trim the string so we can append the substring + $substringLength = mb_strlen($substring, $stringy->encoding); + $length = $length - $substringLength; + + $truncated = mb_substr($stringy->str, 0, $length, $stringy->encoding); + $stringy->str = $truncated . $substring; + + return $stringy; + } + + /** + * Truncates the string to a given length, while ensuring that it does not + * split words. If $substring is provided, and truncating occurs, the + * string is further truncated so that the substring may be appended without + * exceeding the desired length. + * + * @param int $length Desired length of the truncated string + * @param string $substring The substring to append if it can fit + * @return Stringy Object with the resulting $str after truncating + */ + public function safeTruncate($length, $substring = '') + { + $stringy = static::create($this->str, $this->encoding); + if ($length >= $stringy->length()) { + return $stringy; + } + + // Need to further trim the string so we can append the substring + $encoding = $stringy->encoding; + $substringLength = mb_strlen($substring, $encoding); + $length = $length - $substringLength; + + $truncated = mb_substr($stringy->str, 0, $length, $encoding); + + // If the last word was truncated + if (mb_strpos($stringy->str, ' ', $length - 1, $encoding) != $length) { + // Find pos of the last occurrence of a space, get up to that + $lastPos = mb_strrpos($truncated, ' ', 0, $encoding); + $truncated = mb_substr($truncated, 0, $lastPos, $encoding); + } + + $stringy->str = $truncated . $substring; + + return $stringy; + } + + /** + * Returns a reversed string. A multibyte version of strrev(). + * + * @return Stringy Object with a reversed $str + */ + public function reverse() + { + $strLength = $this->length(); + $reversed = ''; + + // Loop from last index of string to first + for ($i = $strLength - 1; $i >= 0; $i--) { + $reversed .= mb_substr($this->str, $i, 1, $this->encoding); + } + + return static::create($reversed, $this->encoding); + } + + /** + * A multibyte str_shuffle() function. It returns a string with its + * characters in random order. + * + * @return Stringy Object with a shuffled $str + */ + public function shuffle() + { + $indexes = range(0, $this->length() - 1); + shuffle($indexes); + + $shuffledStr = ''; + foreach ($indexes as $i) { + $shuffledStr .= mb_substr($this->str, $i, 1, $this->encoding); + } + + return static::create($shuffledStr, $this->encoding); + } + + /** + * Returns a string with whitespace removed from the start and end of the + * string. Supports the removal of unicode whitespace. Accepts an optional + * string of characters to strip instead of the defaults. + * + * @param string $chars Optional string of characters to strip + * @return Stringy Object with a trimmed $str + */ + public function trim($chars = null) + { + $chars = ($chars) ? preg_quote($chars) : '[:space:]'; + + return $this->regexReplace("^[$chars]+|[$chars]+\$", ''); + } + + /** + * Returns a string with whitespace removed from the start of the string. + * Supports the removal of unicode whitespace. Accepts an optional + * string of characters to strip instead of the defaults. + * + * @param string $chars Optional string of characters to strip + * @return Stringy Object with a trimmed $str + */ + public function trimLeft($chars = null) + { + $chars = ($chars) ? preg_quote($chars) : '[:space:]'; + + return $this->regexReplace("^[$chars]+", ''); + } + + /** + * Returns a string with whitespace removed from the end of the string. + * Supports the removal of unicode whitespace. Accepts an optional + * string of characters to strip instead of the defaults. + * + * @param string $chars Optional string of characters to strip + * @return Stringy Object with a trimmed $str + */ + public function trimRight($chars = null) + { + $chars = ($chars) ? preg_quote($chars) : '[:space:]'; + + return $this->regexReplace("[$chars]+\$", ''); + } + + /** + * Returns the longest common prefix between the string and $otherStr. + * + * @param string $otherStr Second string for comparison + * @return Stringy Object with its $str being the longest common prefix + */ + public function longestCommonPrefix($otherStr) + { + $encoding = $this->encoding; + $maxLength = min($this->length(), mb_strlen($otherStr, $encoding)); + + $longestCommonPrefix = ''; + for ($i = 0; $i < $maxLength; $i++) { + $char = mb_substr($this->str, $i, 1, $encoding); + + if ($char == mb_substr($otherStr, $i, 1, $encoding)) { + $longestCommonPrefix .= $char; + } else { + break; + } + } + + return static::create($longestCommonPrefix, $encoding); + } + + /** + * Returns the longest common suffix between the string and $otherStr. + * + * @param string $otherStr Second string for comparison + * @return Stringy Object with its $str being the longest common suffix + */ + public function longestCommonSuffix($otherStr) + { + $encoding = $this->encoding; + $maxLength = min($this->length(), mb_strlen($otherStr, $encoding)); + + $longestCommonSuffix = ''; + for ($i = 1; $i <= $maxLength; $i++) { + $char = mb_substr($this->str, -$i, 1, $encoding); + + if ($char == mb_substr($otherStr, -$i, 1, $encoding)) { + $longestCommonSuffix = $char . $longestCommonSuffix; + } else { + break; + } + } + + return static::create($longestCommonSuffix, $encoding); + } + + /** + * Returns the longest common substring between the string and $otherStr. + * In the case of ties, it returns that which occurs first. + * + * @param string $otherStr Second string for comparison + * @return Stringy Object with its $str being the longest common substring + */ + public function longestCommonSubstring($otherStr) + { + // Uses dynamic programming to solve + // http://en.wikipedia.org/wiki/Longest_common_substring_problem + $encoding = $this->encoding; + $stringy = static::create($this->str, $encoding); + $strLength = $stringy->length(); + $otherLength = mb_strlen($otherStr, $encoding); + + // Return if either string is empty + if ($strLength == 0 || $otherLength == 0) { + $stringy->str = ''; + return $stringy; + } + + $len = 0; + $end = 0; + $table = array_fill(0, $strLength + 1, + array_fill(0, $otherLength + 1, 0)); + + for ($i = 1; $i <= $strLength; $i++) { + for ($j = 1; $j <= $otherLength; $j++) { + $strChar = mb_substr($stringy->str, $i - 1, 1, $encoding); + $otherChar = mb_substr($otherStr, $j - 1, 1, $encoding); + + if ($strChar == $otherChar) { + $table[$i][$j] = $table[$i - 1][$j - 1] + 1; + if ($table[$i][$j] > $len) { + $len = $table[$i][$j]; + $end = $i; + } + } else { + $table[$i][$j] = 0; + } + } + } + + $stringy->str = mb_substr($stringy->str, $end - $len, $len, $encoding); + + return $stringy; + } + + /** + * Returns the length of the string. An alias for PHP's mb_strlen() function. + * + * @return int The number of characters in $str given the encoding + */ + public function length() + { + return mb_strlen($this->str, $this->encoding); + } + + /** + * Returns the substring beginning at $start with the specified $length. + * It differs from the mb_substr() function in that providing a $length of + * null will return the rest of the string, rather than an empty string. + * + * @param int $start Position of the first character to use + * @param int $length Maximum number of characters used + * @return Stringy Object with its $str being the substring + */ + public function substr($start, $length = null) + { + $length = $length === null ? $this->length() : $length; + $str = mb_substr($this->str, $start, $length, $this->encoding); + + return static::create($str, $this->encoding); + } + + /** + * Returns the character at $index, with indexes starting at 0. + * + * @param int $index Position of the character + * @return Stringy The character at $index + */ + public function at($index) + { + return $this->substr($index, 1); + } + + /** + * Returns the first $n characters of the string. + * + * @param int $n Number of characters to retrieve from the start + * @return Stringy Object with its $str being the first $n chars + */ + public function first($n) + { + $stringy = static::create($this->str, $this->encoding); + + if ($n < 0) { + $stringy->str = ''; + } else { + return $stringy->substr(0, $n); + } + + return $stringy; + } + + /** + * Returns the last $n characters of the string. + * + * @param int $n Number of characters to retrieve from the end + * @return Stringy Object with its $str being the last $n chars + */ + public function last($n) + { + $stringy = static::create($this->str, $this->encoding); + + if ($n <= 0) { + $stringy->str = ''; + } else { + return $stringy->substr(-$n); + } + + return $stringy; + } + + /** + * Ensures that the string begins with $substring. If it doesn't, it's + * prepended. + * + * @param string $substring The substring to add if not present + * @return Stringy Object with its $str prefixed by the $substring + */ + public function ensureLeft($substring) + { + $stringy = static::create($this->str, $this->encoding); + + if (!$stringy->startsWith($substring)) { + $stringy->str = $substring . $stringy->str; + } + + return $stringy; + } + + /** + * Ensures that the string begins with $substring. If it doesn't, it's + * appended. + * + * @param string $substring The substring to add if not present + * @return Stringy Object with its $str suffixed by the $substring + */ + public function ensureRight($substring) + { + $stringy = static::create($this->str, $this->encoding); + + if (!$stringy->endsWith($substring)) { + $stringy->str .= $substring; + } + + return $stringy; + } + + /** + * Returns a new string with the prefix $substring removed, if present. + * + * @param string $substring The prefix to remove + * @return Stringy Object having a $str without the prefix $substring + */ + public function removeLeft($substring) + { + $stringy = static::create($this->str, $this->encoding); + + if ($stringy->startsWith($substring)) { + $substringLength = mb_strlen($substring, $stringy->encoding); + return $stringy->substr($substringLength); + } + + return $stringy; + } + + /** + * Returns a new string with the suffix $substring removed, if present. + * + * @param string $substring The suffix to remove + * @return Stringy Object having a $str without the suffix $substring + */ + public function removeRight($substring) + { + $stringy = static::create($this->str, $this->encoding); + + if ($stringy->endsWith($substring)) { + $substringLength = mb_strlen($substring, $stringy->encoding); + return $stringy->substr(0, $stringy->length() - $substringLength); + } + + return $stringy; + } + + /** + * Returns true if $str matches the supplied pattern, false otherwise. + * + * @param string $pattern Regex pattern to match against + * @return bool Whether or not $str matches the pattern + */ + private function matchesPattern($pattern) + { + $regexEncoding = mb_regex_encoding(); + mb_regex_encoding($this->encoding); + + $match = mb_ereg_match($pattern, $this->str); + mb_regex_encoding($regexEncoding); + + return $match; + } + + /** + * Returns true if the string contains a lower case char, false + * otherwise. + * + * @return bool Whether or not the string contains a lower case character. + */ + public function hasLowerCase() + { + return $this->matchesPattern('.*[[:lower:]]'); + } + + /** + * Returns true if the string contains an upper case char, false + * otherwise. + * + * @return bool Whether or not the string contains an upper case character. + */ + public function hasUpperCase() + { + return $this->matchesPattern('.*[[:upper:]]'); + } + + /** + * Returns true if the string contains only alphabetic chars, false + * otherwise. + * + * @return bool Whether or not $str contains only alphabetic chars + */ + public function isAlpha() + { + return $this->matchesPattern('^[[:alpha:]]*$'); + } + + /** + * Returns true if the string contains only alphabetic and numeric chars, + * false otherwise. + * + * @return bool Whether or not $str contains only alphanumeric chars + */ + public function isAlphanumeric() + { + return $this->matchesPattern('^[[:alnum:]]*$'); + } + + /** + * Returns true if the string contains only hexadecimal chars, false + * otherwise. + * + * @return bool Whether or not $str contains only hexadecimal chars + */ + public function isHexadecimal() + { + return $this->matchesPattern('^[[:xdigit:]]*$'); + } + + /** + * Returns true if the string contains only whitespace chars, false + * otherwise. + * + * @return bool Whether or not $str contains only whitespace characters + */ + public function isBlank() + { + return $this->matchesPattern('^[[:space:]]*$'); + } + + /** + * Returns true if the string is JSON, false otherwise. + * + * @return bool Whether or not $str is JSON + */ + public function isJson() + { + json_decode($this->str); + + return (json_last_error() === JSON_ERROR_NONE); + } + + /** + * Returns true if the string contains only lower case chars, false + * otherwise. + * + * @return bool Whether or not $str contains only lower case characters + */ + public function isLowerCase() + { + return $this->matchesPattern('^[[:lower:]]*$'); + } + + /** + * Returns true if the string contains only lower case chars, false + * otherwise. + * + * @return bool Whether or not $str contains only lower case characters + */ + public function isUpperCase() + { + return $this->matchesPattern('^[[:upper:]]*$'); + } + + /** + * Returns true if the string is serialized, false otherwise. + * + * @return bool Whether or not $str is serialized + */ + public function isSerialized() + { + return $this->str === 'b:0;' || @unserialize($this->str) !== false; + } + + /** + * Returns the number of occurrences of $substring in the given string. + * By default, the comparison is case-sensitive, but can be made insensitive + * by setting $caseSensitive to false. + * + * @param string $substring The substring to search for + * @param bool $caseSensitive Whether or not to enforce case-sensitivity + * @return int The number of $substring occurrences + */ + public function countSubstr($substring, $caseSensitive = true) + { + if ($caseSensitive) { + return mb_substr_count($this->str, $substring, $this->encoding); + } + + $str = mb_strtoupper($this->str, $this->encoding); + $substring = mb_strtoupper($substring, $this->encoding); + + return mb_substr_count($str, $substring, $this->encoding); + } + + /** + * Replaces all occurrences of $search in $str by $replacement. + * + * @param string $search The needle to search for + * @param string $replacement The string to replace with + * @return Stringy Object with the resulting $str after the replacements + */ + public function replace($search, $replacement) + { + return $this->regexReplace(preg_quote($search), $replacement); + } + + /** + * Replaces all occurrences of $pattern in $str by $replacement. An alias + * for mb_ereg_replace(). Note that the 'i' option with multibyte patterns + * in mb_ereg_replace() requires PHP 5.4+. This is due to a lack of support + * in the bundled version of Oniguruma in PHP 5.3. + * + * @param string $pattern The regular expression pattern + * @param string $replacement The string to replace with + * @param string $options Matching conditions to be used + * @return Stringy Object with the resulting $str after the replacements + */ + public function regexReplace($pattern, $replacement, $options = 'msr') + { + $regexEncoding = mb_regex_encoding(); + mb_regex_encoding($this->encoding); + + $str = mb_ereg_replace($pattern, $replacement, $this->str, $options); + mb_regex_encoding($regexEncoding); + + return static::create($str, $this->encoding); + } + + /** + * Convert all applicable characters to HTML entities. + * + * @param int|null $flags See http://php.net/manual/en/function.htmlentities.php + * @return Stringy Object with the resulting $str after being html encoded. + */ + public function htmlEncode($flags = ENT_COMPAT) + { + $str = htmlentities($this->str, $flags, $this->encoding); + + return static::create($str, $this->encoding); + } + + /** + * Convert all HTML entities to their applicable characters. + * + * @param int|null $flags See http://php.net/manual/en/function.html-entity-decode.php + * @return Stringy Object with the resulting $str after being html decoded. + */ + public function htmlDecode($flags = ENT_COMPAT) + { + $str = html_entity_decode($this->str, $flags, $this->encoding); + + return static::create($str, $this->encoding); + } +} diff --git a/vendor/danielstjules/stringy/tests/CommonTest.php b/vendor/danielstjules/stringy/tests/CommonTest.php new file mode 100644 index 0000000..285deb5 --- /dev/null +++ b/vendor/danielstjules/stringy/tests/CommonTest.php @@ -0,0 +1,1130 @@ +assertInstanceOf('Stringy\Stringy', $actual); + } + + public function indexOfProvider() + { + return array( + array(2, 'This is the string', 'is'), + array(2, 'This is the string', 'is', 0, 'UTF-8'), + array(false, 'This is the string', 'not-found', 0, 'UTF-8'), + array(32, 'This is the string... and there is another thing', 'is', 10, 'UTF-8'), + ); + } + + public function indexOfLastProvider() + { + return array( + array(5, 'This is the string', 'is'), + array(5, 'This is the string', 'is', 0, 'UTF-8'), + array(false, 'This is the string', 'not-found', 0, 'UTF-8'), + array(32, 'This is the string... and there is another thing', 'is', 0, 'UTF-8'), + ); + } + + public function charsProvider() + { + return array( + array(array(), ''), + array(array('T', 'e', 's', 't'), 'Test'), + array(array('F', 'ò', 'ô', ' ', 'B', 'à', 'ř'), 'Fòô Bàř', 'UTF-8') + ); + } + + public function upperCaseFirstProvider() + { + return array( + array('Test', 'Test'), + array('Test', 'test'), + array('1a', '1a'), + array('Σ test', 'σ test', 'UTF-8'), + array(' σ test', ' σ test', 'UTF-8') + ); + } + + public function lowerCaseFirstProvider() + { + return array( + array('test', 'Test'), + array('test', 'test'), + array('1a', '1a'), + array('σ test', 'Σ test', 'UTF-8'), + array(' Σ test', ' Σ test', 'UTF-8') + ); + } + + public function camelizeProvider() + { + return array( + array('camelCase', 'CamelCase'), + array('camelCase', 'Camel-Case'), + array('camelCase', 'camel case'), + array('camelCase', 'camel -case'), + array('camelCase', 'camel - case'), + array('camelCase', 'camel_case'), + array('camelCTest', 'camel c test'), + array('stringWith1Number', 'string_with1number'), + array('stringWith22Numbers', 'string-with-2-2 numbers'), + array('1Camel2Case', '1camel2case'), + array('camelΣase', 'camel σase', 'UTF-8'), + array('στανιλCase', 'Στανιλ case', 'UTF-8'), + array('σamelCase', 'σamel Case', 'UTF-8') + ); + } + + public function upperCamelizeProvider() + { + return array( + array('CamelCase', 'camelCase'), + array('CamelCase', 'Camel-Case'), + array('CamelCase', 'camel case'), + array('CamelCase', 'camel -case'), + array('CamelCase', 'camel - case'), + array('CamelCase', 'camel_case'), + array('CamelCTest', 'camel c test'), + array('StringWith1Number', 'string_with1number'), + array('StringWith22Numbers', 'string-with-2-2 numbers'), + array('1Camel2Case', '1camel2case'), + array('CamelΣase', 'camel σase', 'UTF-8'), + array('ΣτανιλCase', 'στανιλ case', 'UTF-8'), + array('ΣamelCase', 'Σamel Case', 'UTF-8') + ); + } + + public function dasherizeProvider() + { + return array( + array('test-case', 'testCase'), + array('test-case', 'Test-Case'), + array('test-case', 'test case'), + array('-test-case', '-test -case'), + array('test-case', 'test - case'), + array('test-case', 'test_case'), + array('test-c-test', 'test c test'), + array('test-d-case', 'TestDCase'), + array('test-c-c-test', 'TestCCTest'), + array('string-with1number', 'string_with1number'), + array('string-with-2-2-numbers', 'String-with_2_2 numbers'), + array('1test2case', '1test2case'), + array('dash-σase', 'dash Σase', 'UTF-8'), + array('στανιλ-case', 'Στανιλ case', 'UTF-8'), + array('σash-case', 'Σash Case', 'UTF-8') + ); + } + + public function underscoredProvider() + { + return array( + array('test_case', 'testCase'), + array('test_case', 'Test-Case'), + array('test_case', 'test case'), + array('test_case', 'test -case'), + array('_test_case', '-test - case'), + array('test_case', 'test_case'), + array('test_c_test', ' test c test'), + array('test_u_case', 'TestUCase'), + array('test_c_c_test', 'TestCCTest'), + array('string_with1number', 'string_with1number'), + array('string_with_2_2_numbers', 'String-with_2_2 numbers'), + array('1test2case', '1test2case'), + array('test_σase', 'test Σase', 'UTF-8'), + array('στανιλ_case', 'Στανιλ case', 'UTF-8'), + array('σash_case', 'Σash Case', 'UTF-8') + ); + } + + public function delimitProvider() + { + return array( + array('test*case', 'testCase', '*'), + array('test&case', 'Test-Case', '&'), + array('test#case', 'test case', '#'), + array('test**case', 'test -case', '**'), + array('~!~test~!~case', '-test - case', '~!~'), + array('test*case', 'test_case', '*'), + array('test%c%test', ' test c test', '%'), + array('test+u+case', 'TestUCase', '+'), + array('test=c=c=test', 'TestCCTest', '='), + array('string#>with1number', 'string_with1number', '#>'), + array('1test2case', '1test2case', '*'), + array('test ύα σase', 'test Σase', ' ύα ', 'UTF-8',), + array('στανιλαcase', 'Στανιλ case', 'α', 'UTF-8',), + array('σashΘcase', 'Σash Case', 'Θ', 'UTF-8') + ); + } + + public function swapCaseProvider() + { + return array( + array('TESTcASE', 'testCase'), + array('tEST-cASE', 'Test-Case'), + array(' - σASH cASE', ' - Σash Case', 'UTF-8'), + array('νΤΑΝΙΛ', 'Ντανιλ', 'UTF-8') + ); + } + + public function titleizeProvider() + { + $ignore = array('at', 'by', 'for', 'in', 'of', 'on', 'out', 'to', 'the'); + + return array( + array('Testing The Method', 'testing the method'), + array('Testing the Method', 'testing the method', $ignore, 'UTF-8'), + array('I Like to Watch DVDs at Home', 'i like to watch DVDs at home', + $ignore, 'UTF-8'), + array('Θα Ήθελα Να Φύγει', ' Θα ήθελα να φύγει ', null, 'UTF-8') + ); + } + + public function humanizeProvider() + { + return array( + array('Author', 'author_id'), + array('Test user', ' _test_user_'), + array('Συγγραφέας', ' συγγραφέας_id ', 'UTF-8') + ); + } + + public function tidyProvider() + { + return array( + array('"I see..."', '“I see…”'), + array("'This too'", "‘This too’"), + array('test-dash', 'test—dash'), + array('Ο συγγραφέας είπε...', 'Ο συγγραφέας είπε…') + ); + } + + public function collapseWhitespaceProvider() + { + return array( + array('foo bar', ' foo bar '), + array('test string', 'test string'), + array('Ο συγγραφέας', ' Ο συγγραφέας '), + array('123', ' 123 '), + array('', ' ', 'UTF-8'), // no-break space (U+00A0) + array('', '           ', 'UTF-8'), // spaces U+2000 to U+200A + array('', ' ', 'UTF-8'), // narrow no-break space (U+202F) + array('', ' ', 'UTF-8'), // medium mathematical space (U+205F) + array('', ' ', 'UTF-8'), // ideographic space (U+3000) + array('1 2 3', '  1  2  3  ', 'UTF-8'), + array('', ' '), + array('', ''), + ); + } + + public function toAsciiProvider() + { + return array( + array('foo bar', 'fòô bàř'), + array(' TEST ', ' ŤÉŚŢ '), + array('f = z = 3', 'φ = ź = 3'), + array('perevirka', 'перевірка'), + array('lysaya gora', 'лысая гора'), + array('shchuka', 'щука'), + array('', '漢字'), + array('xin chao the gioi', 'xin chào thế giới'), + array('XIN CHAO THE GIOI', 'XIN CHÀO THẾ GIỚI'), + array('dam phat chet luon', 'đấm phát chết luôn'), + array(' ', ' '), // no-break space (U+00A0) + array(' ', '           '), // spaces U+2000 to U+200A + array(' ', ' '), // narrow no-break space (U+202F) + array(' ', ' '), // medium mathematical space (U+205F) + array(' ', ' '), // ideographic space (U+3000) + array('', '𐍉'), // some uncommon, unsupported character (U+10349) + array('𐍉', '𐍉', false), + ); + } + + public function padProvider() + { + return array( + // length <= str + array('foo bar', 'foo bar', -1), + array('foo bar', 'foo bar', 7), + array('fòô bàř', 'fòô bàř', 7, ' ', 'right', 'UTF-8'), + + // right + array('foo bar ', 'foo bar', 9), + array('foo bar_*', 'foo bar', 9, '_*', 'right'), + array('fòô bàř¬ø¬', 'fòô bàř', 10, '¬ø', 'right', 'UTF-8'), + + // left + array(' foo bar', 'foo bar', 9, ' ', 'left'), + array('_*foo bar', 'foo bar', 9, '_*', 'left'), + array('¬ø¬fòô bàř', 'fòô bàř', 10, '¬ø', 'left', 'UTF-8'), + + // both + array('foo bar ', 'foo bar', 8, ' ', 'both'), + array('¬fòô bàř¬ø', 'fòô bàř', 10, '¬ø', 'both', 'UTF-8'), + array('¬øfòô bàř¬øÿ', 'fòô bàř', 12, '¬øÿ', 'both', 'UTF-8') + ); + } + + public function padLeftProvider() + { + return array( + array(' foo bar', 'foo bar', 9), + array('_*foo bar', 'foo bar', 9, '_*'), + array('_*_foo bar', 'foo bar', 10, '_*'), + array(' fòô bàř', 'fòô bàř', 9, ' ', 'UTF-8'), + array('¬øfòô bàř', 'fòô bàř', 9, '¬ø', 'UTF-8'), + array('¬ø¬fòô bàř', 'fòô bàř', 10, '¬ø', 'UTF-8'), + array('¬ø¬øfòô bàř', 'fòô bàř', 11, '¬ø', 'UTF-8'), + ); + } + + public function padRightProvider() + { + return array( + array('foo bar ', 'foo bar', 9), + array('foo bar_*', 'foo bar', 9, '_*'), + array('foo bar_*_', 'foo bar', 10, '_*'), + array('fòô bàř ', 'fòô bàř', 9, ' ', 'UTF-8'), + array('fòô bàř¬ø', 'fòô bàř', 9, '¬ø', 'UTF-8'), + array('fòô bàř¬ø¬', 'fòô bàř', 10, '¬ø', 'UTF-8'), + array('fòô bàř¬ø¬ø', 'fòô bàř', 11, '¬ø', 'UTF-8'), + ); + } + + public function padBothProvider() + { + return array( + array('foo bar ', 'foo bar', 8), + array(' foo bar ', 'foo bar', 9, ' '), + array('fòô bàř ', 'fòô bàř', 8, ' ', 'UTF-8'), + array(' fòô bàř ', 'fòô bàř', 9, ' ', 'UTF-8'), + array('fòô bàř¬', 'fòô bàř', 8, '¬ø', 'UTF-8'), + array('¬fòô bàř¬', 'fòô bàř', 9, '¬ø', 'UTF-8'), + array('¬fòô bàř¬ø', 'fòô bàř', 10, '¬ø', 'UTF-8'), + array('¬øfòô bàř¬ø', 'fòô bàř', 11, '¬ø', 'UTF-8'), + array('¬fòô bàř¬ø', 'fòô bàř', 10, '¬øÿ', 'UTF-8'), + array('¬øfòô bàř¬ø', 'fòô bàř', 11, '¬øÿ', 'UTF-8'), + array('¬øfòô bàř¬øÿ', 'fòô bàř', 12, '¬øÿ', 'UTF-8') + ); + } + + public function startsWithProvider() + { + return array( + array(true, 'foo bars', 'foo bar'), + array(true, 'FOO bars', 'foo bar', false), + array(true, 'FOO bars', 'foo BAR', false), + array(true, 'FÒÔ bàřs', 'fòô bàř', false, 'UTF-8'), + array(true, 'fòô bàřs', 'fòô BÀŘ', false, 'UTF-8'), + array(false, 'foo bar', 'bar'), + array(false, 'foo bar', 'foo bars'), + array(false, 'FOO bar', 'foo bars'), + array(false, 'FOO bars', 'foo BAR'), + array(false, 'FÒÔ bàřs', 'fòô bàř', true, 'UTF-8'), + array(false, 'fòô bàřs', 'fòô BÀŘ', true, 'UTF-8'), + ); + } + + public function endsWithProvider() + { + return array( + array(true, 'foo bars', 'o bars'), + array(true, 'FOO bars', 'o bars', false), + array(true, 'FOO bars', 'o BARs', false), + array(true, 'FÒÔ bàřs', 'ô bàřs', false, 'UTF-8'), + array(true, 'fòô bàřs', 'ô BÀŘs', false, 'UTF-8'), + array(false, 'foo bar', 'foo'), + array(false, 'foo bar', 'foo bars'), + array(false, 'FOO bar', 'foo bars'), + array(false, 'FOO bars', 'foo BARS'), + array(false, 'FÒÔ bàřs', 'fòô bàřs', true, 'UTF-8'), + array(false, 'fòô bàřs', 'fòô BÀŘS', true, 'UTF-8'), + ); + } + + public function toSpacesProvider() + { + return array( + array(' foo bar ', ' foo bar '), + array(' foo bar ', ' foo bar ', 5), + array(' foo bar ', ' foo bar ', 2), + array('foobar', ' foo bar ', 0), + array(" foo\n bar", " foo\n bar"), + array(" fòô\n bàř", " fòô\n bàř") + ); + } + + public function toTabsProvider() + { + return array( + array(' foo bar ', ' foo bar '), + array(' foo bar ', ' foo bar ', 5), + array(' foo bar ', ' foo bar ', 2), + array(" foo\n bar", " foo\n bar"), + array(" fòô\n bàř", " fòô\n bàř") + ); + } + + public function toLowerCaseProvider() + { + return array( + array('foo bar', 'FOO BAR'), + array(' foo_bar ', ' FOO_bar '), + array('fòô bàř', 'FÒÔ BÀŘ', 'UTF-8'), + array(' fòô_bàř ', ' FÒÔ_bàř ', 'UTF-8'), + array('αυτοκίνητο', 'ΑΥΤΟΚΊΝΗΤΟ', 'UTF-8'), + ); + } + + public function toTitleCaseProvider() + { + return array( + array('Foo Bar', 'foo bar'), + array(' Foo_Bar ', ' foo_bar '), + array('Fòô Bàř', 'fòô bàř', 'UTF-8'), + array(' Fòô_Bàř ', ' fòô_bàř ', 'UTF-8'), + array('Αυτοκίνητο Αυτοκίνητο', 'αυτοκίνητο αυτοκίνητο', 'UTF-8'), + ); + } + + public function toUpperCaseProvider() + { + return array( + array('FOO BAR', 'foo bar'), + array(' FOO_BAR ', ' FOO_bar '), + array('FÒÔ BÀŘ', 'fòô bàř', 'UTF-8'), + array(' FÒÔ_BÀŘ ', ' FÒÔ_bàř ', 'UTF-8'), + array('ΑΥΤΟΚΊΝΗΤΟ', 'αυτοκίνητο', 'UTF-8'), + ); + } + + public function slugifyProvider() + { + return array( + array('foo-bar', ' foo bar '), + array('foo-bar', 'foo -.-"-...bar'), + array('another-foo-bar', 'another..& foo -.-"-...bar'), + array('foo-dbar', " Foo d'Bar "), + array('a-string-with-dashes', 'A string-with-dashes'), + array('using-strings-like-foo-bar', 'Using strings like fòô bàř'), + array('numbers-1234', 'numbers 1234'), + array('perevirka-ryadka', 'перевірка рядка'), + array('bukvar-s-bukvoy-y', 'букварь с буквой ы'), + array('podekhal-k-podezdu-moego-doma', 'подъехал к подъезду моего дома'), + array('foo:bar:baz', 'Foo bar baz', ':'), + array('a_string_with_underscores', 'A_string with_underscores', '_'), + array('a_string_with_dashes', 'A string-with-dashes', '_'), + array('a\string\with\dashes', 'A string-with-dashes', '\\'), + array('an_odd_string', '-- An odd__ string-_', '_') + ); + } + + public function containsProvider() + { + return array( + array(true, 'Str contains foo bar', 'foo bar'), + array(true, '12398!@(*%!@# @!%#*&^%', ' @!%#*&^%'), + array(true, 'Ο συγγραφέας είπε', 'συγγραφέας', 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', 'å´¥©', true, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', 'å˚ ∆', true, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', 'øœ¬', true, 'UTF-8'), + array(false, 'Str contains foo bar', 'Foo bar'), + array(false, 'Str contains foo bar', 'foobar'), + array(false, 'Str contains foo bar', 'foo bar '), + array(false, 'Ο συγγραφέας είπε', ' συγγραφέας ', true, 'UTF-8'), + array(false, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', ' ßå˚', true, 'UTF-8'), + array(true, 'Str contains foo bar', 'Foo bar', false), + array(true, '12398!@(*%!@# @!%#*&^%', ' @!%#*&^%', false), + array(true, 'Ο συγγραφέας είπε', 'ΣΥΓΓΡΑΦΈΑΣ', false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', 'Å´¥©', false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', 'Å˚ ∆', false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', 'ØŒ¬', false, 'UTF-8'), + array(false, 'Str contains foo bar', 'foobar', false), + array(false, 'Str contains foo bar', 'foo bar ', false), + array(false, 'Ο συγγραφέας είπε', ' συγγραφέας ', false, 'UTF-8'), + array(false, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', ' ßÅ˚', false, 'UTF-8') + ); + } + + public function containsAnyProvider() + { + // One needle + $singleNeedle = array_map(function ($array) { + $array[2] = array($array[2]); + return $array; + }, $this->containsProvider()); + + $provider = array( + // No needles + array(false, 'Str contains foo bar', array()), + // Multiple needles + array(true, 'Str contains foo bar', array('foo', 'bar')), + array(true, '12398!@(*%!@# @!%#*&^%', array(' @!%#*', '&^%')), + array(true, 'Ο συγγραφέας είπε', array('συγγρ', 'αφέας'), 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('å´¥', '©'), true, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('å˚ ', '∆'), true, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('øœ', '¬'), true, 'UTF-8'), + array(false, 'Str contains foo bar', array('Foo', 'Bar')), + array(false, 'Str contains foo bar', array('foobar', 'bar ')), + array(false, 'Str contains foo bar', array('foo bar ', ' foo')), + array(false, 'Ο συγγραφέας είπε', array(' συγγραφέας ', ' συγγραφ '), true, 'UTF-8'), + array(false, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array(' ßå˚', ' ß '), true, 'UTF-8'), + array(true, 'Str contains foo bar', array('Foo bar', 'bar'), false), + array(true, '12398!@(*%!@# @!%#*&^%', array(' @!%#*&^%', '*&^%'), false), + array(true, 'Ο συγγραφέας είπε', array('ΣΥΓΓΡΑΦΈΑΣ', 'ΑΦΈΑ'), false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('Å´¥©', '¥©'), false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('Å˚ ∆', ' ∆'), false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('ØŒ¬', 'Œ'), false, 'UTF-8'), + array(false, 'Str contains foo bar', array('foobar', 'none'), false), + array(false, 'Str contains foo bar', array('foo bar ', ' ba '), false), + array(false, 'Ο συγγραφέας είπε', array(' συγγραφέας ', ' ραφέ '), false, 'UTF-8'), + array(false, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array(' ßÅ˚', ' Å˚ '), false, 'UTF-8'), + ); + + return array_merge($singleNeedle, $provider); + } + + public function containsAllProvider() + { + // One needle + $singleNeedle = array_map(function ($array) { + $array[2] = array($array[2]); + return $array; + }, $this->containsProvider()); + + $provider = array( + // One needle + array(false, 'Str contains foo bar', array()), + // Multiple needles + array(true, 'Str contains foo bar', array('foo', 'bar')), + array(true, '12398!@(*%!@# @!%#*&^%', array(' @!%#*', '&^%')), + array(true, 'Ο συγγραφέας είπε', array('συγγρ', 'αφέας'), 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('å´¥', '©'), true, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('å˚ ', '∆'), true, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('øœ', '¬'), true, 'UTF-8'), + array(false, 'Str contains foo bar', array('Foo', 'bar')), + array(false, 'Str contains foo bar', array('foobar', 'bar')), + array(false, 'Str contains foo bar', array('foo bar ', 'bar')), + array(false, 'Ο συγγραφέας είπε', array(' συγγραφέας ', ' συγγραφ '), true, 'UTF-8'), + array(false, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array(' ßå˚', ' ß '), true, 'UTF-8'), + array(true, 'Str contains foo bar', array('Foo bar', 'bar'), false), + array(true, '12398!@(*%!@# @!%#*&^%', array(' @!%#*&^%', '*&^%'), false), + array(true, 'Ο συγγραφέας είπε', array('ΣΥΓΓΡΑΦΈΑΣ', 'ΑΦΈΑ'), false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('Å´¥©', '¥©'), false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('Å˚ ∆', ' ∆'), false, 'UTF-8'), + array(true, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array('ØŒ¬', 'Œ'), false, 'UTF-8'), + array(false, 'Str contains foo bar', array('foobar', 'none'), false), + array(false, 'Str contains foo bar', array('foo bar ', ' ba'), false), + array(false, 'Ο συγγραφέας είπε', array(' συγγραφέας ', ' ραφέ '), false, 'UTF-8'), + array(false, 'å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', array(' ßÅ˚', ' Å˚ '), false, 'UTF-8'), + ); + + return array_merge($singleNeedle, $provider); + } + + public function surroundProvider() + { + return array( + array('__foobar__', 'foobar', '__'), + array('test', 'test', ''), + array('**', '', '*'), + array('¬fòô bàř¬', 'fòô bàř', '¬'), + array('ßå∆˚ test ßå∆˚', ' test ', 'ßå∆˚') + ); + } + + public function insertProvider() + { + return array( + array('foo bar', 'oo bar', 'f', 0), + array('foo bar', 'f bar', 'oo', 1), + array('f bar', 'f bar', 'oo', 20), + array('foo bar', 'foo ba', 'r', 6), + array('fòô bàř', 'òô bàř', 'f', 0, 'UTF-8'), + array('fòô bàř', 'f bàř', 'òô', 1, 'UTF-8'), + array('fòô bàř', 'fòô bà', 'ř', 6, 'UTF-8') + ); + } + + public function truncateProvider() + { + return array( + array('Test foo bar', 'Test foo bar', 12), + array('Test foo ba', 'Test foo bar', 11), + array('Test foo', 'Test foo bar', 8), + array('Test fo', 'Test foo bar', 7), + array('Test', 'Test foo bar', 4), + array('Test foo bar', 'Test foo bar', 12, '...'), + array('Test foo...', 'Test foo bar', 11, '...'), + array('Test ...', 'Test foo bar', 8, '...'), + array('Test...', 'Test foo bar', 7, '...'), + array('T...', 'Test foo bar', 4, '...'), + array('Test fo....', 'Test foo bar', 11, '....'), + array('Test fòô bàř', 'Test fòô bàř', 12, '', 'UTF-8'), + array('Test fòô bà', 'Test fòô bàř', 11, '', 'UTF-8'), + array('Test fòô', 'Test fòô bàř', 8, '', 'UTF-8'), + array('Test fò', 'Test fòô bàř', 7, '', 'UTF-8'), + array('Test', 'Test fòô bàř', 4, '', 'UTF-8'), + array('Test fòô bàř', 'Test fòô bàř', 12, 'ϰϰ', 'UTF-8'), + array('Test fòô ϰϰ', 'Test fòô bàř', 11, 'ϰϰ', 'UTF-8'), + array('Test fϰϰ', 'Test fòô bàř', 8, 'ϰϰ', 'UTF-8'), + array('Test ϰϰ', 'Test fòô bàř', 7, 'ϰϰ', 'UTF-8'), + array('Teϰϰ', 'Test fòô bàř', 4, 'ϰϰ', 'UTF-8'), + array('What are your pl...', 'What are your plans today?', 19, '...') + ); + } + + public function safeTruncateProvider() + { + return array( + array('Test foo bar', 'Test foo bar', 12), + array('Test foo', 'Test foo bar', 11), + array('Test foo', 'Test foo bar', 8), + array('Test', 'Test foo bar', 7), + array('Test', 'Test foo bar', 4), + array('Test foo bar', 'Test foo bar', 12, '...'), + array('Test foo...', 'Test foo bar', 11, '...'), + array('Test...', 'Test foo bar', 8, '...'), + array('Test...', 'Test foo bar', 7, '...'), + array('...', 'Test foo bar', 4, '...'), + array('Test....', 'Test foo bar', 11, '....'), + array('Test fòô bàř', 'Test fòô bàř', 12, '', 'UTF-8'), + array('Test fòô', 'Test fòô bàř', 11, '', 'UTF-8'), + array('Test fòô', 'Test fòô bàř', 8, '', 'UTF-8'), + array('Test', 'Test fòô bàř', 7, '', 'UTF-8'), + array('Test', 'Test fòô bàř', 4, '', 'UTF-8'), + array('Test fòô bàř', 'Test fòô bàř', 12, 'ϰϰ', 'UTF-8'), + array('Test fòôϰϰ', 'Test fòô bàř', 11, 'ϰϰ', 'UTF-8'), + array('Testϰϰ', 'Test fòô bàř', 8, 'ϰϰ', 'UTF-8'), + array('Testϰϰ', 'Test fòô bàř', 7, 'ϰϰ', 'UTF-8'), + array('ϰϰ', 'Test fòô bàř', 4, 'ϰϰ', 'UTF-8'), + array('What are your plans...', 'What are your plans today?', 22, '...') + ); + } + + public function reverseProvider() + { + return array( + array('', ''), + array('raboof', 'foobar'), + array('řàbôòf', 'fòôbàř', 'UTF-8'), + array('řàb ôòf', 'fòô bàř', 'UTF-8'), + array('∂∆ ˚åß', 'ßå˚ ∆∂', 'UTF-8') + ); + } + + public function shuffleProvider() + { + return array( + array('foo bar'), + array('∂∆ ˚åß', 'UTF-8'), + array('å´¥©¨ˆßå˚ ∆∂˙©å∑¥øœ¬', 'UTF-8') + ); + } + + public function trimProvider() + { + return array( + array('foo bar', ' foo bar '), + array('foo bar', ' foo bar'), + array('foo bar', 'foo bar '), + array('foo bar', "\n\t foo bar \n\t"), + array('fòô bàř', ' fòô bàř '), + array('fòô bàř', ' fòô bàř'), + array('fòô bàř', 'fòô bàř '), + array(' foo bar ', "\n\t foo bar \n\t", "\n\t"), + array('fòô bàř', "\n\t fòô bàř \n\t", null, 'UTF-8'), + array('fòô', ' fòô ', null, 'UTF-8'), // narrow no-break space (U+202F) + array('fòô', '  fòô  ', null, 'UTF-8'), // medium mathematical space (U+205F) + array('fòô', '           fòô', null, 'UTF-8') // spaces U+2000 to U+200A + ); + } + + public function trimLeftProvider() + { + return array( + array('foo bar ', ' foo bar '), + array('foo bar', ' foo bar'), + array('foo bar ', 'foo bar '), + array("foo bar \n\t", "\n\t foo bar \n\t"), + array('fòô bàř ', ' fòô bàř '), + array('fòô bàř', ' fòô bàř'), + array('fòô bàř ', 'fòô bàř '), + array('foo bar', '--foo bar', '-'), + array('fòô bàř', 'òòfòô bàř', 'ò', 'UTF-8'), + array("fòô bàř \n\t", "\n\t fòô bàř \n\t", null, 'UTF-8'), + array('fòô ', ' fòô ', null, 'UTF-8'), // narrow no-break space (U+202F) + array('fòô  ', '  fòô  ', null, 'UTF-8'), // medium mathematical space (U+205F) + array('fòô', '           fòô', null, 'UTF-8') // spaces U+2000 to U+200A + ); + } + + public function trimRightProvider() + { + return array( + array(' foo bar', ' foo bar '), + array('foo bar', 'foo bar '), + array(' foo bar', ' foo bar'), + array("\n\t foo bar", "\n\t foo bar \n\t"), + array(' fòô bàř', ' fòô bàř '), + array('fòô bàř', 'fòô bàř '), + array(' fòô bàř', ' fòô bàř'), + array('foo bar', 'foo bar--', '-'), + array('fòô bàř', 'fòô bàřòò', 'ò', 'UTF-8'), + array("\n\t fòô bàř", "\n\t fòô bàř \n\t", null, 'UTF-8'), + array(' fòô', ' fòô ', null, 'UTF-8'), // narrow no-break space (U+202F) + array('  fòô', '  fòô  ', null, 'UTF-8'), // medium mathematical space (U+205F) + array('fòô', 'fòô           ', null, 'UTF-8') // spaces U+2000 to U+200A + ); + } + + public function longestCommonPrefixProvider() + { + return array( + array('foo', 'foobar', 'foo bar'), + array('foo bar', 'foo bar', 'foo bar'), + array('f', 'foo bar', 'far boo'), + array('', 'toy car', 'foo bar'), + array('', 'foo bar', ''), + array('fòô', 'fòôbar', 'fòô bar', 'UTF-8'), + array('fòô bar', 'fòô bar', 'fòô bar', 'UTF-8'), + array('fò', 'fòô bar', 'fòr bar', 'UTF-8'), + array('', 'toy car', 'fòô bar', 'UTF-8'), + array('', 'fòô bar', '', 'UTF-8'), + ); + } + + public function longestCommonSuffixProvider() + { + return array( + array('bar', 'foobar', 'foo bar'), + array('foo bar', 'foo bar', 'foo bar'), + array('ar', 'foo bar', 'boo far'), + array('', 'foo bad', 'foo bar'), + array('', 'foo bar', ''), + array('bàř', 'fòôbàř', 'fòô bàř', 'UTF-8'), + array('fòô bàř', 'fòô bàř', 'fòô bàř', 'UTF-8'), + array(' bàř', 'fòô bàř', 'fòr bàř', 'UTF-8'), + array('', 'toy car', 'fòô bàř', 'UTF-8'), + array('', 'fòô bàř', '', 'UTF-8'), + ); + } + + public function longestCommonSubstringProvider() + { + return array( + array('foo', 'foobar', 'foo bar'), + array('foo bar', 'foo bar', 'foo bar'), + array('oo ', 'foo bar', 'boo far'), + array('foo ba', 'foo bad', 'foo bar'), + array('', 'foo bar', ''), + array('fòô', 'fòôbàř', 'fòô bàř', 'UTF-8'), + array('fòô bàř', 'fòô bàř', 'fòô bàř', 'UTF-8'), + array(' bàř', 'fòô bàř', 'fòr bàř', 'UTF-8'), + array(' ', 'toy car', 'fòô bàř', 'UTF-8'), + array('', 'fòô bàř', '', 'UTF-8'), + ); + } + + public function lengthProvider() + { + return array( + array(11, ' foo bar '), + array(1, 'f'), + array(0, ''), + array(7, 'fòô bàř', 'UTF-8') + ); + } + + public function substrProvider() + { + return array( + array('foo bar', 'foo bar', 0), + array('bar', 'foo bar', 4), + array('bar', 'foo bar', 4, null), + array('o b', 'foo bar', 2, 3), + array('', 'foo bar', 4, 0), + array('fòô bàř', 'fòô bàř', 0, null, 'UTF-8'), + array('bàř', 'fòô bàř', 4, null, 'UTF-8'), + array('ô b', 'fòô bàř', 2, 3, 'UTF-8'), + array('', 'fòô bàř', 4, 0, 'UTF-8') + ); + } + + public function atProvider() + { + return array( + array('f', 'foo bar', 0), + array('o', 'foo bar', 1), + array('r', 'foo bar', 6), + array('', 'foo bar', 7), + array('f', 'fòô bàř', 0, 'UTF-8'), + array('ò', 'fòô bàř', 1, 'UTF-8'), + array('ř', 'fòô bàř', 6, 'UTF-8'), + array('', 'fòô bàř', 7, 'UTF-8'), + ); + } + + public function firstProvider() + { + return array( + array('', 'foo bar', -5), + array('', 'foo bar', 0), + array('f', 'foo bar', 1), + array('foo', 'foo bar', 3), + array('foo bar', 'foo bar', 7), + array('foo bar', 'foo bar', 8), + array('', 'fòô bàř', -5, 'UTF-8'), + array('', 'fòô bàř', 0, 'UTF-8'), + array('f', 'fòô bàř', 1, 'UTF-8'), + array('fòô', 'fòô bàř', 3, 'UTF-8'), + array('fòô bàř', 'fòô bàř', 7, 'UTF-8'), + array('fòô bàř', 'fòô bàř', 8, 'UTF-8'), + ); + } + + public function lastProvider() + { + return array( + array('', 'foo bar', -5), + array('', 'foo bar', 0), + array('r', 'foo bar', 1), + array('bar', 'foo bar', 3), + array('foo bar', 'foo bar', 7), + array('foo bar', 'foo bar', 8), + array('', 'fòô bàř', -5, 'UTF-8'), + array('', 'fòô bàř', 0, 'UTF-8'), + array('ř', 'fòô bàř', 1, 'UTF-8'), + array('bàř', 'fòô bàř', 3, 'UTF-8'), + array('fòô bàř', 'fòô bàř', 7, 'UTF-8'), + array('fòô bàř', 'fòô bàř', 8, 'UTF-8'), + ); + } + + public function ensureLeftProvider() + { + return array( + array('foobar', 'foobar', 'f'), + array('foobar', 'foobar', 'foo'), + array('foo/foobar', 'foobar', 'foo/'), + array('http://foobar', 'foobar', 'http://'), + array('http://foobar', 'http://foobar', 'http://'), + array('fòôbàř', 'fòôbàř', 'f', 'UTF-8'), + array('fòôbàř', 'fòôbàř', 'fòô', 'UTF-8'), + array('fòô/fòôbàř', 'fòôbàř', 'fòô/', 'UTF-8'), + array('http://fòôbàř', 'fòôbàř', 'http://', 'UTF-8'), + array('http://fòôbàř', 'http://fòôbàř', 'http://', 'UTF-8'), + ); + } + + public function ensureRightProvider() + { + return array( + array('foobar', 'foobar', 'r'), + array('foobar', 'foobar', 'bar'), + array('foobar/bar', 'foobar', '/bar'), + array('foobar.com/', 'foobar', '.com/'), + array('foobar.com/', 'foobar.com/', '.com/'), + array('fòôbàř', 'fòôbàř', 'ř', 'UTF-8'), + array('fòôbàř', 'fòôbàř', 'bàř', 'UTF-8'), + array('fòôbàř/bàř', 'fòôbàř', '/bàř', 'UTF-8'), + array('fòôbàř.com/', 'fòôbàř', '.com/', 'UTF-8'), + array('fòôbàř.com/', 'fòôbàř.com/', '.com/', 'UTF-8'), + ); + } + + public function removeLeftProvider() + { + return array( + array('foo bar', 'foo bar', ''), + array('oo bar', 'foo bar', 'f'), + array('bar', 'foo bar', 'foo '), + array('foo bar', 'foo bar', 'oo'), + array('foo bar', 'foo bar', 'oo bar'), + array('oo bar', 'foo bar', Stringy::create('foo bar')->first(1), 'UTF-8'), + array('oo bar', 'foo bar', Stringy::create('foo bar')->at(0), 'UTF-8'), + array('fòô bàř', 'fòô bàř', '', 'UTF-8'), + array('òô bàř', 'fòô bàř', 'f', 'UTF-8'), + array('bàř', 'fòô bàř', 'fòô ', 'UTF-8'), + array('fòô bàř', 'fòô bàř', 'òô', 'UTF-8'), + array('fòô bàř', 'fòô bàř', 'òô bàř', 'UTF-8') + ); + } + + public function removeRightProvider() + { + return array( + array('foo bar', 'foo bar', ''), + array('foo ba', 'foo bar', 'r'), + array('foo', 'foo bar', ' bar'), + array('foo bar', 'foo bar', 'ba'), + array('foo bar', 'foo bar', 'foo ba'), + array('foo ba', 'foo bar', Stringy::create('foo bar')->last(1), 'UTF-8'), + array('foo ba', 'foo bar', Stringy::create('foo bar')->at(6), 'UTF-8'), + array('fòô bàř', 'fòô bàř', '', 'UTF-8'), + array('fòô bà', 'fòô bàř', 'ř', 'UTF-8'), + array('fòô', 'fòô bàř', ' bàř', 'UTF-8'), + array('fòô bàř', 'fòô bàř', 'bà', 'UTF-8'), + array('fòô bàř', 'fòô bàř', 'fòô bà', 'UTF-8') + ); + } + + public function isAlphaProvider() + { + return array( + array(true, ''), + array(true, 'foobar'), + array(false, 'foo bar'), + array(false, 'foobar2'), + array(true, 'fòôbàř', 'UTF-8'), + array(false, 'fòô bàř', 'UTF-8'), + array(false, 'fòôbàř2', 'UTF-8'), + array(true, 'ҠѨњфгШ', 'UTF-8'), + array(false, 'ҠѨњ¨ˆфгШ', 'UTF-8'), + array(true, '丹尼爾', 'UTF-8') + ); + } + + public function isAlphanumericProvider() + { + return array( + array(true, ''), + array(true, 'foobar1'), + array(false, 'foo bar'), + array(false, 'foobar2"'), + array(false, "\nfoobar\n"), + array(true, 'fòôbàř1', 'UTF-8'), + array(false, 'fòô bàř', 'UTF-8'), + array(false, 'fòôbàř2"', 'UTF-8'), + array(true, 'ҠѨњфгШ', 'UTF-8'), + array(false, 'ҠѨњ¨ˆфгШ', 'UTF-8'), + array(true, '丹尼爾111', 'UTF-8'), + array(true, 'دانيال1', 'UTF-8'), + array(false, 'دانيال1 ', 'UTF-8') + ); + } + + public function isBlankProvider() + { + return array( + array(true, ''), + array(true, ' '), + array(true, "\n\t "), + array(true, "\n\t \v\f"), + array(false, "\n\t a \v\f"), + array(false, "\n\t ' \v\f"), + array(false, "\n\t 2 \v\f"), + array(true, '', 'UTF-8'), + array(true, ' ', 'UTF-8'), // no-break space (U+00A0) + array(true, '           ', 'UTF-8'), // spaces U+2000 to U+200A + array(true, ' ', 'UTF-8'), // narrow no-break space (U+202F) + array(true, ' ', 'UTF-8'), // medium mathematical space (U+205F) + array(true, ' ', 'UTF-8'), // ideographic space (U+3000) + array(false, ' z', 'UTF-8'), + array(false, ' 1', 'UTF-8'), + ); + } + + public function isJsonProvider() + { + return array( + array(true, ''), + array(true, '123'), + array(true, '{"foo": "bar"}'), + array(false, '{"foo":"bar",}'), + array(false, '{"foo"}'), + array(true, '["foo"]'), + array(false, '{"foo": "bar"]'), + array(true, '123', 'UTF-8'), + array(true, '{"fòô": "bàř"}', 'UTF-8'), + array(false, '{"fòô":"bàř",}', 'UTF-8'), + array(false, '{"fòô"}', 'UTF-8'), + array(false, '["fòô": "bàř"]', 'UTF-8'), + array(true, '["fòô"]', 'UTF-8'), + array(false, '{"fòô": "bàř"]', 'UTF-8'), + ); + } + + public function isLowerCaseProvider() + { + return array( + array(true, ''), + array(true, 'foobar'), + array(false, 'foo bar'), + array(false, 'Foobar'), + array(true, 'fòôbàř', 'UTF-8'), + array(false, 'fòôbàř2', 'UTF-8'), + array(false, 'fòô bàř', 'UTF-8'), + array(false, 'fòôbÀŘ', 'UTF-8'), + ); + } + + public function hasLowerCaseProvider() + { + return array( + array(false, ''), + array(true, 'foobar'), + array(false, 'FOO BAR'), + array(true, 'fOO BAR'), + array(true, 'foO BAR'), + array(true, 'FOO BAr'), + array(true, 'Foobar'), + array(false, 'FÒÔBÀŘ', 'UTF-8'), + array(true, 'fòôbàř', 'UTF-8'), + array(true, 'fòôbàř2', 'UTF-8'), + array(true, 'Fòô bàř', 'UTF-8'), + array(true, 'fòôbÀŘ', 'UTF-8'), + ); + } + + public function isSerializedProvider() + { + return array( + array(false, ''), + array(true, 'a:1:{s:3:"foo";s:3:"bar";}'), + array(false, 'a:1:{s:3:"foo";s:3:"bar"}'), + array(true, serialize(array('foo' => 'bar'))), + array(true, 'a:1:{s:5:"fòô";s:5:"bàř";}', 'UTF-8'), + array(false, 'a:1:{s:5:"fòô";s:5:"bàř"}', 'UTF-8'), + array(true, serialize(array('fòô' => 'bár')), 'UTF-8'), + ); + } + + public function isUpperCaseProvider() + { + return array( + array(true, ''), + array(true, 'FOOBAR'), + array(false, 'FOO BAR'), + array(false, 'fOOBAR'), + array(true, 'FÒÔBÀŘ', 'UTF-8'), + array(false, 'FÒÔBÀŘ2', 'UTF-8'), + array(false, 'FÒÔ BÀŘ', 'UTF-8'), + array(false, 'FÒÔBàř', 'UTF-8'), + ); + } + + public function hasUpperCaseProvider() + { + return array( + array(false, ''), + array(true, 'FOOBAR'), + array(false, 'foo bar'), + array(true, 'Foo bar'), + array(true, 'FOo bar'), + array(true, 'foo baR'), + array(true, 'fOOBAR'), + array(false, 'fòôbàř', 'UTF-8'), + array(true, 'FÒÔBÀŘ', 'UTF-8'), + array(true, 'FÒÔBÀŘ2', 'UTF-8'), + array(true, 'fÒÔ BÀŘ', 'UTF-8'), + array(true, 'FÒÔBàř', 'UTF-8'), + ); + } + + public function isHexadecimalProvider() + { + return array( + array(true, ''), + array(true, 'abcdef'), + array(true, 'ABCDEF'), + array(true, '0123456789'), + array(true, '0123456789AbCdEf'), + array(false, '0123456789x'), + array(false, 'ABCDEFx'), + array(true, 'abcdef', 'UTF-8'), + array(true, 'ABCDEF', 'UTF-8'), + array(true, '0123456789', 'UTF-8'), + array(true, '0123456789AbCdEf', 'UTF-8'), + array(false, '0123456789x', 'UTF-8'), + array(false, 'ABCDEFx', 'UTF-8'), + ); + } + + public function countSubstrProvider() + { + return array( + array(0, '', 'foo'), + array(0, 'foo', 'bar'), + array(1, 'foo bar', 'foo'), + array(2, 'foo bar', 'o'), + array(0, '', 'fòô', 'UTF-8'), + array(0, 'fòô', 'bàř', 'UTF-8'), + array(1, 'fòô bàř', 'fòô', 'UTF-8'), + array(2, 'fôòô bàř', 'ô', 'UTF-8'), + array(0, 'fÔÒÔ bàř', 'ô', 'UTF-8'), + array(0, 'foo', 'BAR', false), + array(1, 'foo bar', 'FOo', false), + array(2, 'foo bar', 'O', false), + array(1, 'fòô bàř', 'fÒÔ', false, 'UTF-8'), + array(2, 'fôòô bàř', 'Ô', false, 'UTF-8'), + array(2, 'συγγραφέας', 'Σ', false, 'UTF-8') + ); + } + + public function replaceProvider() + { + return array( + array('', '', '', ''), + array('foo', '', '', 'foo'), + array('foo', '\s', '\s', 'foo'), + array('foo bar', 'foo bar', '', ''), + array('foo bar', 'foo bar', 'f(o)o', '\1'), + array('\1 bar', 'foo bar', 'foo', '\1'), + array('bar', 'foo bar', 'foo ', ''), + array('far bar', 'foo bar', 'foo', 'far'), + array('bar bar', 'foo bar foo bar', 'foo ', ''), + array('', '', '', '', 'UTF-8'), + array('fòô', '', '', 'fòô', 'UTF-8'), + array('fòô', '\s', '\s', 'fòô', 'UTF-8'), + array('fòô bàř', 'fòô bàř', '', '', 'UTF-8'), + array('bàř', 'fòô bàř', 'fòô ', '', 'UTF-8'), + array('far bàř', 'fòô bàř', 'fòô', 'far', 'UTF-8'), + array('bàř bàř', 'fòô bàř fòô bàř', 'fòô ', '', 'UTF-8'), + ); + } + + public function regexReplaceProvider() + { + return array( + array('', '', '', ''), + array('bar', 'foo', 'f[o]+', 'bar'), + array('o bar', 'foo bar', 'f(o)o', '\1'), + array('bar', 'foo bar', 'f[O]+\s', '', 'i'), + array('foo', 'bar', '[[:alpha:]]{3}', 'foo'), + array('', '', '', '', 'msr', 'UTF-8'), + array('bàř', 'fòô ', 'f[òô]+\s', 'bàř', 'msr', 'UTF-8'), + array('fòô', 'bàř', '[[:alpha:]]{3}', 'fòô', 'msr', 'UTF-8') + ); + } + + public function htmlEncodeProvider() + { + return array( + array('&', '&'), + array('"', '"'), + array(''', "'", ENT_QUOTES), + array('<', '<'), + array('>', '>'), + ); + } + + public function htmlDecodeProvider() + { + return array( + array('&', '&'), + array('"', '"'), + array("'", ''', ENT_QUOTES), + array('<', '<'), + array('>', '>'), + ); + } +} diff --git a/vendor/danielstjules/stringy/tests/CreateTest.php b/vendor/danielstjules/stringy/tests/CreateTest.php new file mode 100644 index 0000000..aef9c9f --- /dev/null +++ b/vendor/danielstjules/stringy/tests/CreateTest.php @@ -0,0 +1,16 @@ +assertInstanceOf('Stringy\Stringy', $stringy); + $this->assertEquals('foo bar', (string) $stringy); + $this->assertEquals('UTF-8', $stringy->getEncoding()); + } +} diff --git a/vendor/danielstjules/stringy/tests/StaticStringyTest.php b/vendor/danielstjules/stringy/tests/StaticStringyTest.php new file mode 100644 index 0000000..5d17bc6 --- /dev/null +++ b/vendor/danielstjules/stringy/tests/StaticStringyTest.php @@ -0,0 +1,710 @@ +assertEquals($expected, $result); + } + + /** + * @dataProvider indexOfLastProvider() + */ + public function testIndexOfLast($expected, $str, $subStr, $offset = 0, $encoding = null) + { + $result = S::indexOfLast($str, $subStr, $offset, $encoding); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider charsProvider() + */ + public function testChars($expected, $str, $encoding = null) + { + $result = S::chars($str, $encoding); + $this->assertInternalType('array', $result); + foreach ($result as $char) { + $this->assertInternalType('string', $char); + } + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider upperCaseFirstProvider() + */ + public function testUpperCaseFirst($expected, $str, $encoding = null) + { + $result = S::upperCaseFirst($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider lowerCaseFirstProvider() + */ + public function testLowerCaseFirst($expected, $str, $encoding = null) + { + $result = S::lowerCaseFirst($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider camelizeProvider() + */ + public function testCamelize($expected, $str, $encoding = null) + { + $result = S::camelize($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider upperCamelizeProvider() + */ + public function testUpperCamelize($expected, $str, $encoding = null) + { + $result = S::upperCamelize($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider dasherizeProvider() + */ + public function testDasherize($expected, $str, $encoding = null) + { + $result = S::dasherize($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider underscoredProvider() + */ + public function testUnderscored($expected, $str, $encoding = null) + { + $result = S::underscored($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider swapCaseProvider() + */ + public function testSwapCase($expected, $str, $encoding = null) + { + $result = S::swapCase($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider titleizeProvider() + */ + public function testTitleize($expected, $str, $ignore = null, + $encoding = null) + { + $result = S::titleize($str, $ignore, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider humanizeProvider() + */ + public function testHumanize($expected, $str, $encoding = null) + { + $result = S::humanize($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider tidyProvider() + */ + public function testTidy($expected, $str) + { + $result = S::tidy($str); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider collapseWhitespaceProvider() + */ + public function testCollapseWhitespace($expected, $str, $encoding = null) + { + $result = S::collapseWhitespace($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider toAsciiProvider() + */ + public function testToAscii($expected, $str, $removeUnsupported = true) + { + $result = S::toAscii($str, $removeUnsupported); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider padProvider() + */ + public function testPad($expected, $str, $length, $padStr = ' ', + $padType = 'right', $encoding = null) + { + $result = S::pad($str, $length, $padStr, $padType, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testPadException() + { + $result = S::pad('string', 5, 'foo', 'bar'); + } + + /** + * @dataProvider padLeftProvider() + */ + public function testPadLeft($expected, $str, $length, $padStr = ' ', + $encoding = null) + { + $result = S::padLeft($str, $length, $padStr, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider padRightProvider() + */ + public function testPadRight($expected, $str, $length, $padStr = ' ', + $encoding = null) + { + $result = S::padRight($str, $length, $padStr, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider padBothProvider() + */ + public function testPadBoth($expected, $str, $length, $padStr = ' ', + $encoding = null) + { + $result = S::padBoth($str, $length, $padStr, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider startsWithProvider() + */ + public function testStartsWith($expected, $str, $substring, + $caseSensitive = true, $encoding = null) + { + $result = S::startsWith($str, $substring, $caseSensitive, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider endsWithProvider() + */ + public function testEndsWith($expected, $str, $substring, + $caseSensitive = true, $encoding = null) + { + $result = S::endsWith($str, $substring, $caseSensitive, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider toSpacesProvider() + */ + public function testToSpaces($expected, $str, $tabLength = 4) + { + $result = S::toSpaces($str, $tabLength); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider toTabsProvider() + */ + public function testToTabs($expected, $str, $tabLength = 4) + { + $result = S::toTabs($str, $tabLength); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider toLowerCaseProvider() + */ + public function testToLowerCase($expected, $str, $encoding = null) + { + $result = S::toLowerCase($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider toTitleCaseProvider() + */ + public function testToTitleCase($expected, $str, $encoding = null) + { + $result = S::toTitleCase($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider toUpperCaseProvider() + */ + public function testToUpperCase($expected, $str, $encoding = null) + { + $result = S::toUpperCase($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider slugifyProvider() + */ + public function testSlugify($expected, $str, $replacement = '-') + { + $result = S::slugify($str, $replacement); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider containsProvider() + */ + public function testContains($expected, $haystack, $needle, + $caseSensitive = true, $encoding = null) + { + $result = S::contains($haystack, $needle, $caseSensitive, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider containsAnyProvider() + */ + public function testcontainsAny($expected, $haystack, $needles, + $caseSensitive = true, $encoding = null) + { + $result = S::containsAny($haystack, $needles, $caseSensitive, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider containsAllProvider() + */ + public function testContainsAll($expected, $haystack, $needles, + $caseSensitive = true, $encoding = null) + { + $result = S::containsAll($haystack, $needles, $caseSensitive, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider surroundProvider() + */ + public function testSurround($expected, $str, $substring) + { + $result = S::surround($str, $substring); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider insertProvider() + */ + public function testInsert($expected, $str, $substring, $index, + $encoding = null) + { + $result = S::insert($str, $substring, $index, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider truncateProvider() + */ + public function testTruncate($expected, $str, $length, $substring = '', + $encoding = null) + { + $result = S::truncate($str, $length, $substring, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider safeTruncateProvider() + */ + public function testSafeTruncate($expected, $str, $length, $substring = '', + $encoding = null) + { + $result = S::safeTruncate($str, $length, $substring, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider reverseProvider() + */ + public function testReverse($expected, $str, $encoding = null) + { + $result = S::reverse($str, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider shuffleProvider() + */ + public function testShuffle($str, $encoding = null) + { + $result = S::shuffle($str, $encoding); + $encoding = $encoding ?: mb_internal_encoding(); + + $this->assertInternalType('string', $result); + $this->assertEquals(mb_strlen($str, $encoding), + mb_strlen($result, $encoding)); + + // We'll make sure that the chars are present after shuffle + for ($i = 0; $i < mb_strlen($str, $encoding); $i++) { + $char = mb_substr($str, $i, 1, $encoding); + $countBefore = mb_substr_count($str, $char, $encoding); + $countAfter = mb_substr_count($result, $char, $encoding); + $this->assertEquals($countBefore, $countAfter); + } + } + + /** + * @dataProvider trimProvider() + */ + public function testTrim($expected, $str, $chars = null, $encoding = null) + { + $result = S::trim($str, $chars, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider trimLeftProvider() + */ + public function testTrimLeft($expected, $str, $chars = null, + $encoding = null) + { + $result = S::trimLeft($str, $chars, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider trimRightProvider() + */ + public function testTrimRight($expected, $str, $chars = null, + $encoding = null) + { + $result = S::trimRight($str, $chars, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider longestCommonPrefixProvider() + */ + public function testLongestCommonPrefix($expected, $str, $otherStr, + $encoding = null) + { + $result = S::longestCommonPrefix($str, $otherStr, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider longestCommonSuffixProvider() + */ + public function testLongestCommonSuffix($expected, $str, $otherStr, + $encoding = null) + { + $result = S::longestCommonSuffix($str, $otherStr, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider longestCommonSubstringProvider() + */ + public function testLongestCommonSubstring($expected, $str, $otherStr, + $encoding = null) + { + $result = S::longestCommonSubstring($str, $otherStr, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider lengthProvider() + */ + public function testLength($expected, $str, $encoding = null) + { + $result = S::length($str, $encoding); + $this->assertEquals($expected, $result); + $this->assertInternalType('int', $result); + } + + /** + * @dataProvider substrProvider() + */ + public function testSubstr($expected, $str, $start, $length = null, + $encoding = null) + { + $result = S::substr($str, $start, $length, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider atProvider() + */ + public function testAt($expected, $str, $index, $encoding = null) + { + $result = S::at($str, $index, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider firstProvider() + */ + public function testFirst($expected, $str, $n, $encoding = null) + { + $result = S::first($str, $n, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider lastProvider() + */ + public function testLast($expected, $str, $n, $encoding = null) + { + $result = S::last($str, $n, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider ensureLeftProvider() + */ + public function testEnsureLeft($expected, $str, $substring, $encoding = null) + { + $result = S::ensureLeft($str, $substring, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider ensureRightProvider() + */ + public function testEnsureRight($expected, $str, $substring, $encoding = null) + { + $result = S::ensureRight($str, $substring, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider removeLeftProvider() + */ + public function testRemoveLeft($expected, $str, $substring, $encoding = null) + { + $result = S::removeLeft($str, $substring, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider removeRightProvider() + */ + public function testRemoveRight($expected, $str, $substring, $encoding = null) + { + $result = S::removeRight($str, $substring, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider isAlphaProvider() + */ + public function testIsAlpha($expected, $str, $encoding = null) + { + $result = S::isAlpha($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider isAlphanumericProvider() + */ + public function testIsAlphanumeric($expected, $str, $encoding = null) + { + $result = S::isAlphanumeric($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider isBlankProvider() + */ + public function testIsBlank($expected, $str, $encoding = null) + { + $result = S::isBlank($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider isJsonProvider() + */ + public function testIsJson($expected, $str, $encoding = null) + { + $result = S::isJson($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider isLowerCaseProvider() + */ + public function testIsLowerCase($expected, $str, $encoding = null) + { + $result = S::isLowerCase($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider hasLowerCaseProvider() + */ + public function testHasLowerCase($expected, $str, $encoding = null) + { + $result = S::hasLowerCase($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider isSerializedProvider() + */ + public function testIsSerialized($expected, $str, $encoding = null) + { + $result = S::isSerialized($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider isUpperCaseProvider() + */ + public function testIsUpperCase($expected, $str, $encoding = null) + { + $result = S::isUpperCase($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider hasUpperCaseProvider() + */ + public function testHasUpperCase($expected, $str, $encoding = null) + { + $result = S::hasUpperCase($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider isHexadecimalProvider() + */ + public function testIsHexadecimal($expected, $str, $encoding = null) + { + $result = S::isHexadecimal($str, $encoding); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider countSubstrProvider() + */ + public function testCountSubstr($expected, $str, $substring, + $caseSensitive = true, $encoding = null) + { + $result = S::countSubstr($str, $substring, $caseSensitive, $encoding); + $this->assertInternalType('int', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider replaceProvider() + */ + public function testReplace($expected, $str, $search, $replacement, + $encoding = null) + { + $result = S::replace($str, $search, $replacement, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider regexReplaceProvider() + */ + public function testRegexReplace($expected, $str, $pattern, $replacement, + $options = 'msr', $encoding = null) + { + $result = S::regexReplace($str, $pattern, $replacement, $options, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider htmlEncodeProvider() + */ + public function testHtmlEncode($expected, $str, $flags = ENT_COMPAT, $encoding = null) + { + $result = S::htmlEncode($str, $flags, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider htmlDecodeProvider() + */ + public function testHtmlDecode($expected, $str, $flags = ENT_COMPAT, $encoding = null) + { + $result = S::htmlDecode($str, $flags, $encoding); + $this->assertInternalType('string', $result); + $this->assertEquals($expected, $result); + } +} diff --git a/vendor/danielstjules/stringy/tests/StringyTest.php b/vendor/danielstjules/stringy/tests/StringyTest.php new file mode 100644 index 0000000..b5edc43 --- /dev/null +++ b/vendor/danielstjules/stringy/tests/StringyTest.php @@ -0,0 +1,994 @@ +assertStringy($stringy); + $this->assertEquals('foo bar', (string) $stringy); + $this->assertEquals('UTF-8', $stringy->getEncoding()); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testConstructWithArray() + { + (string) new S(array()); + $this->fail('Expecting exception when the constructor is passed an array'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testMissingToString() + { + (string) new S(new stdClass()); + $this->fail('Expecting exception when the constructor is passed an ' . + 'object without a __toString method'); + } + + /** + * @dataProvider toStringProvider() + */ + public function testToString($expected, $str) + { + $this->assertEquals($expected, (string) new S($str)); + } + + public function toStringProvider() + { + return array( + array('', null), + array('', false), + array('1', true), + array('-9', -9), + array('1.18', 1.18), + array(' string ', ' string ') + ); + } + + public function testCreate() + { + $stringy = S::create('foo bar', 'UTF-8'); + $this->assertStringy($stringy); + $this->assertEquals('foo bar', (string) $stringy); + $this->assertEquals('UTF-8', $stringy->getEncoding()); + } + + public function testChaining() + { + $stringy = S::create("Fòô Bàř", 'UTF-8'); + $this->assertStringy($stringy); + $result = $stringy->collapseWhitespace()->swapCase()->upperCaseFirst(); + $this->assertEquals('FÒÔ bÀŘ', $result); + } + + public function testCount() + { + $stringy = S::create('Fòô', 'UTF-8'); + $this->assertEquals(3, $stringy->count()); + $this->assertEquals(3, count($stringy)); + } + + public function testGetIterator() + { + $stringy = S::create('Fòô Bàř', 'UTF-8'); + + $valResult = array(); + foreach ($stringy as $char) { + $valResult[] = $char; + } + + $keyValResult = array(); + foreach ($stringy as $pos => $char) { + $keyValResult[$pos] = $char; + } + + $this->assertEquals(array('F', 'ò', 'ô', ' ', 'B', 'à', 'ř'), $valResult); + $this->assertEquals(array('F', 'ò', 'ô', ' ', 'B', 'à', 'ř'), $keyValResult); + } + + /** + * @dataProvider offsetExistsProvider() + */ + public function testOffsetExists($expected, $offset) + { + $stringy = S::create('fòô', 'UTF-8'); + $this->assertEquals($expected, $stringy->offsetExists($offset)); + $this->assertEquals($expected, isset($stringy[$offset])); + } + + public function offsetExistsProvider() + { + return array( + array(true, 0), + array(true, 2), + array(false, 3), + array(true, -1), + array(true, -3), + array(false, -4) + ); + } + + public function testOffsetGet() + { + $stringy = S::create('fòô', 'UTF-8'); + + $this->assertEquals('f', $stringy->offsetGet(0)); + $this->assertEquals('ô', $stringy->offsetGet(2)); + + $this->assertEquals('ô', $stringy[2]); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testOffsetGetOutOfBounds() + { + $stringy = S::create('fòô', 'UTF-8'); + $test = $stringy[3]; + } + + /** + * @expectedException \Exception + */ + public function testOffsetSet() + { + $stringy = S::create('fòô', 'UTF-8'); + $stringy[1] = 'invalid'; + } + + /** + * @expectedException \Exception + */ + public function testOffsetUnset() + { + $stringy = S::create('fòô', 'UTF-8'); + unset($stringy[1]); + } + + /** + * @dataProvider indexOfProvider() + */ + public function testIndexOf($expected, $str, $subStr, $offset = 0, $encoding = null) + { + $result = S::create($str, $encoding)->indexOf($subStr, $offset); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider indexOfLastProvider() + */ + public function testIndexOfLast($expected, $str, $subStr, $offset = 0, $encoding = null) + { + $result = S::create($str, $encoding)->indexOfLast($subStr, $offset); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider charsProvider() + */ + public function testChars($expected, $str, $encoding = null) + { + $result = S::create($str, $encoding)->chars(); + $this->assertInternalType('array', $result); + foreach ($result as $char) { + $this->assertInternalType('string', $char); + } + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider upperCaseFirstProvider() + */ + public function testUpperCaseFirst($expected, $str, $encoding = null) + { + $result = S::create($str, $encoding)->upperCaseFirst(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider lowerCaseFirstProvider() + */ + public function testLowerCaseFirst($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->lowerCaseFirst(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider camelizeProvider() + */ + public function testCamelize($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->camelize(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider upperCamelizeProvider() + */ + public function testUpperCamelize($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->upperCamelize(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider dasherizeProvider() + */ + public function testDasherize($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->dasherize(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider underscoredProvider() + */ + public function testUnderscored($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->underscored(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider delimitProvider() + */ + public function testDelimit($expected, $str, $delimiter, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->delimit($delimiter); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider swapCaseProvider() + */ + public function testSwapCase($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->swapCase(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider titleizeProvider() + */ + public function testTitleize($expected, $str, $ignore = null, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->titleize($ignore); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider humanizeProvider() + */ + public function testHumanize($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->humanize(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider tidyProvider() + */ + public function testTidy($expected, $str) + { + $stringy = S::create($str); + $result = $stringy->tidy(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider collapseWhitespaceProvider() + */ + public function testCollapseWhitespace($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->collapseWhitespace(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider toAsciiProvider() + */ + public function testToAscii($expected, $str, $removeUnsupported = true) + { + $stringy = S::create($str); + $result = $stringy->toAscii($removeUnsupported); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider padProvider() + */ + public function testPad($expected, $str, $length, $padStr = ' ', + $padType = 'right', $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->pad($length, $padStr, $padType); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testPadException() + { + $stringy = S::create('foo'); + $result = $stringy->pad(5, 'foo', 'bar'); + } + + /** + * @dataProvider padLeftProvider() + */ + public function testPadLeft($expected, $str, $length, $padStr = ' ', + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->padLeft($length, $padStr); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider padRightProvider() + */ + public function testPadRight($expected, $str, $length, $padStr = ' ', + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->padRight($length, $padStr); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider padBothProvider() + */ + public function testPadBoth($expected, $str, $length, $padStr = ' ', + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->padBoth($length, $padStr); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider startsWithProvider() + */ + public function testStartsWith($expected, $str, $substring, + $caseSensitive = true, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->startsWith($substring, $caseSensitive); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider endsWithProvider() + */ + public function testEndsWith($expected, $str, $substring, + $caseSensitive = true, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->endsWith($substring, $caseSensitive); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider toSpacesProvider() + */ + public function testToSpaces($expected, $str, $tabLength = 4) + { + $stringy = S::create($str); + $result = $stringy->toSpaces($tabLength); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider toTabsProvider() + */ + public function testToTabs($expected, $str, $tabLength = 4) + { + $stringy = S::create($str); + $result = $stringy->toTabs($tabLength); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider toLowerCaseProvider() + */ + public function testToLowerCase($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->toLowerCase(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider toTitleCaseProvider() + */ + public function testToTitleCase($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->toTitleCase(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider toUpperCaseProvider() + */ + public function testToUpperCase($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->toUpperCase(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider slugifyProvider() + */ + public function testSlugify($expected, $str, $replacement = '-') + { + $stringy = S::create($str); + $result = $stringy->slugify($replacement); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider containsProvider() + */ + public function testContains($expected, $haystack, $needle, + $caseSensitive = true, $encoding = null) + { + $stringy = S::create($haystack, $encoding); + $result = $stringy->contains($needle, $caseSensitive); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($haystack, $stringy); + } + + /** + * @dataProvider containsAnyProvider() + */ + public function testcontainsAny($expected, $haystack, $needles, + $caseSensitive = true, $encoding = null) + { + $stringy = S::create($haystack, $encoding); + $result = $stringy->containsAny($needles, $caseSensitive); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($haystack, $stringy); + } + + /** + * @dataProvider containsAllProvider() + */ + public function testContainsAll($expected, $haystack, $needles, + $caseSensitive = true, $encoding = null) + { + $stringy = S::create($haystack, $encoding); + $result = $stringy->containsAll($needles, $caseSensitive); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($haystack, $stringy); + } + + /** + * @dataProvider surroundProvider() + */ + public function testSurround($expected, $str, $substring) + { + $stringy = S::create($str); + $result = $stringy->surround($substring); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider insertProvider() + */ + public function testInsert($expected, $str, $substring, $index, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->insert($substring, $index); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider truncateProvider() + */ + public function testTruncate($expected, $str, $length, $substring = '', + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->truncate($length, $substring); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider safeTruncateProvider() + */ + public function testSafeTruncate($expected, $str, $length, $substring = '', + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->safeTruncate($length, $substring); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider reverseProvider() + */ + public function testReverse($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->reverse(); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider shuffleProvider() + */ + public function testShuffle($str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $encoding = $encoding ?: mb_internal_encoding(); + $result = $stringy->shuffle(); + + $this->assertStringy($result); + $this->assertEquals($str, $stringy); + $this->assertEquals(mb_strlen($str, $encoding), + mb_strlen($result, $encoding)); + + // We'll make sure that the chars are present after shuffle + for ($i = 0; $i < mb_strlen($str, $encoding); $i++) { + $char = mb_substr($str, $i, 1, $encoding); + $countBefore = mb_substr_count($str, $char, $encoding); + $countAfter = mb_substr_count($result, $char, $encoding); + $this->assertEquals($countBefore, $countAfter); + } + } + + /** + * @dataProvider trimProvider() + */ + public function testTrim($expected, $str, $chars = null, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->trim($chars); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider trimLeftProvider() + */ + public function testTrimLeft($expected, $str, $chars = null, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->trimLeft($chars); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider trimRightProvider() + */ + public function testTrimRight($expected, $str, $chars = null, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->trimRight($chars); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider longestCommonPrefixProvider() + */ + public function testLongestCommonPrefix($expected, $str, $otherStr, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->longestCommonPrefix($otherStr); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider longestCommonSuffixProvider() + */ + public function testLongestCommonSuffix($expected, $str, $otherStr, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->longestCommonSuffix($otherStr); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider longestCommonSubstringProvider() + */ + public function testLongestCommonSubstring($expected, $str, $otherStr, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->longestCommonSubstring($otherStr); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider lengthProvider() + */ + public function testLength($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->length(); + $this->assertInternalType('int', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider substrProvider() + */ + public function testSubstr($expected, $str, $start, $length = null, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->substr($start, $length); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider atProvider() + */ + public function testAt($expected, $str, $index, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->at($index); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider firstProvider() + */ + public function testFirst($expected, $str, $n, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->first($n); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider lastProvider() + */ + public function testLast($expected, $str, $n, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->last($n); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider ensureLeftProvider() + */ + public function testEnsureLeft($expected, $str, $substring, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->ensureLeft($substring); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider ensureRightProvider() + */ + public function testEnsureRight($expected, $str, $substring, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->ensureRight($substring); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider removeLeftProvider() + */ + public function testRemoveLeft($expected, $str, $substring, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->removeLeft($substring); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider removeRightProvider() + */ + public function testRemoveRight($expected, $str, $substring, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->removeRight($substring); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider isAlphaProvider() + */ + public function testIsAlpha($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->isAlpha(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider isAlphanumericProvider() + */ + public function testIsAlphanumeric($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->isAlphanumeric(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider isBlankProvider() + */ + public function testIsBlank($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->isBlank(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider isJsonProvider() + */ + public function testIsJson($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->isJson(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider isLowerCaseProvider() + */ + public function testIsLowerCase($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->isLowerCase(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider hasLowerCaseProvider() + */ + public function testHasLowerCase($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->hasLowerCase(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider isSerializedProvider() + */ + public function testIsSerialized($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->isSerialized(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider isUpperCaseProvider() + */ + public function testIsUpperCase($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->isUpperCase(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider hasUpperCaseProvider() + */ + public function testHasUpperCase($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->hasUpperCase(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider isHexadecimalProvider() + */ + public function testIsHexadecimal($expected, $str, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->isHexadecimal(); + $this->assertInternalType('boolean', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider countSubstrProvider() + */ + public function testCountSubstr($expected, $str, $substring, + $caseSensitive = true, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->countSubstr($substring, $caseSensitive); + $this->assertInternalType('int', $result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider replaceProvider() + */ + public function testReplace($expected, $str, $search, $replacement, + $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->replace($search, $replacement); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider regexReplaceProvider() + */ + public function testregexReplace($expected, $str, $pattern, $replacement, + $options = 'msr', $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->regexReplace($pattern, $replacement, $options); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider htmlEncodeProvider() + */ + public function testHtmlEncode($expected, $str, $flags = ENT_COMPAT, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->htmlEncode($flags); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } + + /** + * @dataProvider htmlDecodeProvider() + */ + public function testHtmlDecode($expected, $str, $flags = ENT_COMPAT, $encoding = null) + { + $stringy = S::create($str, $encoding); + $result = $stringy->htmlDecode($flags); + $this->assertStringy($result); + $this->assertEquals($expected, $result); + $this->assertEquals($str, $stringy); + } +} diff --git a/vendor/doctrine/inflector/.gitignore b/vendor/doctrine/inflector/.gitignore new file mode 100644 index 0000000..f2cb7f8 --- /dev/null +++ b/vendor/doctrine/inflector/.gitignore @@ -0,0 +1,4 @@ +vendor/ +composer.lock +composer.phar +phpunit.xml diff --git a/vendor/doctrine/inflector/.travis.yml b/vendor/doctrine/inflector/.travis.yml new file mode 100644 index 0000000..6b1d8ff --- /dev/null +++ b/vendor/doctrine/inflector/.travis.yml @@ -0,0 +1,11 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + +install: + - composer --prefer-source install diff --git a/vendor/doctrine/inflector/LICENSE b/vendor/doctrine/inflector/LICENSE new file mode 100644 index 0000000..5e781fc --- /dev/null +++ b/vendor/doctrine/inflector/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006-2013 Doctrine Project + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/doctrine/inflector/README.md b/vendor/doctrine/inflector/README.md new file mode 100644 index 0000000..acb55a0 --- /dev/null +++ b/vendor/doctrine/inflector/README.md @@ -0,0 +1,6 @@ +# Doctrine Inflector + +Doctrine Inflector is a small library that can perform string manipulations +with regard to upper-/lowercase and singular/plural forms of words. + +[![Build Status](https://travis-ci.org/doctrine/inflector.svg?branch=master)](https://travis-ci.org/doctrine/inflector) diff --git a/vendor/doctrine/inflector/composer.json b/vendor/doctrine/inflector/composer.json new file mode 100644 index 0000000..a29c68c --- /dev/null +++ b/vendor/doctrine/inflector/composer.json @@ -0,0 +1,29 @@ +{ + "name": "doctrine/inflector", + "type": "library", + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "keywords": ["string", "inflection", "singularize", "pluralize"], + "homepage": "http://www.doctrine-project.org", + "license": "MIT", + "authors": [ + {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, + {"name": "Roman Borschel", "email": "roman@code-factory.org"}, + {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, + {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, + {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} + ], + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "autoload": { + "psr-0": { "Doctrine\\Common\\Inflector\\": "lib/" } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php b/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php new file mode 100644 index 0000000..b007b21 --- /dev/null +++ b/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php @@ -0,0 +1,415 @@ +. + */ + +namespace Doctrine\Common\Inflector; + +/** + * Doctrine inflector has static methods for inflecting text. + * + * The methods in these classes are from several different sources collected + * across several different php projects and several different authors. The + * original author names and emails are not known. + * + * Pluralize & Singularize implementation are borrowed from CakePHP with some modifications. + * + * @link www.doctrine-project.org + * @since 1.0 + * @author Konsta Vesterinen + * @author Jonathan H. Wage + */ +class Inflector +{ + /** + * Plural inflector rules. + * + * @var array + */ + private static $plural = array( + 'rules' => array( + '/(s)tatus$/i' => '\1\2tatuses', + '/(quiz)$/i' => '\1zes', + '/^(ox)$/i' => '\1\2en', + '/([m|l])ouse$/i' => '\1ice', + '/(matr|vert|ind)(ix|ex)$/i' => '\1ices', + '/(x|ch|ss|sh)$/i' => '\1es', + '/([^aeiouy]|qu)y$/i' => '\1ies', + '/(hive)$/i' => '\1s', + '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', + '/sis$/i' => 'ses', + '/([ti])um$/i' => '\1a', + '/(p)erson$/i' => '\1eople', + '/(m)an$/i' => '\1en', + '/(c)hild$/i' => '\1hildren', + '/(buffal|tomat)o$/i' => '\1\2oes', + '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i', + '/us$/i' => 'uses', + '/(alias)$/i' => '\1es', + '/(ax|cris|test)is$/i' => '\1es', + '/s$/' => 's', + '/^$/' => '', + '/$/' => 's', + ), + 'uninflected' => array( + '.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'people', 'cookie' + ), + 'irregular' => array( + 'atlas' => 'atlases', + 'beef' => 'beefs', + 'brother' => 'brothers', + 'cafe' => 'cafes', + 'child' => 'children', + 'cookie' => 'cookies', + 'corpus' => 'corpuses', + 'cow' => 'cows', + 'criteria' => 'criterion', + 'ganglion' => 'ganglions', + 'genie' => 'genies', + 'genus' => 'genera', + 'graffito' => 'graffiti', + 'hoof' => 'hoofs', + 'human' => 'humans', + 'loaf' => 'loaves', + 'man' => 'men', + 'money' => 'monies', + 'mongoose' => 'mongooses', + 'move' => 'moves', + 'mythos' => 'mythoi', + 'niche' => 'niches', + 'numen' => 'numina', + 'occiput' => 'occiputs', + 'octopus' => 'octopuses', + 'opus' => 'opuses', + 'ox' => 'oxen', + 'penis' => 'penises', + 'person' => 'people', + 'sex' => 'sexes', + 'soliloquy' => 'soliloquies', + 'testis' => 'testes', + 'trilby' => 'trilbys', + 'turf' => 'turfs', + ) + ); + + /** + * Singular inflector rules. + * + * @var array + */ + private static $singular = array( + 'rules' => array( + '/(s)tatuses$/i' => '\1\2tatus', + '/^(.*)(menu)s$/i' => '\1\2', + '/(quiz)zes$/i' => '\\1', + '/(matr)ices$/i' => '\1ix', + '/(vert|ind)ices$/i' => '\1ex', + '/^(ox)en/i' => '\1', + '/(alias)(es)*$/i' => '\1', + '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us', + '/([ftw]ax)es/i' => '\1', + '/(cris|ax|test)es$/i' => '\1is', + '/(shoe|slave)s$/i' => '\1', + '/(o)es$/i' => '\1', + '/ouses$/' => 'ouse', + '/([^a])uses$/' => '\1us', + '/([m|l])ice$/i' => '\1ouse', + '/(x|ch|ss|sh)es$/i' => '\1', + '/(m)ovies$/i' => '\1\2ovie', + '/(s)eries$/i' => '\1\2eries', + '/([^aeiouy]|qu)ies$/i' => '\1y', + '/([lr])ves$/i' => '\1f', + '/(tive)s$/i' => '\1', + '/(hive)s$/i' => '\1', + '/(drive)s$/i' => '\1', + '/([^fo])ves$/i' => '\1fe', + '/(^analy)ses$/i' => '\1sis', + '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', + '/([ti])a$/i' => '\1um', + '/(p)eople$/i' => '\1\2erson', + '/(m)en$/i' => '\1an', + '/(c)hildren$/i' => '\1\2hild', + '/(n)ews$/i' => '\1\2ews', + '/eaus$/' => 'eau', + '/^(.*us)$/' => '\\1', + '/s$/i' => '', + ), + 'uninflected' => array( + '.*[nrlm]ese', + '.*deer', + '.*fish', + '.*measles', + '.*ois', + '.*pox', + '.*sheep', + '.*ss', + ), + 'irregular' => array( + 'criterion' => 'criteria', + 'curves' => 'curve', + 'foes' => 'foe', + 'waves' => 'wave', + ) + ); + + /** + * Words that should not be inflected. + * + * @var array + */ + private static $uninflected = array( + 'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', + 'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps', + 'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder', + 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti', + 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', + 'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media', + 'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese', + 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', + 'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', + 'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'staff', 'swine', + 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting', + 'wildebeest', 'Yengeese' + ); + + /** + * Method cache array. + * + * @var array + */ + private static $cache = array(); + + /** + * The initial state of Inflector so reset() works. + * + * @var array + */ + private static $initialState = array(); + + /** + * Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'. + * + * @param string $word The word to tableize. + * + * @return string The tableized word. + */ + public static function tableize($word) + { + return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word)); + } + + /** + * Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'. + * + * @param string $word The word to classify. + * + * @return string The classified word. + */ + public static function classify($word) + { + return str_replace(" ", "", ucwords(strtr($word, "_-", " "))); + } + + /** + * Camelizes a word. This uses the classify() method and turns the first character to lowercase. + * + * @param string $word The word to camelize. + * + * @return string The camelized word. + */ + public static function camelize($word) + { + return lcfirst(self::classify($word)); + } + + /** + * Clears Inflectors inflected value caches, and resets the inflection + * rules to the initial values. + * + * @return void + */ + public static function reset() + { + if (empty(self::$initialState)) { + self::$initialState = get_class_vars('Inflector'); + + return; + } + + foreach (self::$initialState as $key => $val) { + if ($key != 'initialState') { + self::${$key} = $val; + } + } + } + + /** + * Adds custom inflection $rules, of either 'plural' or 'singular' $type. + * + * ### Usage: + * + * {{{ + * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables')); + * Inflector::rules('plural', array( + * 'rules' => array('/^(inflect)ors$/i' => '\1ables'), + * 'uninflected' => array('dontinflectme'), + * 'irregular' => array('red' => 'redlings') + * )); + * }}} + * + * @param string $type The type of inflection, either 'plural' or 'singular' + * @param array $rules An array of rules to be added. + * @param boolean $reset If true, will unset default inflections for all + * new rules that are being defined in $rules. + * + * @return void + */ + public static function rules($type, $rules, $reset = false) + { + foreach ($rules as $rule => $pattern) { + if ( ! is_array($pattern)) { + continue; + } + + if ($reset) { + self::${$type}[$rule] = $pattern; + } else { + self::${$type}[$rule] = ($rule === 'uninflected') + ? array_merge($pattern, self::${$type}[$rule]) + : $pattern + self::${$type}[$rule]; + } + + unset($rules[$rule], self::${$type}['cache' . ucfirst($rule)]); + + if (isset(self::${$type}['merged'][$rule])) { + unset(self::${$type}['merged'][$rule]); + } + + if ($type === 'plural') { + self::$cache['pluralize'] = self::$cache['tableize'] = array(); + } elseif ($type === 'singular') { + self::$cache['singularize'] = array(); + } + } + + self::${$type}['rules'] = $rules + self::${$type}['rules']; + } + + /** + * Returns a word in plural form. + * + * @param string $word The word in singular form. + * + * @return string The word in plural form. + */ + public static function pluralize($word) + { + if (isset(self::$cache['pluralize'][$word])) { + return self::$cache['pluralize'][$word]; + } + + if (!isset(self::$plural['merged']['irregular'])) { + self::$plural['merged']['irregular'] = self::$plural['irregular']; + } + + if (!isset(self::$plural['merged']['uninflected'])) { + self::$plural['merged']['uninflected'] = array_merge(self::$plural['uninflected'], self::$uninflected); + } + + if (!isset(self::$plural['cacheUninflected']) || !isset(self::$plural['cacheIrregular'])) { + self::$plural['cacheUninflected'] = '(?:' . implode('|', self::$plural['merged']['uninflected']) . ')'; + self::$plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$plural['merged']['irregular'])) . ')'; + } + + if (preg_match('/(.*)\\b(' . self::$plural['cacheIrregular'] . ')$/i', $word, $regs)) { + self::$cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$plural['merged']['irregular'][strtolower($regs[2])], 1); + + return self::$cache['pluralize'][$word]; + } + + if (preg_match('/^(' . self::$plural['cacheUninflected'] . ')$/i', $word, $regs)) { + self::$cache['pluralize'][$word] = $word; + + return $word; + } + + foreach (self::$plural['rules'] as $rule => $replacement) { + if (preg_match($rule, $word)) { + self::$cache['pluralize'][$word] = preg_replace($rule, $replacement, $word); + + return self::$cache['pluralize'][$word]; + } + } + } + + /** + * Returns a word in singular form. + * + * @param string $word The word in plural form. + * + * @return string The word in singular form. + */ + public static function singularize($word) + { + if (isset(self::$cache['singularize'][$word])) { + return self::$cache['singularize'][$word]; + } + + if (!isset(self::$singular['merged']['uninflected'])) { + self::$singular['merged']['uninflected'] = array_merge( + self::$singular['uninflected'], + self::$uninflected + ); + } + + if (!isset(self::$singular['merged']['irregular'])) { + self::$singular['merged']['irregular'] = array_merge( + self::$singular['irregular'], + array_flip(self::$plural['irregular']) + ); + } + + if (!isset(self::$singular['cacheUninflected']) || !isset(self::$singular['cacheIrregular'])) { + self::$singular['cacheUninflected'] = '(?:' . join('|', self::$singular['merged']['uninflected']) . ')'; + self::$singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$singular['merged']['irregular'])) . ')'; + } + + if (preg_match('/(.*)\\b(' . self::$singular['cacheIrregular'] . ')$/i', $word, $regs)) { + self::$cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$singular['merged']['irregular'][strtolower($regs[2])], 1); + + return self::$cache['singularize'][$word]; + } + + if (preg_match('/^(' . self::$singular['cacheUninflected'] . ')$/i', $word, $regs)) { + self::$cache['singularize'][$word] = $word; + + return $word; + } + + foreach (self::$singular['rules'] as $rule => $replacement) { + if (preg_match($rule, $word)) { + self::$cache['singularize'][$word] = preg_replace($rule, $replacement, $word); + + return self::$cache['singularize'][$word]; + } + } + + self::$cache['singularize'][$word] = $word; + + return $word; + } +} diff --git a/vendor/doctrine/inflector/phpunit.xml.dist b/vendor/doctrine/inflector/phpunit.xml.dist new file mode 100644 index 0000000..ef07faa --- /dev/null +++ b/vendor/doctrine/inflector/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + ./tests/Doctrine/ + + + + + + ./lib/Doctrine/ + + + + + + performance + + + diff --git a/vendor/doctrine/inflector/tests/Doctrine/Tests/Common/Inflector/InflectorTest.php b/vendor/doctrine/inflector/tests/Doctrine/Tests/Common/Inflector/InflectorTest.php new file mode 100644 index 0000000..a8a075d --- /dev/null +++ b/vendor/doctrine/inflector/tests/Doctrine/Tests/Common/Inflector/InflectorTest.php @@ -0,0 +1,210 @@ +assertEquals( + $singular, + Inflector::singularize($plural), + "'$plural' should be singularized to '$singular'" + ); + } + + /** + * testInflectingPlurals method + * + * @dataProvider dataSampleWords + * @return void + */ + public function testInflectingPlurals($singular, $plural) + { + $this->assertEquals( + $plural, + Inflector::pluralize($singular), + "'$singular' should be pluralized to '$plural'" + ); + } + + /** + * testCustomPluralRule method + * + * @return void + */ + public function testCustomPluralRule() + { + Inflector::reset(); + Inflector::rules('plural', array('/^(custom)$/i' => '\1izables')); + + $this->assertEquals(Inflector::pluralize('custom'), 'customizables'); + + Inflector::rules('plural', array('uninflected' => array('uninflectable'))); + + $this->assertEquals(Inflector::pluralize('uninflectable'), 'uninflectable'); + + Inflector::rules('plural', array( + 'rules' => array('/^(alert)$/i' => '\1ables'), + 'uninflected' => array('noflect', 'abtuse'), + 'irregular' => array('amaze' => 'amazable', 'phone' => 'phonezes') + )); + + $this->assertEquals(Inflector::pluralize('noflect'), 'noflect'); + $this->assertEquals(Inflector::pluralize('abtuse'), 'abtuse'); + $this->assertEquals(Inflector::pluralize('alert'), 'alertables'); + $this->assertEquals(Inflector::pluralize('amaze'), 'amazable'); + $this->assertEquals(Inflector::pluralize('phone'), 'phonezes'); + } + + /** + * testCustomSingularRule method + * + * @return void + */ + public function testCustomSingularRule() + { + Inflector::reset(); + Inflector::rules('singular', array('/(eple)r$/i' => '\1', '/(jente)r$/i' => '\1')); + + $this->assertEquals(Inflector::singularize('epler'), 'eple'); + $this->assertEquals(Inflector::singularize('jenter'), 'jente'); + + Inflector::rules('singular', array( + 'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'), + 'uninflected' => array('singulars'), + 'irregular' => array('spins' => 'spinor') + )); + + $this->assertEquals(Inflector::singularize('inflectors'), 'inflecta'); + $this->assertEquals(Inflector::singularize('contributors'), 'contributa'); + $this->assertEquals(Inflector::singularize('spins'), 'spinor'); + $this->assertEquals(Inflector::singularize('singulars'), 'singulars'); + } + + /** + * test that setting new rules clears the inflector caches. + * + * @return void + */ + public function testRulesClearsCaches() + { + Inflector::reset(); + + $this->assertEquals(Inflector::singularize('Bananas'), 'Banana'); + $this->assertEquals(Inflector::pluralize('Banana'), 'Bananas'); + + Inflector::rules('singular', array( + 'rules' => array('/(.*)nas$/i' => '\1zzz') + )); + + $this->assertEquals('Banazzz', Inflector::singularize('Bananas'), 'Was inflected with old rules.'); + + Inflector::rules('plural', array( + 'rules' => array('/(.*)na$/i' => '\1zzz'), + 'irregular' => array('corpus' => 'corpora') + )); + + $this->assertEquals(Inflector::pluralize('Banana'), 'Banazzz', 'Was inflected with old rules.'); + $this->assertEquals(Inflector::pluralize('corpus'), 'corpora', 'Was inflected with old irregular form.'); + } + + /** + * Test resetting inflection rules. + * + * @return void + */ + public function testCustomRuleWithReset() + { + Inflector::reset(); + + $uninflected = array('atlas', 'lapis', 'onibus', 'pires', 'virus', '.*x'); + $pluralIrregular = array('as' => 'ases'); + + Inflector::rules('singular', array( + 'rules' => array('/^(.*)(a|e|o|u)is$/i' => '\1\2l'), + 'uninflected' => $uninflected, + ), true); + + Inflector::rules('plural', array( + 'rules' => array( + '/^(.*)(a|e|o|u)l$/i' => '\1\2is', + ), + 'uninflected' => $uninflected, + 'irregular' => $pluralIrregular + ), true); + + $this->assertEquals(Inflector::pluralize('Alcool'), 'Alcoois'); + $this->assertEquals(Inflector::pluralize('Atlas'), 'Atlas'); + $this->assertEquals(Inflector::singularize('Alcoois'), 'Alcool'); + $this->assertEquals(Inflector::singularize('Atlas'), 'Atlas'); + } +} + diff --git a/vendor/doctrine/inflector/tests/Doctrine/Tests/DoctrineTestCase.php b/vendor/doctrine/inflector/tests/Doctrine/Tests/DoctrineTestCase.php new file mode 100644 index 0000000..e8323d2 --- /dev/null +++ b/vendor/doctrine/inflector/tests/Doctrine/Tests/DoctrineTestCase.php @@ -0,0 +1,10 @@ + composer-installer.php + hhvm composer-installer.php + hhvm -v ResourceLimit.SocketDefaultTimeout=30 -v Http.SlowQueryThreshold=30000 composer.phar update --prefer-source +elif [ "$TRAVIS_PHP_VERSION" = '5.3.3' ] ; then + composer self-update + composer update --prefer-source --no-dev + composer dump-autoload +else + composer self-update + composer update --prefer-source +fi diff --git a/vendor/doctrine/instantiator/.travis.yml b/vendor/doctrine/instantiator/.travis.yml new file mode 100644 index 0000000..7f1ec5f --- /dev/null +++ b/vendor/doctrine/instantiator/.travis.yml @@ -0,0 +1,22 @@ +language: php + +php: + - 5.3.3 + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + +before_script: + - ./.travis.install.sh + - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then PHPUNIT_FLAGS="--coverage-clover coverage.clover"; else PHPUNIT_FLAGS=""; fi + +script: + - if [ $TRAVIS_PHP_VERSION = '5.3.3' ]; then phpunit; fi + - if [ $TRAVIS_PHP_VERSION != '5.3.3' ]; then ./vendor/bin/phpunit $PHPUNIT_FLAGS; fi + - if [ $TRAVIS_PHP_VERSION != '5.3.3' ]; then ./vendor/bin/phpcs --standard=PSR2 ./src/ ./tests/; fi + - if [[ $TRAVIS_PHP_VERSION != '5.3.3' && $TRAVIS_PHP_VERSION != '5.4.29' && $TRAVIS_PHP_VERSION != '5.5.13' ]]; then php -n ./vendor/bin/athletic -p ./tests/DoctrineTest/InstantiatorPerformance/ -f GroupedFormatter; fi + +after_script: + - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi diff --git a/vendor/doctrine/instantiator/CONTRIBUTING.md b/vendor/doctrine/instantiator/CONTRIBUTING.md new file mode 100644 index 0000000..75b84b2 --- /dev/null +++ b/vendor/doctrine/instantiator/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contributing + + * Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) + * The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php) + * Any contribution must provide tests for additional introduced conditions + * Any un-confirmed issue needs a failing test case before being accepted + * Pull requests must be sent from a new hotfix/feature branch, not from `master`. + +## Installation + +To install the project and run the tests, you need to clone it first: + +```sh +$ git clone git://github.com/doctrine/instantiator.git +``` + +You will then need to run a composer installation: + +```sh +$ cd Instantiator +$ curl -s https://getcomposer.org/installer | php +$ php composer.phar update +``` + +## Testing + +The PHPUnit version to be used is the one installed as a dev- dependency via composer: + +```sh +$ ./vendor/bin/phpunit +``` + +Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement +won't be merged. + diff --git a/vendor/doctrine/instantiator/LICENSE b/vendor/doctrine/instantiator/LICENSE new file mode 100644 index 0000000..4d983d1 --- /dev/null +++ b/vendor/doctrine/instantiator/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Doctrine Project + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/doctrine/instantiator/README.md b/vendor/doctrine/instantiator/README.md new file mode 100644 index 0000000..393ec7c --- /dev/null +++ b/vendor/doctrine/instantiator/README.md @@ -0,0 +1,40 @@ +# Instantiator + +This library provides a way of avoiding usage of constructors when instantiating PHP classes. + +[![Build Status](https://travis-ci.org/doctrine/instantiator.svg?branch=master)](https://travis-ci.org/doctrine/instantiator) +[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master) +[![Dependency Status](https://www.versioneye.com/package/php--doctrine--instantiator/badge.svg)](https://www.versioneye.com/package/php--doctrine--instantiator) +[![HHVM Status](http://hhvm.h4cc.de/badge/doctrine/instantiator.png)](http://hhvm.h4cc.de/package/doctrine/instantiator) + +[![Latest Stable Version](https://poser.pugx.org/doctrine/instantiator/v/stable.png)](https://packagist.org/packages/doctrine/instantiator) +[![Latest Unstable Version](https://poser.pugx.org/doctrine/instantiator/v/unstable.png)](https://packagist.org/packages/doctrine/instantiator) + +## Installation + +The suggested installation method is via [composer](https://getcomposer.org/): + +```sh +php composer.phar require "doctrine/instantiator:~1.0.3" +``` + +## Usage + +The instantiator is able to create new instances of any class without using the constructor or any API of the class +itself: + +```php +$instantiator = new \Doctrine\Instantiator\Instantiator(); + +$instance = $instantiator->instantiate('My\\ClassName\\Here'); +``` + +## Contributing + +Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out! + +## Credits + +This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which +has been donated to the doctrine organization, and which is now deprecated in favour of this package. diff --git a/vendor/doctrine/instantiator/composer.json b/vendor/doctrine/instantiator/composer.json new file mode 100644 index 0000000..4823890 --- /dev/null +++ b/vendor/doctrine/instantiator/composer.json @@ -0,0 +1,45 @@ +{ + "name": "doctrine/instantiator", + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "type": "library", + "license": "MIT", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "instantiate", + "constructor" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "ext-phar": "*", + "ext-pdo": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0", + "athletic/athletic": "~0.1.8" + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "autoload-dev": { + "psr-0": { + "DoctrineTest\\InstantiatorPerformance\\": "tests", + "DoctrineTest\\InstantiatorTest\\": "tests", + "DoctrineTest\\InstantiatorTestAsset\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/doctrine/instantiator/phpmd.xml.dist b/vendor/doctrine/instantiator/phpmd.xml.dist new file mode 100644 index 0000000..8254105 --- /dev/null +++ b/vendor/doctrine/instantiator/phpmd.xml.dist @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + diff --git a/vendor/doctrine/instantiator/phpunit.xml.dist b/vendor/doctrine/instantiator/phpunit.xml.dist new file mode 100644 index 0000000..0a8d570 --- /dev/null +++ b/vendor/doctrine/instantiator/phpunit.xml.dist @@ -0,0 +1,22 @@ + + + + ./tests/DoctrineTest/InstantiatorTest + + + + ./src + + + diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php new file mode 100644 index 0000000..3065375 --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php @@ -0,0 +1,29 @@ +. + */ + +namespace Doctrine\Instantiator\Exception; + +/** + * Base exception marker interface for the instantiator component + * + * @author Marco Pivetta + */ +interface ExceptionInterface +{ +} diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..ea8d28c --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php @@ -0,0 +1,62 @@ +. + */ + +namespace Doctrine\Instantiator\Exception; + +use InvalidArgumentException as BaseInvalidArgumentException; +use ReflectionClass; + +/** + * Exception for invalid arguments provided to the instantiator + * + * @author Marco Pivetta + */ +class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface +{ + /** + * @param string $className + * + * @return self + */ + public static function fromNonExistingClass($className) + { + if (interface_exists($className)) { + return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className)); + } + + if (PHP_VERSION_ID >= 50400 && trait_exists($className)) { + return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className)); + } + + return new self(sprintf('The provided class "%s" does not exist', $className)); + } + + /** + * @param ReflectionClass $reflectionClass + * + * @return self + */ + public static function fromAbstractClass(ReflectionClass $reflectionClass) + { + return new self(sprintf( + 'The provided class "%s" is abstract, and can not be instantiated', + $reflectionClass->getName() + )); + } +} diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php new file mode 100644 index 0000000..1681e56 --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php @@ -0,0 +1,79 @@ +. + */ + +namespace Doctrine\Instantiator\Exception; + +use Exception; +use ReflectionClass; +use UnexpectedValueException as BaseUnexpectedValueException; + +/** + * Exception for given parameters causing invalid/unexpected state on instantiation + * + * @author Marco Pivetta + */ +class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface +{ + /** + * @param ReflectionClass $reflectionClass + * @param Exception $exception + * + * @return self + */ + public static function fromSerializationTriggeredException(ReflectionClass $reflectionClass, Exception $exception) + { + return new self( + sprintf( + 'An exception was raised while trying to instantiate an instance of "%s" via un-serialization', + $reflectionClass->getName() + ), + 0, + $exception + ); + } + + /** + * @param ReflectionClass $reflectionClass + * @param string $errorString + * @param int $errorCode + * @param string $errorFile + * @param int $errorLine + * + * @return UnexpectedValueException + */ + public static function fromUncleanUnSerialization( + ReflectionClass $reflectionClass, + $errorString, + $errorCode, + $errorFile, + $errorLine + ) { + return new self( + sprintf( + 'Could not produce an instance of "%s" via un-serialization, since an error was triggered ' + . 'in file "%s" at line "%d"', + $reflectionClass->getName(), + $errorFile, + $errorLine + ), + 0, + new Exception($errorString, $errorCode) + ); + } +} diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php new file mode 100644 index 0000000..6d5b3b6 --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php @@ -0,0 +1,273 @@ +. + */ + +namespace Doctrine\Instantiator; + +use Closure; +use Doctrine\Instantiator\Exception\InvalidArgumentException; +use Doctrine\Instantiator\Exception\UnexpectedValueException; +use Exception; +use ReflectionClass; + +/** + * {@inheritDoc} + * + * @author Marco Pivetta + */ +final class Instantiator implements InstantiatorInterface +{ + /** + * Markers used internally by PHP to define whether {@see \unserialize} should invoke + * the method {@see \Serializable::unserialize()} when dealing with classes implementing + * the {@see \Serializable} interface. + */ + const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C'; + const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O'; + + /** + * @var \Closure[] of {@see \Closure} instances used to instantiate specific classes + */ + private static $cachedInstantiators = array(); + + /** + * @var object[] of objects that can directly be cloned + */ + private static $cachedCloneables = array(); + + /** + * {@inheritDoc} + */ + public function instantiate($className) + { + if (isset(self::$cachedCloneables[$className])) { + return clone self::$cachedCloneables[$className]; + } + + if (isset(self::$cachedInstantiators[$className])) { + $factory = self::$cachedInstantiators[$className]; + + return $factory(); + } + + return $this->buildAndCacheFromFactory($className); + } + + /** + * Builds the requested object and caches it in static properties for performance + * + * @param string $className + * + * @return object + */ + private function buildAndCacheFromFactory($className) + { + $factory = self::$cachedInstantiators[$className] = $this->buildFactory($className); + $instance = $factory(); + + if ($this->isSafeToClone(new ReflectionClass($instance))) { + self::$cachedCloneables[$className] = clone $instance; + } + + return $instance; + } + + /** + * Builds a {@see \Closure} capable of instantiating the given $className without + * invoking its constructor. + * + * @param string $className + * + * @return Closure + */ + private function buildFactory($className) + { + $reflectionClass = $this->getReflectionClass($className); + + if ($this->isInstantiableViaReflection($reflectionClass)) { + return function () use ($reflectionClass) { + return $reflectionClass->newInstanceWithoutConstructor(); + }; + } + + $serializedString = sprintf( + '%s:%d:"%s":0:{}', + $this->getSerializationFormat($reflectionClass), + strlen($className), + $className + ); + + $this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString); + + return function () use ($serializedString) { + return unserialize($serializedString); + }; + } + + /** + * @param string $className + * + * @return ReflectionClass + * + * @throws InvalidArgumentException + */ + private function getReflectionClass($className) + { + if (! class_exists($className)) { + throw InvalidArgumentException::fromNonExistingClass($className); + } + + $reflection = new ReflectionClass($className); + + if ($reflection->isAbstract()) { + throw InvalidArgumentException::fromAbstractClass($reflection); + } + + return $reflection; + } + + /** + * @param ReflectionClass $reflectionClass + * @param string $serializedString + * + * @throws UnexpectedValueException + * + * @return void + */ + private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, $serializedString) + { + set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) { + $error = UnexpectedValueException::fromUncleanUnSerialization( + $reflectionClass, + $message, + $code, + $file, + $line + ); + }); + + $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString); + + restore_error_handler(); + + if ($error) { + throw $error; + } + } + + /** + * @param ReflectionClass $reflectionClass + * @param string $serializedString + * + * @throws UnexpectedValueException + * + * @return void + */ + private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString) + { + try { + unserialize($serializedString); + } catch (Exception $exception) { + restore_error_handler(); + + throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception); + } + } + + /** + * @param ReflectionClass $reflectionClass + * + * @return bool + */ + private function isInstantiableViaReflection(ReflectionClass $reflectionClass) + { + if (\PHP_VERSION_ID >= 50600) { + return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal()); + } + + return \PHP_VERSION_ID >= 50400 && ! $this->hasInternalAncestors($reflectionClass); + } + + /** + * Verifies whether the given class is to be considered internal + * + * @param ReflectionClass $reflectionClass + * + * @return bool + */ + private function hasInternalAncestors(ReflectionClass $reflectionClass) + { + do { + if ($reflectionClass->isInternal()) { + return true; + } + } while ($reflectionClass = $reflectionClass->getParentClass()); + + return false; + } + + /** + * Verifies if the given PHP version implements the `Serializable` interface serialization + * with an incompatible serialization format. If that's the case, use serialization marker + * "C" instead of "O". + * + * @link http://news.php.net/php.internals/74654 + * + * @param ReflectionClass $reflectionClass + * + * @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER + * or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER + */ + private function getSerializationFormat(ReflectionClass $reflectionClass) + { + if ($this->isPhpVersionWithBrokenSerializationFormat() + && $reflectionClass->implementsInterface('Serializable') + ) { + return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER; + } + + return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER; + } + + /** + * Checks whether the current PHP runtime uses an incompatible serialization format + * + * @return bool + */ + private function isPhpVersionWithBrokenSerializationFormat() + { + return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513; + } + + /** + * Checks if a class is cloneable + * + * @param ReflectionClass $reflection + * + * @return bool + */ + private function isSafeToClone(ReflectionClass $reflection) + { + if (method_exists($reflection, 'isCloneable') && ! $reflection->isCloneable()) { + return false; + } + + // not cloneable if it implements `__clone`, as we want to avoid calling it + return ! $reflection->hasMethod('__clone'); + } +} diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php new file mode 100644 index 0000000..b665bea --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php @@ -0,0 +1,37 @@ +. + */ + +namespace Doctrine\Instantiator; + +/** + * Instantiator provides utility methods to build objects without invoking their constructors + * + * @author Marco Pivetta + */ +interface InstantiatorInterface +{ + /** + * @param string $className + * + * @return object + * + * @throws \Doctrine\Instantiator\Exception\ExceptionInterface + */ + public function instantiate($className); +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorPerformance/InstantiatorPerformanceEvent.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorPerformance/InstantiatorPerformanceEvent.php new file mode 100644 index 0000000..3e8fc6f --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorPerformance/InstantiatorPerformanceEvent.php @@ -0,0 +1,96 @@ +. + */ + +namespace DoctrineTest\InstantiatorPerformance; + +use Athletic\AthleticEvent; +use Doctrine\Instantiator\Instantiator; + +/** + * Performance tests for {@see \Doctrine\Instantiator\Instantiator} + * + * @author Marco Pivetta + */ +class InstantiatorPerformanceEvent extends AthleticEvent +{ + /** + * @var \Doctrine\Instantiator\Instantiator + */ + private $instantiator; + + /** + * {@inheritDoc} + */ + protected function setUp() + { + $this->instantiator = new Instantiator(); + + $this->instantiator->instantiate(__CLASS__); + $this->instantiator->instantiate('ArrayObject'); + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'); + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'); + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'); + } + + /** + * @iterations 20000 + * @baseline + * @group instantiation + */ + public function testInstantiateSelf() + { + $this->instantiator->instantiate(__CLASS__); + } + + /** + * @iterations 20000 + * @group instantiation + */ + public function testInstantiateInternalClass() + { + $this->instantiator->instantiate('ArrayObject'); + } + + /** + * @iterations 20000 + * @group instantiation + */ + public function testInstantiateSimpleSerializableAssetClass() + { + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'); + } + + /** + * @iterations 20000 + * @group instantiation + */ + public function testInstantiateSerializableArrayObjectAsset() + { + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'); + } + + /** + * @iterations 20000 + * @group instantiation + */ + public function testInstantiateUnCloneableAsset() + { + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php new file mode 100644 index 0000000..39d9b94 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php @@ -0,0 +1,83 @@ +. + */ + +namespace DoctrineTest\InstantiatorTest\Exception; + +use Doctrine\Instantiator\Exception\InvalidArgumentException; +use PHPUnit_Framework_TestCase; +use ReflectionClass; + +/** + * Tests for {@see \Doctrine\Instantiator\Exception\InvalidArgumentException} + * + * @author Marco Pivetta + * + * @covers \Doctrine\Instantiator\Exception\InvalidArgumentException + */ +class InvalidArgumentExceptionTest extends PHPUnit_Framework_TestCase +{ + public function testFromNonExistingTypeWithNonExistingClass() + { + $className = __CLASS__ . uniqid(); + $exception = InvalidArgumentException::fromNonExistingClass($className); + + $this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\InvalidArgumentException', $exception); + $this->assertSame('The provided class "' . $className . '" does not exist', $exception->getMessage()); + } + + public function testFromNonExistingTypeWithTrait() + { + if (PHP_VERSION_ID < 50400) { + $this->markTestSkipped('Need at least PHP 5.4.0, as this test requires traits support to run'); + } + + $exception = InvalidArgumentException::fromNonExistingClass( + 'DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset' + ); + + $this->assertSame( + 'The provided type "DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset" is a trait, ' + . 'and can not be instantiated', + $exception->getMessage() + ); + } + + public function testFromNonExistingTypeWithInterface() + { + $exception = InvalidArgumentException::fromNonExistingClass('Doctrine\\Instantiator\\InstantiatorInterface'); + + $this->assertSame( + 'The provided type "Doctrine\\Instantiator\\InstantiatorInterface" is an interface, ' + . 'and can not be instantiated', + $exception->getMessage() + ); + } + + public function testFromAbstractClass() + { + $reflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset'); + $exception = InvalidArgumentException::fromAbstractClass($reflection); + + $this->assertSame( + 'The provided class "DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset" is abstract, ' + . 'and can not be instantiated', + $exception->getMessage() + ); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php new file mode 100644 index 0000000..84154e7 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/Exception/UnexpectedValueExceptionTest.php @@ -0,0 +1,69 @@ +. + */ + +namespace DoctrineTest\InstantiatorTest\Exception; + +use Doctrine\Instantiator\Exception\UnexpectedValueException; +use Exception; +use PHPUnit_Framework_TestCase; +use ReflectionClass; + +/** + * Tests for {@see \Doctrine\Instantiator\Exception\UnexpectedValueException} + * + * @author Marco Pivetta + * + * @covers \Doctrine\Instantiator\Exception\UnexpectedValueException + */ +class UnexpectedValueExceptionTest extends PHPUnit_Framework_TestCase +{ + public function testFromSerializationTriggeredException() + { + $reflectionClass = new ReflectionClass($this); + $previous = new Exception(); + $exception = UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $previous); + + $this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\UnexpectedValueException', $exception); + $this->assertSame($previous, $exception->getPrevious()); + $this->assertSame( + 'An exception was raised while trying to instantiate an instance of "' + . __CLASS__ . '" via un-serialization', + $exception->getMessage() + ); + } + + public function testFromUncleanUnSerialization() + { + $reflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset'); + $exception = UnexpectedValueException::fromUncleanUnSerialization($reflection, 'foo', 123, 'bar', 456); + + $this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\UnexpectedValueException', $exception); + $this->assertSame( + 'Could not produce an instance of "DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset" ' + . 'via un-serialization, since an error was triggered in file "bar" at line "456"', + $exception->getMessage() + ); + + $previous = $exception->getPrevious(); + + $this->assertInstanceOf('Exception', $previous); + $this->assertSame('foo', $previous->getMessage()); + $this->assertSame(123, $previous->getCode()); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php new file mode 100644 index 0000000..0a2cb93 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php @@ -0,0 +1,219 @@ +. + */ + +namespace DoctrineTest\InstantiatorTest; + +use Doctrine\Instantiator\Exception\UnexpectedValueException; +use Doctrine\Instantiator\Instantiator; +use PHPUnit_Framework_TestCase; +use ReflectionClass; + +/** + * Tests for {@see \Doctrine\Instantiator\Instantiator} + * + * @author Marco Pivetta + * + * @covers \Doctrine\Instantiator\Instantiator + */ +class InstantiatorTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Instantiator + */ + private $instantiator; + + /** + * {@inheritDoc} + */ + protected function setUp() + { + $this->instantiator = new Instantiator(); + } + + /** + * @param string $className + * + * @dataProvider getInstantiableClasses + */ + public function testCanInstantiate($className) + { + $this->assertInstanceOf($className, $this->instantiator->instantiate($className)); + } + + /** + * @param string $className + * + * @dataProvider getInstantiableClasses + */ + public function testInstantiatesSeparateInstances($className) + { + $instance1 = $this->instantiator->instantiate($className); + $instance2 = $this->instantiator->instantiate($className); + + $this->assertEquals($instance1, $instance2); + $this->assertNotSame($instance1, $instance2); + } + + public function testExceptionOnUnSerializationException() + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped( + 'As of facebook/hhvm#3432, HHVM has no PDORow, and therefore ' + . ' no internal final classes that cannot be instantiated' + ); + } + + $className = 'DoctrineTest\\InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset'; + + if (\PHP_VERSION_ID >= 50600) { + $className = 'PDORow'; + } + + if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) { + $className = 'DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'; + } + + $this->setExpectedException('Doctrine\\Instantiator\\Exception\\UnexpectedValueException'); + + $this->instantiator->instantiate($className); + } + + public function testNoticeOnUnSerializationException() + { + if (\PHP_VERSION_ID >= 50600) { + $this->markTestSkipped( + 'PHP 5.6 supports `ReflectionClass#newInstanceWithoutConstructor()` for some internal classes' + ); + } + + try { + $this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset'); + + $this->fail('No exception was raised'); + } catch (UnexpectedValueException $exception) { + $wakeUpNoticesReflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset'); + $previous = $exception->getPrevious(); + + $this->assertInstanceOf('Exception', $previous); + + // in PHP 5.4.29 and PHP 5.5.13, this case is not a notice, but an exception being thrown + if (! (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513)) { + $this->assertSame( + 'Could not produce an instance of "DoctrineTest\\InstantiatorTestAsset\WakeUpNoticesAsset" ' + . 'via un-serialization, since an error was triggered in file "' + . $wakeUpNoticesReflection->getFileName() . '" at line "36"', + $exception->getMessage() + ); + + $this->assertSame('Something went bananas while un-serializing this instance', $previous->getMessage()); + $this->assertSame(\E_USER_NOTICE, $previous->getCode()); + } + } + } + + /** + * @param string $invalidClassName + * + * @dataProvider getInvalidClassNames + */ + public function testInstantiationFromNonExistingClass($invalidClassName) + { + $this->setExpectedException('Doctrine\\Instantiator\\Exception\\InvalidArgumentException'); + + $this->instantiator->instantiate($invalidClassName); + } + + public function testInstancesAreNotCloned() + { + $className = 'TemporaryClass' . uniqid(); + + eval('namespace ' . __NAMESPACE__ . '; class ' . $className . '{}'); + + $instance = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className); + + $instance->foo = 'bar'; + + $instance2 = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className); + + $this->assertObjectNotHasAttribute('foo', $instance2); + } + + /** + * Provides a list of instantiable classes (existing) + * + * @return string[][] + */ + public function getInstantiableClasses() + { + $classes = array( + array('stdClass'), + array(__CLASS__), + array('Doctrine\\Instantiator\\Instantiator'), + array('Exception'), + array('PharException'), + array('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\ExceptionAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\FinalExceptionAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\PharExceptionAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\XMLReaderAsset'), + ); + + if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) { + return $classes; + } + + $classes = array_merge( + $classes, + array( + array('PharException'), + array('ArrayObject'), + array('DoctrineTest\\InstantiatorTestAsset\\ArrayObjectAsset'), + array('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'), + ) + ); + + if (\PHP_VERSION_ID >= 50600) { + $classes[] = array('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset'); + $classes[] = array('DoctrineTest\\InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset'); + } + + return $classes; + } + + /** + * Provides a list of instantiable classes (existing) + * + * @return string[][] + */ + public function getInvalidClassNames() + { + $classNames = array( + array(__CLASS__ . uniqid()), + array('Doctrine\\Instantiator\\InstantiatorInterface'), + array('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset'), + ); + + if (\PHP_VERSION_ID >= 50400) { + $classNames[] = array('DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset'); + } + + return $classNames; + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php new file mode 100644 index 0000000..fbe28dd --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php @@ -0,0 +1,29 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +/** + * A simple asset for an abstract class + * + * @author Marco Pivetta + */ +abstract class AbstractClassAsset +{ +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ArrayObjectAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ArrayObjectAsset.php new file mode 100644 index 0000000..56146d7 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ArrayObjectAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use ArrayObject; +use BadMethodCallException; + +/** + * Test asset that extends an internal PHP class + * + * @author Marco Pivetta + */ +class ArrayObjectAsset extends ArrayObject +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php new file mode 100644 index 0000000..43bbe46 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use Exception; + +/** + * Test asset that extends an internal PHP base exception + * + * @author Marco Pivetta + */ +class ExceptionAsset extends Exception +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/FinalExceptionAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/FinalExceptionAsset.php new file mode 100644 index 0000000..7d268f5 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/FinalExceptionAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use Exception; + +/** + * Test asset that extends an internal PHP base exception + * + * @author Marco Pivetta + */ +final class FinalExceptionAsset extends Exception +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharAsset.php new file mode 100644 index 0000000..553fd56 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use Phar; + +/** + * Test asset that extends an internal PHP class + * + * @author Marco Pivetta + */ +class PharAsset extends Phar +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharExceptionAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharExceptionAsset.php new file mode 100644 index 0000000..42bf73e --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/PharExceptionAsset.php @@ -0,0 +1,44 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use PharException; + +/** + * Test asset that extends an internal PHP class + * This class should be serializable without problems + * and without getting the "Erroneous data format for unserializing" + * error + * + * @author Marco Pivetta + */ +class PharExceptionAsset extends PharException +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SerializableArrayObjectAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SerializableArrayObjectAsset.php new file mode 100644 index 0000000..ba19aaf --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SerializableArrayObjectAsset.php @@ -0,0 +1,62 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use ArrayObject; +use BadMethodCallException; +use Serializable; + +/** + * Serializable test asset that also extends an internal class + * + * @author Marco Pivetta + */ +class SerializableArrayObjectAsset extends ArrayObject implements Serializable +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } + + /** + * {@inheritDoc} + */ + public function serialize() + { + return ''; + } + + /** + * {@inheritDoc} + * + * Should not be called + * + * @throws BadMethodCallException + */ + public function unserialize($serialized) + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php new file mode 100644 index 0000000..39f84a6 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php @@ -0,0 +1,61 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use Serializable; + +/** + * Base serializable test asset + * + * @author Marco Pivetta + */ +class SimpleSerializableAsset implements Serializable +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } + + /** + * {@inheritDoc} + */ + public function serialize() + { + return ''; + } + + /** + * {@inheritDoc} + * + * Should not be called + * + * @throws BadMethodCallException + */ + public function unserialize($serialized) + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleTraitAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleTraitAsset.php new file mode 100644 index 0000000..04e7806 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/SimpleTraitAsset.php @@ -0,0 +1,29 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +/** + * A simple trait with no attached logic + * + * @author Marco Pivetta + */ +trait SimpleTraitAsset +{ +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnCloneableAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnCloneableAsset.php new file mode 100644 index 0000000..7d03bda --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnCloneableAsset.php @@ -0,0 +1,50 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; + +/** + * Base un-cloneable asset + * + * @author Marco Pivetta + */ +class UnCloneableAsset +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } + + /** + * Magic `__clone` - should not be invoked + * + * @throws BadMethodCallException + */ + public function __clone() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php new file mode 100644 index 0000000..b348a40 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/UnserializeExceptionArrayObjectAsset.php @@ -0,0 +1,39 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use ArrayObject; +use BadMethodCallException; + +/** + * A simple asset for an abstract class + * + * @author Marco Pivetta + */ +class UnserializeExceptionArrayObjectAsset extends ArrayObject +{ + /** + * {@inheritDoc} + */ + public function __wakeup() + { + throw new BadMethodCallException(); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php new file mode 100644 index 0000000..18dc671 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php @@ -0,0 +1,38 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use ArrayObject; + +/** + * A simple asset for an abstract class + * + * @author Marco Pivetta + */ +class WakeUpNoticesAsset extends ArrayObject +{ + /** + * Wakeup method called after un-serialization + */ + public function __wakeup() + { + trigger_error('Something went bananas while un-serializing this instance'); + } +} diff --git a/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php new file mode 100644 index 0000000..39ee699 --- /dev/null +++ b/vendor/doctrine/instantiator/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php @@ -0,0 +1,41 @@ +. + */ + +namespace DoctrineTest\InstantiatorTestAsset; + +use BadMethodCallException; +use XMLReader; + +/** + * Test asset that extends an internal PHP class + * + * @author Dave Marshall + */ +class XMLReaderAsset extends XMLReader +{ + /** + * Constructor - should not be called + * + * @throws BadMethodCallException + */ + public function __construct() + { + throw new BadMethodCallException('Not supposed to be called!'); + } +} diff --git a/vendor/fzaninotto/faker/.gitignore b/vendor/fzaninotto/faker/.gitignore new file mode 100644 index 0000000..7579f74 --- /dev/null +++ b/vendor/fzaninotto/faker/.gitignore @@ -0,0 +1,2 @@ +vendor +composer.lock diff --git a/vendor/fzaninotto/faker/.travis.yml b/vendor/fzaninotto/faker/.travis.yml new file mode 100644 index 0000000..df3e0b1 --- /dev/null +++ b/vendor/fzaninotto/faker/.travis.yml @@ -0,0 +1,17 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - hhvm + +sudo: false + +before_script: + - travis_retry composer self-update + - travis_retry composer install --no-interaction --prefer-source --dev + +script: make sniff test diff --git a/vendor/fzaninotto/faker/CHANGELOG.md b/vendor/fzaninotto/faker/CHANGELOG.md new file mode 100644 index 0000000..d0f1023 --- /dev/null +++ b/vendor/fzaninotto/faker/CHANGELOG.md @@ -0,0 +1,295 @@ +CHANGELOG +========= + +To be released, v1.5.0 +---------------------- + +* Added ability to print custom text on the images fetched by the Image provider [\#583](https://github.com/fzaninotto/Faker/pull/583) ([fzaninotto](https://github.com/fzaninotto)) +* Fixed typos in Preuvian (es\_PE) Person provider [\#581](https://github.com/fzaninotto/Faker/pull/581) [\#580](https://github.com/fzaninotto/Faker/pull/580) ([ysramirez](https://github.com/ysramirez)) +* Added instructions for installing with composer to readme.md [\#572](https://github.com/fzaninotto/Faker/pull/572) ([totophe](https://github.com/totophe)) +* Added Kazakh (kk\_KZ) locale [\#569](https://github.com/fzaninotto/Faker/pull/569) ([YerlenZhubangaliyev](https://github.com/YerlenZhubangaliyev)) +* Added Korean (ko\_KR) locale [\#566](https://github.com/fzaninotto/Faker/pull/566) ([pearlc](https://github.com/pearlc)) +* Fixed file provider to ignore unreadable and special files [\#565](https://github.com/fzaninotto/Faker/pull/565) ([svrnm](https://github.com/svrnm)) +* Fixed Dutch (nl\_NL) Address and Person providers [\#560](https://github.com/fzaninotto/Faker/pull/560) ([killerog](https://github.com/killerog)) +* Fixed Dutch (nl\_NL) Person provider [\#559](https://github.com/fzaninotto/Faker/pull/559) ([pauledenburg](https://github.com/pauledenburg)) +* Added Russian (ru\_RU) Bank names provider [\#553](https://github.com/fzaninotto/Faker/pull/553) ([wizardjedi](https://github.com/wizardjedi)) +* Added mobile phone function in French (fr\_FR) provider [\#552](https://github.com/fzaninotto/Faker/pull/552) ([kletellier](https://github.com/kletellier)) +* Added phpdoc for new magic methods in Generator to help IntelliSense completion [\#550](https://github.com/fzaninotto/Faker/pull/550) ([stof](https://github.com/stof)) +* Fixed File provider bug 'The first argument to copy() function cannot be a directory' [\#547](https://github.com/fzaninotto/Faker/pull/547) ([svrnm](https://github.com/svrnm)) +* Added new Brazilian (pt\_BR) Providers [\#545](https://github.com/fzaninotto/Faker/pull/545) ([igorsantos07](https://github.com/igorsantos07)) +* Fixed ability to seed the generator [\#543](https://github.com/fzaninotto/Faker/pull/543) ([schmengler](https://github.com/schmengler)) +* Added streetAddress formatter to Russian (ru\_RU) provider [\#542](https://github.com/fzaninotto/Faker/pull/542) ([ZAYEC77](https://github.com/ZAYEC77)) +* Fixed Internet provider warning "Could not create transliterator"* [\#541](https://github.com/fzaninotto/Faker/pull/541) ([fonsecas72](https://github.com/fonsecas72)) +* Fixed Spanish for Argentina (es\_AR) Address provider [\#540](https://github.com/fzaninotto/Faker/pull/540) ([ivanmirson](https://github.com/ivanmirson)) +* Fixed region names in French for Belgium (fr\_BE) address provider [\#536](https://github.com/fzaninotto/Faker/pull/536) ([miclf](https://github.com/miclf)) +* Fixed broken Doctrine2 link in README [\#534](https://github.com/fzaninotto/Faker/pull/534) ([JonathanKryza](https://github.com/JonathanKryza)) +* Added link to faker-context Behat extension in readme [\#532](https://github.com/fzaninotto/Faker/pull/532) ([denheck](https://github.com/denheck)) +* Added PHP 7.0 nightly to Travis build targets [\#525](https://github.com/fzaninotto/Faker/pull/525) ([TomasVotruba](https://github.com/TomasVotruba)) +* Added Dutch (nl\_NL) color names [\#523](https://github.com/fzaninotto/Faker/pull/523) ([belendel](https://github.com/belendel)) +* Fixed Chinese (zh\_CN) Address provider (remove Taipei) [\#522](https://github.com/fzaninotto/Faker/pull/522) ([asika32764](https://github.com/asika32764)) +* Fixed phonenumber formats in Dutch (nl\_NL) PhoneNumber provider [\#521](https://github.com/fzaninotto/Faker/pull/521) ([SpaceK33z](https://github.com/SpaceK33z)) +* Fixed Russian (ru\_RU) Address provider [\#518](https://github.com/fzaninotto/Faker/pull/518) ([glagola](https://github.com/glagola)) +* Added Italian (it\_IT) Text provider [\#517](https://github.com/fzaninotto/Faker/pull/517) ([endelwar](https://github.com/endelwar)) +* Added Norwegian (no\_NO) locale [\#515](https://github.com/fzaninotto/Faker/pull/515) ([phaza](https://github.com/phaza)) +* Added VAT number to Bulgarian (bg\_BG) Payment provider [\#512](https://github.com/fzaninotto/Faker/pull/512) ([ronanguilloux](https://github.com/ronanguilloux)) +* Fixed UserAgent provider outdated user agents [\#511](https://github.com/fzaninotto/Faker/pull/511) ([ajbdev](https://github.com/ajbdev)) +* Fixed `image()` formatter to make it work with temp dir of any (decent) OS [\#507](https://github.com/fzaninotto/Faker/pull/507) ([ronanguilloux](https://github.com/ronanguilloux)) +* Added Persian (fa\_IR) locale [\#500](https://github.com/fzaninotto/Faker/pull/500) ([zoli](https://github.com/zoli)) +* Added Currency Code formatter [\#497](https://github.com/fzaninotto/Faker/pull/497) ([stelgenhof](https://github.com/stelgenhof)) +* Added VAT number to Belgium (be_BE) Payment provider [\#495](https://github.com/fzaninotto/Faker/pull/495) ([ronanguilloux](https://github.com/ronanguilloux)) +* Fixed `imageUrl` formatter bug where it would always return the same image [\#494](https://github.com/fzaninotto/Faker/pull/494) ([fzaninotto](https://github.com/fzaninotto)) +* Added more Indonesian (id\_ID) providers [\#493](https://github.com/fzaninotto/Faker/pull/493) ([deerawan](https://github.com/deerawan)) +* Added Indonesian (id\_ID) locale [\#492](https://github.com/fzaninotto/Faker/pull/492) ([stoutZero](https://github.com/stoutZero)) +* Fixed unique generator performance [\#491](https://github.com/fzaninotto/Faker/pull/491) ([ikwattro](https://github.com/ikwattro)) +* Added transliterator to `email` and `username` [\#490](https://github.com/fzaninotto/Faker/pull/490) ([fzaninotto](https://github.com/fzaninotto)) +* Added Hungarian (hu\_HU) Text provider [\#486](https://github.com/fzaninotto/Faker/pull/486) ([lintaba](https://github.com/lintaba)) +* Fixed CakePHP Entity Popolator (some cases where no entities prev. inserted) [\#483](https://github.com/fzaninotto/Faker/pull/483) ([jadb](https://github.com/jadb)) +* Added Color and DateTime Turkish (tr\_TR) Providers [\#481](https://github.com/fzaninotto/Faker/pull/481) ([behramcelen](https://github.com/behramcelen)) +* Added Latvian (lv\_LV) `personalIdentityNumber` formatter [\#472](https://github.com/fzaninotto/Faker/pull/472) ([MatissJanis](https://github.com/MatissJanis)) +* Added VAT number to Austrian (at_AT) Payment provider [\#470](https://github.com/fzaninotto/Faker/pull/470) ([ronanguilloux](https://github.com/ronanguilloux)) +* Fixed missing @return phpDoc in Payment provider [\#469](https://github.com/fzaninotto/Faker/pull/469) ([ronanguilloux](https://github.com/ronanguilloux)) +* Added SWIFT/BIC payment type formatter to the Payment provider [\#465](https://github.com/fzaninotto/Faker/pull/465) ([ronanguilloux](https://github.com/ronanguilloux)) +* Fixed small typo in Base provider exception [\#460](https://github.com/fzaninotto/Faker/pull/460) ([miclf](https://github.com/miclf)) +* Added Georgian (ka\_Ge) locale [\#457](https://github.com/fzaninotto/Faker/pull/457) ([lperto](https://github.com/lperto)) +* Added PSR-4 Autoloading [\#455](https://github.com/fzaninotto/Faker/pull/455) ([GrahamCampbell](https://github.com/GrahamCampbell)) +* Added Uganda (en_UG) locale [\#454](https://github.com/fzaninotto/Faker/pull/454) ([tharoldD](https://github.com/tharoldD)) +* Added `regexify` formatter, generating a random string based on a regular expression [\#453](https://github.com/fzaninotto/Faker/pull/453) ([fzaninotto](https://github.com/fzaninotto)) +* Added shuffle formatter, to shuffle an array or a string [\#452](https://github.com/fzaninotto/Faker/pull/452) ([fzaninotto](https://github.com/fzaninotto)) +* Added ISBN-10 & ISBN-13 codes formatters to Barcode provider [\#451](https://github.com/fzaninotto/Faker/pull/451) ([gietos](https://github.com/gietos)) +* Fixed Russian (ru\_RU) middle names (different for different genders) [\#450](https://github.com/fzaninotto/Faker/pull/450) ([gietos](https://github.com/gietos)) +* Fixed Ukranian (uk\_UA) Person provider [\#448](https://github.com/fzaninotto/Faker/pull/448) ([aivus](https://github.com/aivus)) +* Added Vietnamese (vi\_VN) locale [\#447](https://github.com/fzaninotto/Faker/pull/447) ([huy95](https://github.com/huy95)) +* Added type hint to the Documentor constructor [\#446](https://github.com/fzaninotto/Faker/pull/446) ([JeroenDeDauw](https://github.com/JeroenDeDauw)) +* Fixed Russian (ru\_RU) Person provider (joined names) [\#445](https://github.com/fzaninotto/Faker/pull/445) ([aivus](https://github.com/aivus)) +* Added English (en\_GB) `mobileNumber` methods [\#438](https://github.com/fzaninotto/Faker/pull/438) ([daveblake](https://github.com/daveblake)) +* Added Traditional Chinese (zh\_TW) Realtext provider [\#434](https://github.com/fzaninotto/Faker/pull/434) ([tzhuan](https://github.com/tzhuan)) +* Fixed first name in Spanish for Argentina (es\_AR) Person provider [\#433](https://github.com/fzaninotto/Faker/pull/433) ([fzaninotto](https://github.com/fzaninotto)) +* Fixed Canadian (en_CA) state abbreviation for Nunavut [\#430](https://github.com/fzaninotto/Faker/pull/430) ([julien-c](https://github.com/julien-c)) +* Added CakePHP ORM entity populator [\#428](https://github.com/fzaninotto/Faker/pull/428) ([jadb](https://github.com/jadb)) +* Added Traditional Chinese (zh\_TW) locale [\#427](https://github.com/fzaninotto/Faker/pull/427) ([tzhuan](https://github.com/tzhuan)) +* Fixed typo in Doctrine Populator phpDoc [\#425](https://github.com/fzaninotto/Faker/pull/425) ([ihsanudin](https://github.com/ihsanudin)) +* Added Chinese (zh_CN) Internet provider [\#424](https://github.com/fzaninotto/Faker/pull/424) ([Lisso-Me](https://github.com/Lisso-Me)) +* Added Country ISO 3166-1 alpha-3 code to the Miscellaneous provider[\#422](https://github.com/fzaninotto/Faker/pull/422) ([gido](https://github.com/gido)) +* Added English (en\_GB) Person provider [\#421](https://github.com/fzaninotto/Faker/pull/421) ([AlexCutts](https://github.com/AlexCutts)) +* Added missing tests for the Color Provider [\#420](https://github.com/fzaninotto/Faker/pull/420) ([bessl](https://github.com/bessl)) +* Added Nepali (ne\_NP) locale [\#419](https://github.com/fzaninotto/Faker/pull/419) ([ankitpokhrel](https://github.com/ankitpokhrel)) +* Fixed latitude and longitude formatters bug (numeric value out of range for 32bits) [\#416](https://github.com/fzaninotto/Faker/pull/416) ([fzaninotto](https://github.com/fzaninotto)) +* Added a dedicated calculator Luhn calculator service [\#414](https://github.com/fzaninotto/Faker/pull/414) ([fzaninotto](https://github.com/fzaninotto)) +* Fixed Russian (ru_RU) Person provider (removed lowercase duplications) [\#413](https://github.com/fzaninotto/Faker/pull/413) ([Ragazzo](https://github.com/Ragazzo)) +* Fixed barcode formatter (improved speed, added tests) [\#412](https://github.com/fzaninotto/Faker/pull/412) ([fzaninotto](https://github.com/fzaninotto)) +* Added ipv4 and barcode formatters tests [\#410](https://github.com/fzaninotto/Faker/pull/410) ([bessl](https://github.com/bessl)) +* Fixed typos in various comments blocks [\#409](https://github.com/fzaninotto/Faker/pull/409) ([bessl](https://github.com/bessl)) +* Fixed InternetTest (replaced regex with PHP filter) [\#406](https://github.com/fzaninotto/Faker/pull/406) ([bessl](https://github.com/bessl)) +* Added password formatter to the Internet provider[\#402](https://github.com/fzaninotto/Faker/pull/402) ([fzaninotto](https://github.com/fzaninotto)) +* Added Company and Internet Austrian (de\_AT) Providers [\#400](https://github.com/fzaninotto/Faker/pull/400) ([bessl](https://github.com/bessl)) +* Added third-party libraries section in README [\#399](https://github.com/fzaninotto/Faker/pull/399) ([fzaninotto](https://github.com/fzaninotto)) +* Added Spanish for Venezuela (es\_VE) locale [\#398](https://github.com/fzaninotto/Faker/pull/398) ([DIOHz0r](https://github.com/DIOHz0r)) +* Added PhoneNumber Autrian (de\_AT) Provider, and missing test for the 'locale' method. [\#395](https://github.com/fzaninotto/Faker/pull/395) ([bessl](https://github.com/bessl)) +* Removed wrongly localized Lorem provider [\#394](https://github.com/fzaninotto/Faker/pull/394) ([fzaninotto](https://github.com/fzaninotto)) +* Fixed Miscellaneous provider (made the `locale` formatter static) [\#390](https://github.com/fzaninotto/Faker/pull/390) ([bessl](https://github.com/bessl)) +* Added a unit test file for the Miscellaneous Provider [\#389](https://github.com/fzaninotto/Faker/pull/389) ([bessl](https://github.com/bessl)) +* Added warning in README about using `rand()`` and the seed functions [\#386](https://github.com/fzaninotto/Faker/pull/386) ([paulvalla](https://github.com/paulvalla)) +* Fixed French (fr\_FR) Person provider (Uppercased a first name) [\#385](https://github.com/fzaninotto/Faker/pull/385) ([netcarver](https://github.com/netcarver)) +* Added Russian (ru\_RU) and Ukrainian (uk\_UA) Text providers [\#383](https://github.com/fzaninotto/Faker/pull/383) ([terion-name](https://github.com/terion-name)) +* Added more street prefixes to French (fr\_FR) Address provider [\#381](https://github.com/fzaninotto/Faker/pull/381) ([ronanguilloux](https://github.com/ronanguilloux)) +* Added PHP 5.6 to CI targets [\#378](https://github.com/fzaninotto/Faker/pull/378) ([GrahamCampbell](https://github.com/GrahamCampbell)) +* Fixed spaces remaining at the end of liine in various files [\#377](https://github.com/fzaninotto/Faker/pull/377) ([GrahamCampbell](https://github.com/GrahamCampbell)) +* Fixed UserAgent provider (added space before processor on linux platform) [\#374](https://github.com/fzaninotto/Faker/pull/374) ([TomK](https://github.com/TomK)) +* Added Company generator for Russian (ru\_RU) locale [\#371](https://github.com/fzaninotto/Faker/pull/371) ([kix](https://github.com/kix)) +* Fixed Russian (ru\_RU) Color provider (uppercase letters) [\#370](https://github.com/fzaninotto/Faker/pull/370) ([semanser](https://github.com/semanser)) +* Added more Polish (pl\_PL) phone numbers [\#369](https://github.com/fzaninotto/Faker/pull/369) ([piotrantosik](https://github.com/piotrantosik)) +* Fixed Ruby Faker link in readme [\#368](https://github.com/fzaninotto/Faker/pull/368) ([philsturgeon](https://github.com/philsturgeon)) +* Added more Japanese (ja\_JP) names in Person provider [\#366](https://github.com/fzaninotto/Faker/pull/366) ([kumamidori](https://github.com/kumamidori)) +* Added Slovenian (sl\_SL) locale [\#363](https://github.com/fzaninotto/Faker/pull/363) ([alesf](https://github.com/alesf)) +* Fixed German (de\_DE) Person provider (first names) [\#362](https://github.com/fzaninotto/Faker/pull/362) ([mikehaertl](https://github.com/mikehaertl)) +* Fixed Ukrainian (uk\_UA) Person providr (there is no such letter "ы" in Ukrainian) [\#359](https://github.com/fzaninotto/Faker/pull/359) ([nazar-pc](https://github.com/nazar-pc)) +* Fixed Chinese (zh\_CN) PhoneNumber provider (the length of mobile phone number is 11) [\#358](https://github.com/fzaninotto/Faker/pull/358) ([byan](https://github.com/byan)) +* Added Arabic (ar_\JO) Locale [\#357](https://github.com/fzaninotto/Faker/pull/357) ([zrashwani](https://github.com/zrashwani)) +* Fixed Czech (cs\_CZ) Person provider (missing lowercase in last name) [\#355](https://github.com/fzaninotto/Faker/pull/355) ([halaxa](https://github.com/halaxa)) +* Fixed French for Belgium (fr\_BE) Address Provider (doubled city names) [\#354](https://github.com/fzaninotto/Faker/pull/354) ([miclf](https://github.com/miclf)) +* Added Biased Integer Provider [\#332](https://github.com/fzaninotto/Faker/pull/332) ([TimWolla](https://github.com/TimWolla)) +* Added Swedish (sv\_SE) locale [\#316](https://github.com/fzaninotto/Faker/pull/316) ([ulrikjohansson](https://github.com/ulrikjohansson)) +* Added English for New Zealand (en\_NZ) locale [\#283](https://github.com/fzaninotto/Faker/pull/283) ([JasonMortonNZ](https://github.com/JasonMortonNZ)) +* Added mention of external Provider for cron expressions to readme[\#498](https://github.com/fzaninotto/Faker/pull/498) ([swekaj](https://github.com/swekaj)) + +2014-06-04, v1.4.0 +------------------ + +* Fixed typo in Slovak person names (cinan) +* Added tests for uk_UA providers (serge-kuharev) +* Fixed numerify() performance by making it 30% faster (fzaninotto) +* Added strict option to randomNumber to force number of digits (fzaninotto) +* Fixed randomNumber usage duplicating numberBetween (fzaninotto) +* Fixed address provider for latvian language (MatissJA) +* Added Czech Republic (cs_CZ) address, company, datetime and text providers (Mikulas) +* Fixed da_DK Person provider data containing an 'unnamed' person (tolnem) +* Added slug provider (fzaninotto) +* Fixed IDE insights for new local IP and MAC address providers (hugofonseca) +* Added firstname gender method to all Person providers (csanquer) +* Fixed tr_TR email service, city name, person, and phone number formats (ogunkarakus) +* Fixed US_en state list (fzaninotto) +* Fixed en_US address provider so state abbr are ISO 3166 codes (Garbee) +* Added local IP and MAC address providers (kielabokkie) +* Fixed typo in century list affecting the century provider (fzaninotto) +* Added default value to optional modifier (joshuajabbour) +* Fixed Portuguese phonenumbers have 9 digits (hugofonseca) +* Added fileCopy to File provider to simulate file upload (stefanosala) +* Added pt_PT providers (hugofonseca) +* Fixed dead code in text provider (hugofonseca) +* Fixed IDE insights for magic properties (hugofonseca) +* Added tin (NIF) generator for pt_PT provider (hugofonseca) +* Fixed numberBetween max default value handling (fzaninotto) +* Added pt_PT phone number provider (hugofonseca) +* Fixed PSR-2 standards and add make task to force it on Travis (terite) +* Added new ro_RO Personal Numerical Code (CNP) and phone number providers (avataru) +* Fixed Internet provider for sk_SK locale (cinan) +* Fixed typo in en_ZA Internet provider (bjorntheart) +* Fixed phpdoc for DateTime magic methods (stof) +* Added doc about seeding with maximum timestamp using dateTime formatters (fzaninotto) +* Added Maximum Timestamp option to get always same unix timestamp when using a fixed seed (csanquer) +* Added Montenegrian (me_ME) providers (ognjenm) +* Added ean barcode provider (nineinchnick) +* Added fullPath parameter to Image provider (stefanosala) +* Added more Polish company formats (nineinchnick) +* Added Polish realText provider (nineinchnick) +* Fixed remaining non-seedable random generators (terite) +* Added randomElements provider (terite) +* Added French realText provider (fzaninotto) +* Fixed realText provider bootstrap slowness (fzaninotto) +* Added realText provider for English and German, based on Markov Chains Generator (TimWolla) +* Fixed address format in nl_NL provider (doenietzomoeilijk) +* Fixed potentially offensive word from last name list (joshuajabbour) +* Fixed reamde documentation about the optional modifier (cryode) +* Fixed Image provider and documentor routine (fzaninotto) +* Fixed IDE insights for methods (PedroTroller) +* Fixed missing data in en_US Address provider (Garbee) +* Added Bengali (bn_BD) providers (masnun) +* Fixed warning on test file when short tags are on (bateller) +* Fixed Doctrine populator undefined index warning (dbojdo) +* Added French Canadian (fr_CA) Address and Person providers (marcaube) +* Fixed typo in NullGenerator (mhanson01) +* Fixed Doctrine populator issue with one-to-one nullable relationship (jpetitcolas) +* Added Canadian English (en_CA) address and phone number providers (cviebrock) +* Fixed duplicated Payment example in readme (Garbee) +* Fixed Polish (pl_PL) Person provider data (czogori) +* Added Hungarian (hu_HU) providers (sagikazarmark) +* Added 'kana' (ja_JP) name formatters (kzykhys) +* Added allow_failure for hhvm to travis-ci and test against php 5.5 (toin0u) + +2013-12-16, v1.3.0 +------------------ + +* Fixed state generator in Australian (en_AU) provider (sebklaus) +* Fixed IDE insights for locale specific providers (ulrikjohansson) +* Added English (South Africa) (en_ZA) person, address, Internet and phone number providers (dmfaux) +* Fixed integer values overflowing on signed INTEGER columns on Doctrine populator (Thinkscape) +* Fixed spelling error in French (fr_FR) address provider (leihog) +* Added improvements based on SensioLabsInsights analysis +* Fixed Italian (it_IT) email provider (garak) +* Added Spanish (es_ES) Internet provider (eusonlito) +* Added English Philippines (en_PH) address provider (kamote) +* Added Brazilian (pt_BR) email provider data (KennedyTedesco) +* Fixed UK country code (pgscandeias) +* Added Peruvian (es_PE) person, address, phone number, and company providers (cslucano) +* Added Ukrainian (uk_UA) color provider (ruden) +* Fixed Ukrainian (uk_UA) namespace and email translitteration (ruden) +* Added Romanian (Moldova) (ro_MD) person, address, and phone number providers (AlexanderC) +* Added IBAN generator for every currently known locale that uses it (nineinchnick) +* Added Image generation powered by LoremPixel (weotch) +* Fixed missing timezone with dateTimeBetween (baldurrensch) +* Fixed call to undefined method cardType in Payment (WMeldon) +* Added Romanian (ro_RO) address and person providers (calina-c) +* Fixed Doctrine populator to use ObjectManager instead of EntityManagerInterface (mgiustiniani) +* Fixed docblock for Provider\Base::unique() (pschultz) +* Added Payment providers (creditCardType, creditCardNumber, creditCardExpirationDate, creditCardExpirationDateString) (pomaxa) +* Added unique() modifier +* Added IDE insights to allow better intellisense/phpStorm autocompletion (thallisphp) +* Added Polish (pl_PL) address provider, personal identity number and pesel number generator (nineinchnick) +* Added Turkish (tr_TR) address provider, and improved internet provider (hasandz) +* Fixed Propel column number guesser to use signed range of values (gunnarlium) +* Added Greek (el_GR) person, address, and phone number providers (georgeharito) +* Added Austrian (en_AU) address, Internet, and phone number providers (rcuddy) +* Fixed phpDoc in Doctrine Entity populator (rogamoore) +* Added French (fr_FR) phone number formats (vchabot) +* Added optional() modifier (weotch) +* Fixed typo in the Person provider documentation (jtreminio) +* Fixed Russian (ru_RU) person format (alexshadow007) +* Added Japanese (ja_JP) person, address, Internet, phone number, and company providers (kumamidori) +* Added color providers, driver license and passport number formats for the ru_RU locale (pomaxa) +* Added Latvian (lv_LV) person, address, Internet, and phone number providers (pomaxa) +* Added Brazilian (pt_BR) Internet provider (vjnrv) +* Added more Czech (cs_CZ) lastnames (petrkle) +* Added Chinese Simplified (zh_CN) person, address, Internet, and phone number providers (tlikai) +* Fixed Typos (pborelli) +* Added Color provider with hexColor, rgbColor, rgbColorAsArray, rgbCssColor, safeColorName, and colorName formatters (lsv) +* Added support for associative arrays in `randomElement` (aRn0D) + + +2013-06-09, v1.2.0 +------------------ + +* Added new provider for fr_BE locale (jflefebvre) +* Updated locale provider to use a static locale list (spawn-guy) +* Fixed invalid UTF-8 sequence in domain provider with the Bulgarian provider (Dynom) +* Fixed the nl_NL Person provider (Dynom) +* Removed all requires and added the autoload definition to composer (Dynom) +* Fixed encoding problems in nl_NL Address provider (Dynom) +* Added icelandic provider (is_IS) (birkir) +* Added en_CA address and phone numbers (cviebrock) +* Updated safeEmail provider to be really safe (TimWolla) +* Documented alternative randomNumber usage (Seldaek) +* Added basic file provider (anroots) +* Fixed use of fourth argument on Doctrine addEntity (ecentinela) +* Added nl_BE provider (wimvds) +* Added Random Float provider (csanquer) +* Fixed bug in Faker\ORM\Doctrine\Populator (mmf-amarcos) +* Updated ru_RU provider (rmrevin) +* Added safe email domain provider (csanquer) +* Fixed latitude provider (rumpl) +* Fixed unpredictability of fake data generated by Faker\Provider\Base::numberBetween() (goatherd) +* Added uuid provider (goatherd) +* Added possibility to call methods on Doctrine entities, possibility to generate unique id (nenadalm) +* Fixed prefixes typos in 'pl_PL' Person provider (krymen) +* Added more fake data to the Ukraininan providers (lysenkobv) +* Added more fake data to the Italian providers (EmanueleMinotto) +* Fixed spaces appearing in generated emails (alchy58) +* Added Armenian (hy_AM) provider (artash) +* Added Generation of valid SIREN & SIRET codes to French providers (alexsegura) +* Added Dutch (nl_NL) provider (WouterJ) +* Fixed missing typehint in Base::__construct() (benja-M-1) +* Fixed typo in README (benja-M-1) +* Added Ukrainian (ua_UA) provider (rsvasilyev) +* Added Turkish (tr_TR) Provider (faridmovsumov) +* Fixed executable bit in some PHP files (siwinski) +* Added Brazilian Portuguese (pt_BR) provider (oliveiraev) +* Added Spanish (es_ES) provider (ivannis) +* Fixed Doctrine populator to allow for the population of entity data that has associations to other entities (afishnamedsquish) +* Added Danish (da_DK) providers (toin0u) +* Cleaned up whitespaces (toin0u) +* Fixed utf-8 bug with lowercase generators (toin0u) +* Fixed composer.json (Seldaek) +* Fixed bug in Doctrine EntityPopulator (beberlei) +* Added Finnish (fi_FI) provider (drodil) + +2012-10-29, v1.1.0 +------------------ + +* Updated text provider to return paragraphs as a string instead of array. Great for populating markdown textarea fields (Seldaek) +* Updated dateTimeBetween to accept DateTime instances (Seldaek) +* Added random number generator between a and b, simply like rand() (Seldaek) +* Fixed spaces in generated emails (blaugueux) +* Fixed Person provider in Russian locale (Isamashii) +* Added new UserAgent provider (blaugueux) +* Added locale generator to Miscellaneous provider (blaugueux) +* Added timezone generator to DateTime provider (blaugueux) +* Added new generators to French Address providers (departments, regions) (geoffrey-brier) +* Added new generators to French Company provider (catch phrase, SIREN, and SIRET numbers) (geoffrey-brier) +* Added state generator to German Address provider (Powerhamster) +* Added Slovak provider (bazo) +* Added latitude and longitude formatters to Address provider (fixe) +* Added Serbian provider (umpirsky) + +2012-07-10, v1.0.0 +----------------- + +* Initial Version diff --git a/vendor/fzaninotto/faker/CONTRIBUTING.md b/vendor/fzaninotto/faker/CONTRIBUTING.md new file mode 100644 index 0000000..b8cc8c3 --- /dev/null +++ b/vendor/fzaninotto/faker/CONTRIBUTING.md @@ -0,0 +1,21 @@ +Contributing +============ + +If you've written a new formatter, adapted Faker to a new locale, or fixed a bug, your contribution is welcome! + +Before proposing a pull request, check the following: + +* Your code should follow the [PSR-2 coding standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) (and use [php-cs-fixer](https://github.com/fabpot/PHP-CS-Fixer) to fix inconsistencies). +* Unit tests should still pass after your patch +* As much as possible, add unit tests for your code +* If you add new providers (or new locales) and that they embed a lot of data for random generation (e.g. first names in a new language), please add a link to the reference you used for this list (example [in the ru_RU locale](https://github.com/fzaninotto/Faker/blob/master/src/Faker/Provider/ru_RU/Person.php#L13)). This will ease future updates of the list and debates about the most relevant data for this provider. +* If you add long list of random data, please split the list into several lines. This makes diffs easier to read, and facilitates core review. +* If you add new formatters, please include documentation for it in the README. Don't forget to add a line about new formatters in the `@property` or `@method` phpDoc entries in [Generator.php](https://github.com/fzaninotto/Faker/blob/master/src/Faker/Generator.php#L6-L118) to help IDEs auto-complete your formatters. +* If your new formatters are specific to a certain locale, document them in the [Language-specific formatters](https://github.com/fzaninotto/Faker#language-specific-formatters) list instead. +* Avoid changing existing sets of data. Some developers use Faker with seeding for unit tests ; changing the data makes their tests fail. +* Speed is important in all Faker usages. Make sure your code is optimized to generate thousands of fake items in no time, without consuming too much memory or CPU. +* If you commit a new feature, be prepared to help maintaining it. Watch the project on GitHub, and please comment on issues or PRs regarding the feature you contributed. + +Once your code is merged, it is available for free to everybody under the MIT License. Publishing your Pull Request on the Faker GitHub repository means that you agree with this license for your contribution. + +Thank you for your contribution! Faker wouldn't be so great without you. diff --git a/vendor/fzaninotto/faker/LICENSE b/vendor/fzaninotto/faker/LICENSE new file mode 100644 index 0000000..99ed007 --- /dev/null +++ b/vendor/fzaninotto/faker/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2011 François Zaninotto +Portions Copyright (c) 2008 Caius Durling +Portions Copyright (c) 2008 Adam Royle +Portions Copyright (c) 2008 Fiona Burrows + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/fzaninotto/faker/Makefile b/vendor/fzaninotto/faker/Makefile new file mode 100644 index 0000000..55e11d0 --- /dev/null +++ b/vendor/fzaninotto/faker/Makefile @@ -0,0 +1,10 @@ +vendor/autoload.php: + composer install --no-interaction --prefer-source --dev + +.PHONY: sniff +sniff: vendor/autoload.php + vendor/bin/phpcs --standard=PSR2 src -n + +.PHONY: test +test: vendor/autoload.php + vendor/bin/phpunit --verbose diff --git a/vendor/fzaninotto/faker/composer.json b/vendor/fzaninotto/faker/composer.json new file mode 100644 index 0000000..a415031 --- /dev/null +++ b/vendor/fzaninotto/faker/composer.json @@ -0,0 +1,37 @@ +{ + "name": "fzaninotto/faker", + "type": "library", + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": ["faker", "fixtures", "data"], + "license": "MIT", + "authors": [ + { + "name": "François Zaninotto" + } + ], + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5" + }, + "suggest": { + "ext-intl": "*" + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "autoload-dev": { + "psr-4": { + "Faker\\PHPUnit\\": "test/Faker/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + } +} diff --git a/vendor/fzaninotto/faker/phpunit.xml.dist b/vendor/fzaninotto/faker/phpunit.xml.dist new file mode 100644 index 0000000..fcd85fa --- /dev/null +++ b/vendor/fzaninotto/faker/phpunit.xml.dist @@ -0,0 +1,9 @@ + + + + + + ./test/Faker/ + + + diff --git a/vendor/fzaninotto/faker/readme.md b/vendor/fzaninotto/faker/readme.md new file mode 100644 index 0000000..bc9f831 --- /dev/null +++ b/vendor/fzaninotto/faker/readme.md @@ -0,0 +1,1048 @@ +# Faker + +Faker is a PHP library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in your persistence to stress test it, or anonymize data taken from a production service, Faker is for you. + +Faker is heavily inspired by Perl's [Data::Faker](http://search.cpan.org/~jasonk/Data-Faker-0.07/), and by ruby's [Faker](https://rubygems.org/gems/faker). + +Faker requires PHP >= 5.3.3. + +[![Monthly Downloads](https://poser.pugx.org/fzaninotto/faker/d/monthly.png)](https://packagist.org/packages/fzaninotto/faker) [![Build Status](https://secure.travis-ci.org/fzaninotto/Faker.png)](http://travis-ci.org/fzaninotto/Faker) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/eceb78a9-38d4-4ad5-8b6b-b52f323e3549/mini.png)](https://insight.sensiolabs.com/projects/eceb78a9-38d4-4ad5-8b6b-b52f323e3549) + +## Installation + +```sh +composer require fzaninotto/faker +``` + +## Basic Usage + +Use `Faker\Factory::create()` to create and initialize a faker generator, which can generate data by accessing properties named after the type of data you want. + +```php +name; + // 'Lucy Cechtelar'; +echo $faker->address; + // "426 Jordy Lodge + // Cartwrightshire, SC 88120-6700" +echo $faker->text; + // Sint velit eveniet. Rerum atque repellat voluptatem quia rerum. Numquam excepturi + // beatae sint laudantium consequatur. Magni occaecati itaque sint et sit tempore. Nesciunt + // amet quidem. Iusto deleniti cum autem ad quia aperiam. + // A consectetur quos aliquam. In iste aliquid et aut similique suscipit. Consequatur qui + // quaerat iste minus hic expedita. Consequuntur error magni et laboriosam. Aut aspernatur + // voluptatem sit aliquam. Dolores voluptatum est. + // Aut molestias et maxime. Fugit autem facilis quos vero. Eius quibusdam possimus est. + // Ea quaerat et quisquam. Deleniti sunt quam. Adipisci consequatur id in occaecati. + // Et sint et. Ut ducimus quod nemo ab voluptatum. +``` + +Even if this example shows a property access, each call to `$faker->name` yields a different (random) result. This is because Faker uses `__get()` magic, and forwards `Faker\Generator->$property` calls to `Faker\Generator->format($property)`. + +```php +name, "\n"; +} + // Adaline Reichel + // Dr. Santa Prosacco DVM + // Noemy Vandervort V + // Lexi O'Conner + // Gracie Weber + // Roscoe Johns + // Emmett Lebsack + // Keegan Thiel + // Wellington Koelpin II + // Ms. Karley Kiehn V +``` + +**Tip**: For a quick generation of fake data, you can also use Faker as a command line tool thanks to [faker-cli](https://github.com/bit3/faker-cli). + +## Formatters + +Each of the generator properties (like `name`, `address`, and `lorem`) are called "formatters". A faker generator has many of them, packaged in "providers". Here is a list of the bundled formatters in the default locale. + +### `Faker\Provider\Base` + + randomDigit // 7 + randomDigitNotNull // 5 + randomNumber($nbDigits = NULL) // 79907610 + randomFloat($nbMaxDecimals = NULL, $min = 0, $max = NULL) // 48.8932 + numberBetween($min = 1000, $max = 9000) // 8567 + randomLetter // 'b' + randomElements($array = array ('a','b','c'), $count = 1) // array('c') + randomElement($array = array ('a','b','c')) // 'b' + shuffle('hello, world') // 'rlo,h eoldlw' + shuffle(array(1, 2, 3)) // array(2, 1, 3) + numerify('Hello ###') // 'Hello 609' + lexify('Hello ???') // 'Hello wgt' + bothify('Hello ##??') // 'Hello 42jz' + asciify('Hello ***') // 'Hello R6+' + regexify('[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'); // sm0@y8k96a.ej + +### `Faker\Provider\Lorem` + + word // 'aut' + words($nb = 3) // array('porro', 'sed', 'magni') + sentence($nbWords = 6) // 'Sit vitae voluptas sint non voluptates.' + sentences($nb = 3) // array('Optio quos qui illo error.', 'Laborum vero a officia id corporis.', 'Saepe provident esse hic eligendi.') + paragraph($nbSentences = 3) // 'Ut ab voluptas sed a nam. Sint autem inventore aut officia aut aut blanditiis. Ducimus eos odit amet et est ut eum.' + paragraphs($nb = 3) // array('Quidem ut sunt et quidem est accusamus aut. Fuga est placeat rerum ut. Enim ex eveniet facere sunt.', 'Aut nam et eum architecto fugit repellendus illo. Qui ex esse veritatis.', 'Possimus omnis aut incidunt sunt. Asperiores incidunt iure sequi cum culpa rem. Rerum exercitationem est rem.') + text($maxNbChars = 200) // 'Fuga totam reiciendis qui architecto fugiat nemo. Consequatur recusandae qui cupiditate eos quod.' + +### `Faker\Provider\en_US\Person` + + title($gender = null|'male'|'female') // 'Ms.' + titleMale // 'Mr.' + titleFemale // 'Ms.' + suffix // 'Jr.' + name($gender = null|'male'|'female') // 'Dr. Zane Stroman' + firstName($gender = null|'male'|'female') // 'Maynard' + firstNameMale // 'Maynard' + firstNameFemale // 'Rachel' + lastName // 'Zulauf' + +### `Faker\Provider\en_US\Address` + + cityPrefix // 'Lake' + secondaryAddress // 'Suite 961' + state // 'NewMexico' + stateAbbr // 'OH' + citySuffix // 'borough' + streetSuffix // 'Keys' + buildingNumber // '484' + city // 'West Judge' + streetName // 'Keegan Trail' + streetAddress // '439 Karley Loaf Suite 897' + postcode // '17916' + address // '8888 Cummings Vista Apt. 101, Susanbury, NY 95473' + country // 'Falkland Islands (Malvinas)' + latitude // 77.147489 + longitude // 86.211205 + +### `Faker\Provider\en_US\PhoneNumber` + + phoneNumber // '132-149-0269x3767' + +### `Faker\Provider\en_US\Company` + + catchPhrase // 'Monitored regional contingency' + bs // 'e-enable robust architectures' + company // 'Bogan-Treutel' + companySuffix // 'and Sons' + +### `Faker\Provider\en_US\Text` + + realText($maxNbChars = 200, $indexSize = 2) // "And yet I wish you could manage it?) 'And what are they made of?' Alice asked in a shrill, passionate voice. 'Would YOU like cats if you were never even spoke to Time!' 'Perhaps not,' Alice replied." + +### `Faker\Provider\DateTime` + + unixTime($max = 'now') // 58781813 + dateTime($max = 'now') // DateTime('2008-04-25 08:37:17') + dateTimeAD($max = 'now') // DateTime('1800-04-29 20:38:49') + iso8601($max = 'now') // '1978-12-09T10:10:29+0000' + date($format = 'Y-m-d', $max = 'now') // '1979-06-09' + time($format = 'H:i:s', $max = 'now') // '20:49:42' + dateTimeBetween($startDate = '-30 years', $endDate = 'now') // DateTime('2003-03-15 02:00:49') + dateTimeThisCentury($max = 'now') // DateTime('1915-05-30 19:28:21') + dateTimeThisDecade($max = 'now') // DateTime('2007-05-29 22:30:48') + dateTimeThisYear($max = 'now') // DateTime('2011-02-27 20:52:14') + dateTimeThisMonth($max = 'now') // DateTime('2011-10-23 13:46:23') + amPm($max = 'now') // 'pm' + dayOfMonth($max = 'now') // '04' + dayOfWeek($max = 'now') // 'Friday' + month($max = 'now') // '06' + monthName($max = 'now') // 'January' + year($max = 'now') // '1993' + century // 'VI' + timezone // 'Europe/Paris' + +### `Faker\Provider\Internet` + + email // 'tkshlerin@collins.com' + safeEmail // 'king.alford@example.org' + freeEmail // 'bradley72@gmail.com' + companyEmail // 'russel.durward@mcdermott.org' + freeEmailDomain // 'yahoo.com' + safeEmailDomain // 'example.org' + userName // 'wade55' + password // 'k&|X+a45*2[' + domainName // 'wolffdeckow.net' + domainWord // 'feeney' + tld // 'biz' + url // 'http://www.skilesdonnelly.biz/aut-accusantium-ut-architecto-sit-et.html' + slug // 'aut-repellat-commodi-vel-itaque-nihil-id-saepe-nostrum' + ipv4 // '109.133.32.252' + localIpv4 // '10.242.58.8' + ipv6 // '8e65:933d:22ee:a232:f1c1:2741:1f10:117c' + macAddress // '43:85:B7:08:10:CA' + +### `Faker\Provider\UserAgent` + + userAgent // 'Mozilla/5.0 (Windows CE) AppleWebKit/5350 (KHTML, like Gecko) Chrome/13.0.888.0 Safari/5350' + chrome // 'Mozilla/5.0 (Macintosh; PPC Mac OS X 10_6_5) AppleWebKit/5312 (KHTML, like Gecko) Chrome/14.0.894.0 Safari/5312' + firefox // 'Mozilla/5.0 (X11; Linuxi686; rv:7.0) Gecko/20101231 Firefox/3.6' + safari // 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_7_1 rv:3.0; en-US) AppleWebKit/534.11.3 (KHTML, like Gecko) Version/4.0 Safari/534.11.3' + opera // 'Opera/8.25 (Windows NT 5.1; en-US) Presto/2.9.188 Version/10.00' + internetExplorer // 'Mozilla/5.0 (compatible; MSIE 7.0; Windows 98; Win 9x 4.90; Trident/3.0)' + +### `Faker\Provider\Payment` + + creditCardType // 'MasterCard' + creditCardNumber // '4485480221084675' + creditCardExpirationDate // 04/13 + creditCardExpirationDateString // '04/13' + creditCardDetails // array('MasterCard', '4485480221084675', 'Aleksander Nowak', '04/13') + swiftBicNumber // RZTIAT22263 + +### `Faker\Provider\Color` + + hexcolor // '#fa3cc2' + rgbcolor // '0,255,122' + rgbColorAsArray // array(0,255,122) + rgbCssColor // 'rgb(0,255,122)' + safeColorName // 'fuchsia' + colorName // 'Gainsbor' + +### `Faker\Provider\File` + + fileExtension // 'avi' + mimeType // 'video/x-msvideo' + // Copy a random file from the source to the target directory and returns the fullpath or filename + file($sourceDir = '/tmp', $targetDir = '/tmp') // '/path/to/targetDir/13b73edae8443990be1aa8f1a483bc27.jpg' + file($sourceDir, $targetDir, false) // '13b73edae8443990be1aa8f1a483bc27.jpg' + +### `Faker\Provider\Image` + + // Image generation provided by LoremPixel (http://lorempixel.com/) + imageUrl($width = 640, $height = 480) // 'http://lorempixel.com/640/480/' + imageUrl($width, $height, 'cats') // 'http://lorempixel.com/800/600/cats/' + imageUrl($width, $height, 'cats', true, 'Faker') // 'http://lorempixel.com/800/400/cats/Faker' + image($dir = '/tmp', $width = 640, $height = 480) // '/tmp/13b73edae8443990be1aa8f1a483bc27.jpg' + image($dir, $width, $height, 'cats') // 'tmp/13b73edae8443990be1aa8f1a483bc27.jpg' it's a cat! + image($dir, $width, $height, 'cats', true, 'Faker') // 'tmp/13b73edae8443990be1aa8f1a483bc27.jpg' it's a cat with Faker text + +### `Faker\Provider\Uuid` + + uuid // '7e57d004-2b97-0e7a-b45f-5387367791cd' + +### `Faker\Provider\Barcode` + + ean13 // '4006381333931' + ean8 // '73513537' + isbn13 // '9790404436093' + isbn10 // '4881416324' + +### `Faker\Provider\Miscellaneous` + + boolean($chanceOfGettingTrue = 50) // true + md5 // 'de99a620c50f2990e87144735cd357e7' + sha1 // 'f08e7f04ca1a413807ebc47551a40a20a0b4de5c' + sha256 // '0061e4c60dac5c1d82db0135a42e00c89ae3a333e7c26485321f24348c7e98a5' + locale // en_UK + countryCode // UK + languageCode // en + currencyCode // EUR + +### `Faker\Provider\Biased` + + // get a random number between 10 and 20, + // with more chances to be close to 20 + biasedNumberBetween($min = 10, $max = 20, $function = 'sqrt') + +## Unique and Optional modifiers + +Faker provides two special providers, `unique()` and `optional()`, to be called before any provider. `optional()` can be useful for seeding non-required fields, like a mobile telephone number; `unique()` is required to populate fields that cannot accept twice the same value, like primary identifiers. + +```php +// unique() forces providers to return unique values +$values = array(); +for ($i=0; $i < 10; $i++) { + // get a random digit, but always a new one, to avoid duplicates + $values []= $faker->unique()->randomDigit; +} +print_r($values); // [4, 1, 8, 5, 0, 2, 6, 9, 7, 3] + +// providers with a limited range will throw an exception when no new unique value can be generated +$values = array(); +try { + for ($i=0; $i < 10; $i++) { + $values []= $faker->unique()->randomDigitNotNull; + } +} catch (\OverflowException $e) { + echo "There are only 9 unique digits not null, Faker can't generate 10 of them!"; +} + +// you can reset the unique modifier for all providers by passing true as first argument +$faker->unique($reset = true)->randomDigitNotNull; // will not throw OverflowException since unique() was reset +// tip: unique() keeps one array of values per provider + +// optional() sometimes bypasses the provider to return a default value instead (which defaults to NULL) +$values = array(); +for ($i=0; $i < 10; $i++) { + // get a random digit, but also null sometimes + $values []= $faker->optional()->randomDigit; +} +print_r($values); // [1, 4, null, 9, 5, null, null, 4, 6, null] + +// optional() accepts a weight argument to specify the probability of receiving the default value. +// 0 will always return the default value; 1 will always return the provider. Default weight is 0.5. +$faker->optional($weight = 0.1)->randomDigit; // 90% chance of NULL +$faker->optional($weight = 0.9)->randomDigit; // 10% chance of NULL + +// optional() accepts a default argument to specify the default value to return. +// Defaults to NULL. +$faker->optional($weight = 0.5, $default = false)->randomDigit; // 50% chance of FALSE +$faker->optional($weight = 0.9, $default = 'abc')->word; // 10% chance of 'abc' +``` + +## Localization + +`Faker\Factory` can take a locale as an argument, to return localized data. If no localized provider is found, the factory fallbacks to the default locale (en_EN). + +```php +name, "\n"; +} + // Luce du Coulon + // Auguste Dupont + // Roger Le Voisin + // Alexandre Lacroix + // Jacques Humbert-Roy + // Thérèse Guillet-Andre + // Gilles Gros-Bodin + // Amélie Pires + // Marcel Laporte + // Geneviève Marchal +``` + +You can check available Faker locales in the source code, [under the `Provider` directory](https://github.com/fzaninotto/Faker/tree/master/src/Faker/Provider). The localization of Faker is an ongoing process, for which we need your help. Don't hesitate to create localized providers to your own locale and submit a PR! + +## Populating Entities Using an ORM or an ODM + +Faker provides adapters for Object-Relational and Object-Document Mappers (currently, [Propel](http://www.propelorm.org), [Doctrine2](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/), [CakePHP](http://cakephp.org) and [Mandango](https://github.com/mandango/mandango) are supported). These adapters ease the population of databases through the Entity classes provided by an ORM library (or the population of document stores using Document classes provided by an ODM library). + +To populate entities, create a new populator class (using a generator instance as parameter), then list the class and number of all the entities that must be generated. To launch the actual data population, call the `execute()` method. + +Here is an example showing how to populate 5 `Author` and 10 `Book` objects: + +```php +addEntity('Author', 5); +$populator->addEntity('Book', 10); +$insertedPKs = $populator->execute(); +``` + +The populator uses name and column type guessers to populate each column with relevant data. For instance, Faker populates a column named `first_name` using the `firstName` formatter, and a column with a `TIMESTAMP` type using the `dateTime` formatter. The resulting entities are therefore coherent. If Faker misinterprets a column name, you can still specify a custom closure to be used for populating a particular column, using the third argument to `addEntity()`: + +```php +addEntity('Book', 5, array( + 'ISBN' => function() use ($generator) { return $generator->ean13(); } +)); +``` + +In this example, Faker will guess a formatter for all columns except `ISBN`, for which the given anonymous function will be used. + +**Tip**: To ignore some columns, specify `null` for the column names in the third argument of `addEntity()`. This is usually necessary for columns added by a behavior: + +```php +addEntity('Book', 5, array( + 'CreatedAt' => null, + 'UpdatedAt' => null, +)); +``` + +Of course, Faker does not populate autoincremented primary keys. In addition, `Faker\ORM\Propel\Populator::execute()` returns the list of inserted PKs, indexed by class: + +```php + (34, 35, 36, 37, 38), +// 'Book' => (456, 457, 458, 459, 470, 471, 472, 473, 474, 475) +// ) +``` + +In the previous example, the `Book` and `Author` models share a relationship. Since `Author` entities are populated first, Faker is smart enough to relate the populated `Book` entities to one of the populated `Author` entities. + +Lastly, if you want to execute an arbitrary function on an entity before insertion, use the fourth argument of the `addEntity()` method: + +```php +addEntity('Book', 5, array(), array( + function($book) { $book->publish(); }, +)); +``` + +## Seeding the Generator + +You may want to get always the same generated data - for instance when using Faker for unit testing purposes. The generator offers a `seed()` method, which seeds the random number generator. Calling the same script twice with the same seed produces the same results. + +```php +seed(1234); + +echo $faker->name; // 'Jess Mraz I'; +``` + +> **Tip**: DateTime formatters won't reproduce the same fake data if you don't fix the `$max` value: +> +> ```php +> // even when seeded, this line will return different results because $max varies +> $faker->dateTime(); // equivalent to $faker->dateTime($max = 'now') +> // make sure you fix the $max parameter +> $faker->dateTime('2014-02-25 08:37:17'); // will return always the same date when seeded +> ``` +> +> **Tip**: Formatters won't reproduce the same fake data if you use the `rand()` php function. Use `$faker` or `mt_rand()` instead: +> +> ```php +> // bad +> $faker->realText(rand(10,20)); +> // good +> $faker->realText($faker->numberBetween(10,20)); +> ``` + + + +## Faker Internals: Understanding Providers + +A `Faker\Generator` alone can't do much generation. It needs `Faker\Provider` objects to delegate the data generation to them. `Faker\Factory::create()` actually creates a `Faker\Generator` bundled with the default providers. Here is what happens under the hood: + +```php +addProvider(new Faker\Provider\en_US\Person($faker)); +$faker->addProvider(new Faker\Provider\en_US\Address($faker)); +$faker->addProvider(new Faker\Provider\en_US\PhoneNumber($faker)); +$faker->addProvider(new Faker\Provider\en_US\Company($faker)); +$faker->addProvider(new Faker\Provider\Lorem($faker)); +$faker->addProvider(new Faker\Provider\Internet($faker)); +```` + +Whenever you try to access a property on the `$faker` object, the generator looks for a method with the same name in all the providers attached to it. For instance, calling `$faker->name` triggers a call to `Faker\Provider\Person::name()`. And since Faker starts with the last provider, you can easily override existing formatters: just add a provider containing methods named after the formatters you want to override. + +That means that you can easily add your own providers to a `Faker\Generator` instance. A provider is usually a class extending `\Faker\Provider\Base`. This parent class allows you to use methods like `lexify()` or `randomNumber()`; it also gives you access to formatters of other providers, through the protected `$generator` property. The new formatters are the public methods of the provider class. + +Here is an example provider for populating Book data: + +```php +generator->sentence($nbWords); + return substr($sentence, 0, strlen($sentence) - 1); + } + + public function ISBN() + { + return $this->generator->ean13(); + } +} +``` + +To register this provider, just add a new instance of `\Faker\Provider\Book` to an existing generator: + +```php +addProvider(new \Faker\Provider\Book($faker)); +``` + +Now you can use the two new formatters like any other Faker formatter: + +```php +setTitle($faker->title); +$book->setISBN($faker->ISBN); +$book->setSummary($faker->text); +$book->setPrice($faker->randomNumber(2)); +``` + +**Tip**: A provider can also be a Plain Old PHP Object. In that case, all the public methods of the provider become available to the generator. + +## Real Life Usage + +The following script generates a valid XML document: + +```php + + + + + + +boolean(25)): ?> + + +
+ streetAddress ?> + city ?> + postcode ?> + state ?> +
+ +boolean(33)): ?> + bs ?> + +boolean(33)): ?> + + + +boolean(15)): ?> +
+text(400) ?> +]]> +
+ +
+ +
+``` + +Running this script produces a document looking like: + +```xml + + + + +
+ 182 Harrison Cove + North Lloyd + 45577 + Alabama +
+ + orchestrate compelling web-readiness + +
+ +
+
+ + +
+ 90111 Hegmann Inlet + South Geovanymouth + 69961-9311 + Colorado +
+ + +
+ + +
+ 9791 Nona Corner + Harberhaven + 74062-8191 + RhodeIsland +
+ + +
+ + +
+ 11161 Schultz Via + Feilstad + 98019 + NewJersey +
+ + + +
+ +
+
+ + +
+ 6106 Nader Village Suite 753 + McLaughlinstad + 43189-8621 + Missouri +
+ + expedite viral synergies + + +
+ + +
+ 7546 Kuvalis Plaza + South Wilfrid + 77069 + Georgia +
+ + +
+ + + +
+ 478 Daisha Landing Apt. 510 + West Lizethhaven + 30566-5362 + WestVirginia +
+ + orchestrate dynamic networks + + +
+ +
+
+ + +
+ 1251 Koelpin Mission + North Revastad + 81620 + Maryland +
+ + +
+ + +
+ 6396 Langworth Hills Apt. 446 + New Carlos + 89399-0268 + Wyoming +
+ + + +
+ + + +
+ 2246 Kreiger Station Apt. 291 + Kaydenmouth + 11397-1072 + Wyoming +
+ + grow sticky portals + +
+ +
+
+
+``` + +## Language specific formatters + +### `Faker\Provider\at_AT\Payment` +```php +vat; // "AT U12345678" - Austrian Value Added Tax number +echo $faker->vat(false); // "ATU12345678" - unspaced Austrian Value Added Tax number + +``` + +### `Faker\Provider\be_BE\Payment` +```php +vat; // "BE 0123456789" - Belgian Value Added Tax number +echo $faker->vat(false); // "BE0123456789" - unspaced Belgian Value Added Tax number + +``` + +### `Faker\Provider\bg_BG\Payment` +```php +vat; // "BG 0123456789" - Bulgarian Value Added Tax number +echo $faker->vat(false); // "BG0123456789" - unspaced Bulgarian Value Added Tax number + +``` + +### `Faker\Provider\cs_CZ\Address` +```php +region; // "Liberecký kraj" + +``` + +### `Faker\Provider\cs_CZ\Company` +```php +ico; // "69663963" + +``` + +### `Faker\Provider\cs_CZ\DateTime` +```php +monthNameGenitive; // "prosince" +echo $faker->formattedDate; // "12. listopadu 2015" + +``` + +### `Faker\Provider\da_DK\Person` + +```php +cpr; // "051280-2387" + +``` + +### `Faker\Provider\da_DK\Address` + +```php +kommune; // "Frederiksberg" + +// Generates a random region name +echo $faker->region; // "Region Sjælland" + +``` + +### `Faker\Provider\da_DK\Company` + +```php +cvr; // "32458723" + +// Generates a random P number +echo $faker->p; // "5398237590" + +``` + +### `Faker\Provider\fr_FR\Company` + +```php +siren; // 082 250 104 + +// Generates a random SIRET number +echo $faker->siret; // 347 355 708 00224 +``` + +### `Faker\Provider\fr_FR\Address` + +```php +departmentName; // "Haut-Rhin" + +// Generates a random department number +echo $faker->departmentNumber; // "2B" + +// Generates a random department info (department number => department name) +$faker->department; // array('18' => 'Cher'); + +// Generates a random region +echo $faker->region; // "Saint-Pierre-et-Miquelon" + +``` + +### `Faker\Provider\ja_JP\Person` + +```php +kanaName; // "アオタ ミノル" + +// Generates a 'kana' first name +echo $faker->firstKanaName; // "ハルカ" + +// Generates a 'kana' last name +echo $faker->lastKanaName; // "ナカジマ" +``` + +### `Faker\Provider\kk_KZ\Company` + +```php +businessIdentificationNumber; // "150140000019" + +``` + +### `Faker\Provider\kk_KZ\Person` + +```php +individualIdentificationNumber; // "780322300455" + +``` + +### `Faker\Provider\ko_KR\Address` + +```php +metropolitanCity; // "서울특별시" + +// Generates a borough +echo $faker->borough; // "강남구" + +``` + + +### `Faker\Provider\lv_LV\Person` + +```php +personalIdentityNumber; // "140190-12301" + +``` + +### `Faker\Provider\pl_PL\Person` + +```php +pesel; // "40061451555" +// Generates a random personal identity card number +echo $faker->personalIdentityNumber; // "AKX383360" +// Generates a random taxpayer identification number (NIP) +echo $faker->taxpayerIdentificationNumber; // '8211575109' + +``` + +### `Faker\Provider\pl_PL\Company` + +```php +regon; // "714676680" +// Generates a random local REGON number +echo $faker->regonLocal; // "15346111382836" + +``` + +### `Faker\Provider\pl_PL\Payment` + +```php +bank; // "Narodowy Bank Polski" +// Generates a random bank account number +echo $faker->bankAccountNumber; // "PL14968907563953822118075816" + +``` + +### `Faker\Provider\pt_PT\Person` + +```php +taxpayerIdentificationNumber; // '165249277' + +``` + +### `Faker\Provider\pt_BR\PhoneNumber` + +```php +areaCode; // 21 +echo $faker->cellphone; // 9432-5656 +echo $faker->landline; // 2654-3445 +echo $faker->phone; // random landline, 8-digit or 9-digit cellphone number + +// Using the phone functions with a false argument returns unformatted numbers +echo $faker->cellphone(false); // 74336667 + +// cellphone() has a special second argument to add the 9th digit. Ignored if generated a Radio number +echo $faker->cellphone(true, true); // 98983-3945 or 7343-1290 + +// Using the "Number" suffix adds area code to the phone +echo $faker->cellphoneNumber; // (11) 98309-2935 +echo $faker->landlineNumber(false); // 3522835934 +echo $faker->phoneNumber; // formatted, random landline or cellphone (obbeying the 9th digit rule) +echo $faker->phoneNumberCleared; // not formatted, random landline or cellphone (obbeying the 9th digit rule) +``` + +### `Faker\Provider\pt_BR\Person` + +```php +name; // 'Sr. Luis Adriano Sepúlveda Filho' + +// Valid document generators have a boolean argument to remove formatting +echo $faker->cpf; // '145.343.345-76' +echo $faker->cpf(false); // '45623467866' +echo $faker->rg; // '84.405.736-3' +echo $faker->cnpj; // '23.663.478/0001-24' +``` + +### `Faker\Provider\ro_RO\Person` + +```php +prefixMale; // "ing." +// Generates a random female name prefix/title +echo $faker->prefixFemale; // "d-na." +// Generates a random male fist name +echo $faker->firstNameMale; // "Adrian" +// Generates a random female fist name +echo $faker->firstNameFemale; // "Miruna" + +// Generates a random Personal Numerical Code (CNP) +echo $faker->cnp; // "2800523081231" +echo $faker->cnp($gender = NULL, $century = NULL, $county = NULL); + +// Valid option values: +// $gender: m, f, 1, 2 +// $century: 1800, 1900, 2000, 1, 2, 3, 4, 5, 6 +// $county: 2 letter ISO 3166-2:RO county codes and B1-B6 for Bucharest's 6 sectors +``` + +### `Faker\Provider\ro_RO\PhoneNumber` + +```php +tollFreePhoneNumber; // "0800123456" +// Generates a random premium-rate phone number +echo $faker->premiumRatePhoneNumber; // "0900123456" +``` + +### `Faker\Provider\ru_RU\Payment` + +```php +bank; // "ОТП Банк" +``` + +### `Faker\Provider\en_NZ\Phone` + +```php +cellNumber; // "021 123 4567" + +// Generates a toll free number +echo $faker->tollFreeNumber; // "0800 123 456" + +// Area Code +echo $faker->areaCode; // "03" +``` + +### `Faker\Provider\sv_SE\Person` +```php +personalIdentityNumber() // '950910-0799' + +//Since the numbers are different for male and female persons, optionally you can specify gender. +echo $faker->personalIdentityNumber('female') // '950910-0781' + +``` + +### `Faker\Provider\ne_NP\Address` +```php +district; + +//Generates a Nepali city name +echo $faker->cityName; +``` + +## Third-Party Libraries Extending/Based On Faker + +* [BazingaFakerBundle](https://github.com/willdurand/BazingaFakerBundle): Put the awesome Faker library into the Symfony2 DIC and populate your database with fake data. +* [FakerServiceProvider](https://github.com/EmanueleMinotto/FakerServiceProvider): Faker Service Provider for Silex +* [faker-cli](https://github.com/bit3/faker-cli): Command Line Tool for the Faker PHP library +* [AliceFixturesBundle](https://github.com/h4cc/AliceFixturesBundle): A Symfony2 bundle for using Alice and Faker with data fixtures. Abled to use Doctrine ORM as well as Doctrine MongoDB ODM. +* [Factory Muffin](https://github.com/thephpleague/factory-muffin): enable the rapid creation of objects (PHP port of factory-girl) +* [CompanyNameGenerator](https://github.com/fzaninotto/CompanyNameGenerator): Generate names for English tech companies with class +* [datalea](https://github.com/spyrit/datalea) A highly customizable random test data generator web app +* [newage-ipsum](https://github.com/frequenc1/newage-ipsum): A new aged ipsum provider for the faker library inspired by http://sebpearce.com/bullshit/ +* [xml-faker](https://github.com/prewk/xml-faker): Create fake XML with Faker +* [faker-context](https://github.com/denheck/faker-context): Behat context using Faker to generate testdata +* [CronExpressionGenerator](https://github.com/swekaj/CronExpressionGenerator): Faker provider for generating random, valid cron expressions. + +## License + +Faker is released under the MIT Licence. See the bundled LICENSE file for details. diff --git a/vendor/fzaninotto/faker/src/Faker/Calculator/Luhn.php b/vendor/fzaninotto/faker/src/Faker/Calculator/Luhn.php new file mode 100644 index 0000000..4caad29 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Calculator/Luhn.php @@ -0,0 +1,55 @@ += 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; + } + + /** + * @return string + */ + public static function computeCheckDigit($partialNumber) + { + $checkDigit = self::checksum($partialNumber . '0'); + if ($checkDigit === 0) { + return 0; + } + + return (string) (10 - $checkDigit); + } + + /** + * Checks whether a number (partial number + check digit) is Luhn compliant + * + * @return boolean + */ + public static function isValid($number) + { + return self::checksum($number) === 0; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/DefaultGenerator.php b/vendor/fzaninotto/faker/src/Faker/DefaultGenerator.php new file mode 100644 index 0000000..ad75ccd --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/DefaultGenerator.php @@ -0,0 +1,27 @@ +optional(). + */ +class DefaultGenerator +{ + protected $default = null; + + public function __construct($default = null) + { + $this->default = $default; + } + + public function __get($attribute) + { + return $this->default; + } + + public function __call($method, $attributes) + { + return $this->default; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Documentor.php b/vendor/fzaninotto/faker/src/Faker/Documentor.php new file mode 100644 index 0000000..f13df1f --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Documentor.php @@ -0,0 +1,60 @@ +generator = $generator; + } + + public function getFormatters() + { + $formatters = array(); + $providers = array_reverse($this->generator->getProviders()); + $providers[]= new \Faker\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) { // modifier + $example = ''; + } else { + $example = var_export($example, true); + } + $formatters[$providerClass][$methodName . $parameters] = $example; + } + } + + return $formatters; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Factory.php b/vendor/fzaninotto/faker/src/Faker/Factory.php new file mode 100644 index 0000000..430a951 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Factory.php @@ -0,0 +1,46 @@ +addProvider(new $providerClassName($generator)); + } + + return $generator; + } + + protected static function getProviderClassname($provider, $locale = '') + { + if ($providerClass = self::findProviderClassname($provider, $locale)) { + return $providerClass; + } + // fallback to default locale + if ($providerClass = self::findProviderClassname($provider, static::DEFAULT_LOCALE)) { + return $providerClass; + } + // fallback to no locale + $providerClass = self::findProviderClassname($provider); + if (class_exists($providerClass)) { + 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; + } + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Generator.php b/vendor/fzaninotto/faker/src/Faker/Generator.php new file mode 100644 index 0000000..a169997 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Generator.php @@ -0,0 +1,239 @@ +providers, $provider); + } + + public function getProviders() + { + return $this->providers; + } + + public function seed($seed = null) + { + if ($seed === null) { + mt_srand(); + } else { + mt_srand($seed); + } + } + + public function format($formatter, $arguments = array()) + { + return call_user_func_array($this->getFormatter($formatter), $arguments); + } + + /** + * @return Callable + */ + 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)); + } + + /** + * Replaces tokens ('{{ tokenName }}') with the result from the token method call + * + * @param string $string String that needs to bet parsed + * @return string + */ + 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); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Guesser/Name.php b/vendor/fzaninotto/faker/src/Faker/Guesser/Name.php new file mode 100644 index 0000000..604cce1 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Guesser/Name.php @@ -0,0 +1,92 @@ +generator = $generator; + } + + public function guessFormat($name) + { + $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 ($name) { + case 'first_name': + case 'firstname': + return function () use ($generator) { + return $generator->firstName; + }; + case 'last_name': + case 'lastname': + return function () use ($generator) { + return $generator->lastName; + }; + case 'username': + case 'login': + return function () use ($generator) { + return $generator->userName; + }; + case 'email': + return function () use ($generator) { + return $generator->email; + }; + case 'phone_number': + case 'phonenumber': + case 'phone': + return function () use ($generator) { + return $generator->phoneNumber; + }; + case 'address': + return function () use ($generator) { + return $generator->address; + }; + case 'city': + 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 'country': + return function () use ($generator) { + return $generator->country; + }; + case 'title': + return function () use ($generator) { + return $generator->sentence; + }; + case 'body': + case 'summary': + return function () use ($generator) { + return $generator->text; + }; + } + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/ColumnTypeGuesser.php b/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/ColumnTypeGuesser.php new file mode 100644 index 0000000..0f36f60 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/ColumnTypeGuesser.php @@ -0,0 +1,64 @@ +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 () use ($generator) { + return $generator->randomNumber(10); + }; + case 'biginteger': + return function () use ($generator) { + return $generator->randomNumber(20); + }; + 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; + } + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/EntityPopulator.php b/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/EntityPopulator.php new file mode 100644 index 0000000..2eb1194 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/EntityPopulator.php @@ -0,0 +1,149 @@ +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($populator) + { + $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)]; + $primaryKey = $table->primaryKey(); + $data[$assoc->foreignKey()] = $foreignKey; + return $data; + }; + } + + // TODO check if TreeBehavior attached to modify lft/rgt cols + + 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(); + return $entity->{$pk}; + } + + 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); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/Populator.php b/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/Populator.php new file mode 100644 index 0000000..cd5aa47 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/CakePHP/Populator.php @@ -0,0 +1,84 @@ +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->mergeModifiers($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; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/ColumnTypeGuesser.php b/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/ColumnTypeGuesser.php new file mode 100644 index 0000000..899dc95 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/ColumnTypeGuesser.php @@ -0,0 +1,68 @@ +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: + // no smart way to guess what the user expects here + return null; + } + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/EntityPopulator.php b/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/EntityPopulator.php new file mode 100644 index 0000000..5ed8acb --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/EntityPopulator.php @@ -0,0 +1,193 @@ +class = $class; + } + + /** + * @return string + */ + 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; + } + + if ($formatter = $nameGuesser->guessFormat($fieldName)) { + $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; + $mappings = $this->class->getAssociationMappings(); + foreach ($mappings as $mapping) { + if ($mapping['targetEntity'] == $relatedClass) { + if ($mapping['type'] == ClassMetadata::ONE_TO_ONE) { + $unique = true; + $optional = isset($mapping['joinColumns'][0]['nullable']) ? $mapping['joinColumns'][0]['nullable'] : false; + break; + } + } + } + + $index = 0; + $formatters[$assocName] = function ($inserted) use ($relatedClass, &$index, $unique, $optional) { + if ($unique && isset($inserted[$relatedClass])) { + $related = null; + if (isset($inserted[$relatedClass][$index]) || !$optional) { + $related = $inserted[$relatedClass][$index]; + } + + $index++; + + return $related; + } elseif (isset($inserted[$relatedClass])) { + return $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)]; + } + + return null; + }; + } + + return $formatters; + } + + /** + * Insert one new record using the Entity class. + */ + 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) { + $value = is_callable($format) ? $format($insertedEntities, $obj) : $format; + $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, EntityManagerInterface $manager) + { + /* @var $repository \Doctrine\ORM\EntityRepository */ + $repository = $manager->getRepository(get_class($obj)); + $result = $repository->createQueryBuilder('e') + ->select(sprintf('e.%s', $column)) + ->getQuery() + ->getResult(); + $ids = array_map('current', $result); + + $id = null; + do { + $id = rand(); + } while (in_array($id, $ids)); + + return $id; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/Populator.php b/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/Populator.php new file mode 100644 index 0000000..27114c0 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Doctrine/Populator.php @@ -0,0 +1,78 @@ +generator = $generator; + $this->manager = $manager; + } + + /** + * Add an order for the generation of $number records for $entity. + * + * @param mixed $entity A Doctrine classname, or a \Faker\ORM\Doctrine\EntityPopulator instance + * @param int $number The number of entities to populate + */ + 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; + } + + /** + * Populate the database using all the Entity classes previously added. + * + * @param EntityManager $entityManager A Doctrine connection object + * + * @return array A list of the inserted PKs + */ + 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; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/ColumnTypeGuesser.php b/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/ColumnTypeGuesser.php new file mode 100644 index 0000000..e64dc75 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/ColumnTypeGuesser.php @@ -0,0 +1,43 @@ +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: + // no smart way to guess what the user expects here + return null; + } + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/EntityPopulator.php b/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/EntityPopulator.php new file mode 100644 index 0000000..061df77 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/EntityPopulator.php @@ -0,0 +1,110 @@ +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); + + // fields + foreach ($metadata['fields'] as $fieldName => $field) { + if ($formatter = $nameGuesser->guessFormat($fieldName)) { + $formatters[$fieldName] = $formatter; + continue; + } + if ($formatter = $columnTypeGuesser->guessFormat($field)) { + $formatters[$fieldName] = $formatter; + continue; + } + } + + // references + 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; + } + + /** + * Insert one new record using the Entity class. + */ + 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; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/Populator.php b/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/Populator.php new file mode 100644 index 0000000..57a06a5 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Mandango/Populator.php @@ -0,0 +1,61 @@ +generator = $generator; + $this->mandango = $mandango; + } + + /** + * Add an order for the generation of $number records for $entity. + * + * @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel\EntityPopulator instance + * @param int $number The number of entities to populate + */ + 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; + } + + /** + * Populate the database using all the Entity classes previously added. + * + * @return array A list of the inserted entities. + */ + 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; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Propel/ColumnTypeGuesser.php b/vendor/fzaninotto/faker/src/Faker/ORM/Propel/ColumnTypeGuesser.php new file mode 100644 index 0000000..cb3e446 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Propel/ColumnTypeGuesser.php @@ -0,0 +1,99 @@ +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: + // no smart way to guess what the user expects here + return null; + } + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Propel/EntityPopulator.php b/vendor/fzaninotto/faker/src/Faker/ORM/Propel/EntityPopulator.php new file mode 100644 index 0000000..a83d872 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Propel/EntityPopulator.php @@ -0,0 +1,170 @@ +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) { + // skip behavior columns, handled by modifiers + 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())) { + $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, $generator) { + $maxRank = isset($inserted[$class]) ? count($inserted[$class]) : 0; + $obj->insertAtRank(mt_rand(1, $maxRank + 1)); + }; + break; + } + } + + return $modifiers; + } + + /** + * Insert one new record using the Entity class. + */ + 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(); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/ORM/Propel/Populator.php b/vendor/fzaninotto/faker/src/Faker/ORM/Propel/Populator.php new file mode 100644 index 0000000..067229b --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/ORM/Propel/Populator.php @@ -0,0 +1,86 @@ +generator = $generator; + } + + /** + * Add an order for the generation of $number records for $entity. + * + * @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel\EntityPopulator instance + * @param int $number The number of entities to populate + */ + 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; + } + + /** + * Populate the database using all the Entity classes previously added. + * + * @param PropelPDO $con A Propel connection object + * + * @return array A list of the inserted PKs + */ + 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() + { + // use the first connection available + $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); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/Address.php new file mode 100644 index 0000000..c11b5b1 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/Address.php @@ -0,0 +1,123 @@ +generator->parse($format); + } + + /** + * @example 'Crist Parks' + */ + public function streetName() + { + $format = static::randomElement(static::$streetNameFormats); + + return $this->generator->parse($format); + } + + /** + * @example '791 Crist Parks' + */ + public function streetAddress() + { + $format = static::randomElement(static::$streetAddressFormats); + + return $this->generator->parse($format); + } + + /** + * @example 86039-9874 + */ + public static function postcode() + { + return static::toUpper(static::bothify(static::randomElement(static::$postcode))); + } + + /** + * @example '791 Crist Parks, Sashabury, IL 86039-9874' + */ + public function address() + { + $format = static::randomElement(static::$addressFormats); + + return $this->generator->parse($format); + } + + /** + * @example 'Japan' + */ + public static function country() + { + return static::randomElement(static::$country); + } + + /** + * @example 77.147489 + * @return float Uses signed degrees format (returns a float number between -90 and 90) + */ + public static function latitude() + { + return static::randomFloat(6, 0, 180) - 90; + } + + /** + * @example 86.211205 + * @return float Uses signed degrees format (returns a float number between -180 and 180) + */ + public static function longitude() + { + return static::randomFloat(6, 0, 360) - 180; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/Barcode.php b/vendor/fzaninotto/faker/src/Faker/Provider/Barcode.php new file mode 100644 index 0000000..5281e37 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/Barcode.php @@ -0,0 +1,110 @@ +numerify(str_repeat('#', $length - 1)); + + return $code . static::eanChecksum($code); + } + + /** + * Utility function for computing EAN checksums + */ + 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; + } + + /** + * ISBN-10 check digit + * @link http://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digits + * + * @param string $input ISBN without check-digit + * @throws \LengthException When wrong input length passed + * + * @return integer Check digit + */ + protected static function isbnChecksum($input) + { + // We're calculating check digit for ISBN-10 + // so, the length of the input should be 9 + $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; + + // 10 is replaced by X + return ($result < 10)?$result:'X'; + } + + /** + * Get a random EAN13 barcode. + * @return string + * @example '4006381333931' + */ + public function ean13() + { + return $this->ean(13); + } + + /** + * Get a random EAN8 barcode. + * @return string + * @example '73513537' + */ + public function ean8() + { + return $this->ean(8); + } + + /** + * Get a random ISBN-10 code + * @link http://en.wikipedia.org/wiki/International_Standard_Book_Number + * + * @return string + * @example '4881416324' + */ + public function isbn10() + { + $code = $this->numerify(str_repeat('#', 9)); + + return $code . static::isbnChecksum($code); + } + + /** + * Get a random ISBN-13 code + * @link http://en.wikipedia.org/wiki/International_Standard_Book_Number + * + * @return string + * @example '9790404436093' + */ + public function isbn13() + { + $code = '97' . static::numberBetween(8, 9) . $this->numerify(str_repeat('#', 9)); + + return $code . static::eanChecksum($code); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/Base.php b/vendor/fzaninotto/faker/src/Faker/Provider/Base.php new file mode 100644 index 0000000..9cfda63 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/Base.php @@ -0,0 +1,509 @@ +generator = $generator; + } + + /** + * Returns a random number between 0 and 9 + * + * @return integer + */ + public static function randomDigit() + { + return mt_rand(0, 9); + } + + /** + * Returns a random number between 1 and 9 + * + * @return integer + */ + public static function randomDigitNotNull() + { + return mt_rand(1, 9); + } + + /** + * Returns a random integer with 0 to $nbDigits digits. + * + * The maximum value returned is mt_getrandmax() + * + * @param integer $nbDigits Defaults to a random number between 1 and 9 + * @param boolean $strict Whether the returned number should have exactly $nbDigits + * @example 79907610 + * + * @return integer + */ + 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); + } + + /** + * Return a random float number + * + * @param int $nbMaxDecimals + * @param int|float $min + * @param int|float $max + * @example 48.8932 + * + * @return float + */ + 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) { + $tmp = $min; + $min = $max; + $max = $tmp; + } + + return round($min + mt_rand() / mt_getrandmax() * ($max - $min), $nbMaxDecimals); + } + + /** + * Returns a random number between $min and $max + * + * @param integer $min default to 0 + * @param integer $max defaults to 32 bit max integer, ie 2147483647 + * @example 79907610 + * + * @return integer + */ + public static function numberBetween($min = 0, $max = 2147483647) + { + return mt_rand($min, $max); + } + + /** + * Returns a random letter from a to z + * + * @return string + */ + public static function randomLetter() + { + return chr(mt_rand(97, 122)); + } + + /** + * Returns a random ASCII character (excluding accents and special chars) + */ + public static function randomAscii() + { + return chr(mt_rand(33, 126)); + } + + /** + * Returns random elements from a provided array + * + * @param array $array Array to take elements from. Defaults to a-f + * @param integer $count Number of elements to take. + * @throws \LengthException When requesting more elements than provided + * + * @return array New array with $count elements from $array + */ + public static function randomElements(array $array = array('a', 'b', 'c'), $count = 1) + { + $allKeys = array_keys($array); + $numKeys = count($allKeys); + + if ($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 (isset($keys[$num])) { + continue; + } + + $keys[$num] = true; + $elements[] = $array[$allKeys[$num]]; + $numElements++; + } + + return $elements; + } + + /** + * Returns a random element from a passed array + * + * @param array $array + * @return mixed + */ + public static function randomElement($array = array('a', 'b', 'c')) + { + if (!$array) { + return null; + } + $elements = static::randomElements($array, 1); + + return $elements[0]; + } + + /** + * Returns a random key from a passed associative array + * + * @param array $array + * @return int|string|null + */ + public static function randomKey($array = array()) + { + if (!$array) { + return null; + } + $keys = array_keys($array); + $key = $keys[mt_rand(0, count($keys) - 1)]; + + return $key; + } + + /** + * Returns a shuffled version of the argument. + * + * This function accepts either an array, or a string. + * + * @example $faker->shuffle([1, 2, 3]); // [2, 1, 3] + * @example $faker->shuffle('hello, world'); // 'rlo,h eold!lw' + * + * @see shuffleArray() + * @see shuffleString() + * + * @param array|string $arg The set to shuffle + * @return array|string The shuffled set + */ + 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'); + } + + /** + * Returns a shuffled version of the array. + * + * This function does not mutate the original array. It uses the + * Fisher–Yates algorithm, which is unbiaised, together with a Mersenne + * twister random generator. This function is therefore more random than + * PHP's shuffle() function, and it is seedable. + * + * @link http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + * + * @example $faker->shuffleArray([1, 2, 3]); // [2, 1, 3] + * + * @param array $array The set to shuffle + * @return array The shuffled set + */ + public static function shuffleArray($array = array()) + { + $shuffledArray = array(); + $i = 0; + reset($array); + while (list($key, $value) = each($array)) { + 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; + } + + /** + * Returns a shuffled version of the string. + * + * This function does not mutate the original string. It uses the + * Fisher–Yates algorithm, which is unbiaised, together with a Mersenne + * twister random generator. This function is therefore more random than + * PHP's shuffle() function, and it is seedable. Additionally, it is + * UTF8 safe if the mb extension is available. + * + * @link http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + * + * @example $faker->shuffleString('hello, world'); // 'rlo,h eold!lw' + * + * @param string $string The set to shuffle + * @param string $encoding The string encoding (defaults to UTF-8) + * @return string The shuffled set + */ + public static function shuffleString($string = '', $encoding = 'UTF-8') + { + if (function_exists('mb_strlen')) { + // UTF8-safe str_split() + $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 join('', static::shuffleArray($array)); + } + + /** + * Replaces all hash sign ('#') occurrences with a random number + * Replaces all percentage sign ('%') occurrences with a not null number + * + * @param string $string String that needs to bet parsed + * @return string + */ + public static function numerify($string = '###') + { + // instead of using randomDigit() several times, which is slow, + // count the number of hashes and generate once a large number + $toReplace = array(); + for ($i = 0, $count = strlen($string); $i < $count; $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 = preg_replace_callback('/\%/u', 'static::randomDigitNotNull', $string); + + return $string; + } + + /** + * Replaces all question mark ('?') occurrences with a random letter + * + * @param string $string String that needs to bet parsed + * @return string + */ + public static function lexify($string = '????') + { + return preg_replace_callback('/\?/u', 'static::randomLetter', $string); + } + + /** + * Replaces hash signs and question marks with random numbers and letters + * + * @param string $string String that needs to bet parsed + * @return string + */ + public static function bothify($string = '## ??') + { + return static::lexify(static::numerify($string)); + } + + /** + * Replaces * signs with random numbers and letters and special characters + * + * @example $faker->asciify(''********'); // "s5'G!uC3" + * + * @param string $string String that needs to bet parsed + * @return string + */ + public static function asciify($string = '****') + { + return preg_replace_callback('/\*/u', 'static::randomAscii', $string); + } + + /** + * Transforms a basic regular expression into a random string satisfying the expression. + * + * @example $faker->regexify('[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'); // sm0@y8k96a.ej + * + * Regex delimiters '/.../' and begin/end markers '^...$' are ignored. + * + * Only supports a small subset of the regex syntax. For instance, + * unicode, negated classes, unbouned ranges, subpatterns, back references, + * assertions, recursive patterns, and comments are not supported. Escaping + * support is extremely fragile. + * + * This method is also VERY slow. Use it only when no other formatter + * can generate the fake data you want. For instance, prefer calling + * `$faker->email` rather than `regexify` with the previous regular + * expression. + * + * Also note than `bothify` can probably do most of what this method does, + * but much faster. For instance, for a dummy email generation, try + * `$faker->bothify('?????????@???.???')`. + * + * @see https://github.com/icomefromthenet/ReverseRegex for a more robust implementation + * + * @param string $regex A regular expression (delimiters are optional) + * @return string + */ + public static function regexify($regex = '') + { + // ditch the anchors + $regex = preg_replace('/^\/?\^?/', '', $regex); + $regex = preg_replace('/\$?\/?$/', '', $regex); + // All {2} become {2,2} + $regex = preg_replace('/\{(\d+)\}/', '{\1,\1}', $regex); + // Single-letter quantifiers (?, *, +) become bracket quantifiers ({0,1}, {0,rand}, {1, rand}) + $regex = preg_replace('/(?generator; + } + + return new DefaultGenerator($default); + } + + /** + * Chainable method for making any formatter unique. + * + * + * // will never return twice the same value + * $faker->unique()->randomElement(array(1, 2, 3)); + * + * + * @param boolean $reset If set to true, resets the list of existing values + * @param integer $maxRetries Maximum number of retries to find a unique value, + * After which an OverflowException is thrown. + * @throws \OverflowException When no unique value can be found by iterating $maxRetries times + * + * @return UniqueGenerator A proxy class returning only non-existing values + */ + public function unique($reset = false, $maxRetries = 10000) + { + if ($reset || !$this->unique) { + $this->unique = new UniqueGenerator($this->generator, $maxRetries); + } + + return $this->unique; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/Biased.php b/vendor/fzaninotto/faker/src/Faker/Provider/Biased.php new file mode 100644 index 0000000..c9ebb41 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/Biased.php @@ -0,0 +1,64 @@ +generator->parse($format); + } + + /** + * @example 'Ltd' + */ + public static function companySuffix() + { + return static::randomElement(static::$companySuffix); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/DateTime.php b/vendor/fzaninotto/faker/src/Faker/Provider/DateTime.php new file mode 100644 index 0000000..776a841 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/DateTime.php @@ -0,0 +1,240 @@ +getTimestamp(); + } + + return strtotime(empty($max) ? 'now' : $max); + } + + /** + * Get a timestamp between January 1, 1970 and now + * + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return int + * + * @example 1061306726 + */ + public static function unixTime($max = 'now') + { + return mt_rand(0, static::getMaxTimestamp($max)); + } + + /** + * Get a datetime object for a date between January 1, 1970 and now + * + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @example DateTime('2005-08-16 20:39:21') + * @return \DateTime + */ + public static function dateTime($max = 'now') + { + return new \DateTime('@' . static::unixTime($max)); + } + + /** + * Get a datetime object for a date between January 1, 001 and now + * + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @example DateTime('1265-03-22 21:15:52') + * @return \DateTime + */ + public static function dateTimeAD($max = 'now') + { + return new \DateTime('@' . mt_rand(-62135597361, static::getMaxTimestamp($max))); + } + + /** + * get a date string formatted with ISO8601 + * + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example '2003-10-21T16:05:52+0000' + */ + public static function iso8601($max = 'now') + { + return static::date(\DateTime::ISO8601, $max); + } + + /** + * Get a date string between January 1, 1970 and now + * + * @param string $format + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example '2008-11-27' + */ + public static function date($format = 'Y-m-d', $max = 'now') + { + return static::dateTime($max)->format($format); + } + + /** + * Get a time string (24h format by default) + * + * @param string $format + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example '15:02:34' + */ + public static function time($format = 'H:i:s', $max = 'now') + { + return static::dateTime($max)->format($format); + } + + /** + * Get a DateTime object based on a random date between two given dates. + * Accepts date strings that can be recognized by strtotime(). + * + * @param string $startDate Defaults to 30 years ago + * @param string $endDate Defaults to "now" + * @example DateTime('1999-02-02 11:42:52') + * @return \DateTime + */ + public static function dateTimeBetween($startDate = '-30 years', $endDate = 'now') + { + $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); + + $ts = new \DateTime('@' . $timestamp); + $ts->setTimezone(new \DateTimeZone(date_default_timezone_get())); + + return $ts; + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @example DateTime('1964-04-04 11:02:02') + * @return \DateTime + */ + public static function dateTimeThisCentury($max = 'now') + { + return static::dateTimeBetween('-100 year', $max); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @example DateTime('2010-03-10 05:18:58') + * @return \DateTime + */ + public static function dateTimeThisDecade($max = 'now') + { + return static::dateTimeBetween('-10 year', $max); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @example DateTime('2011-09-19 09:24:37') + * @return \DateTime + */ + public static function dateTimeThisYear($max = 'now') + { + return static::dateTimeBetween('-1 year', $max); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @example DateTime('2011-10-05 12:51:46') + * @return \DateTime + */ + public static function dateTimeThisMonth($max = 'now') + { + return static::dateTimeBetween('-1 month', $max); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example 'am' + */ + public static function amPm($max = 'now') + { + return static::dateTime($max)->format('a'); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example '22' + */ + public static function dayOfMonth($max = 'now') + { + return static::dateTime($max)->format('d'); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example 'Tuesday' + */ + public static function dayOfWeek($max = 'now') + { + return static::dateTime($max)->format('l'); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example '7' + */ + public static function month($max = 'now') + { + return static::dateTime($max)->format('m'); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example 'September' + */ + public static function monthName($max = 'now') + { + return static::dateTime($max)->format('F'); + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return int + * @example 1673 + */ + public static function year($max = 'now') + { + return static::dateTime($max)->format('Y'); + } + + /** + * @return string + * @example 'XVII' + */ + public static function century() + { + return static::randomElement(static::$century); + } + + /** + * @return string + * @example 'Europe/Paris' + */ + public static function timezone() + { + return static::randomElement(\DateTimeZone::listIdentifiers()); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/File.php b/vendor/fzaninotto/faker/src/Faker/Provider/File.php new file mode 100644 index 0000000..3897c27 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/File.php @@ -0,0 +1,606 @@ + file extension(s) + * @link http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types + */ + 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', + ); + + /** + * Get a random MIME type + * + * @return string + * @example 'video/avi' + */ + public static function mimeType() + { + return static::randomElement(array_keys(static::$mimeTypes)); + } + + /** + * Get a random file extension (without a dot) + * + * @example avi + * @return string + */ + public static function fileExtension() + { + $random_extension = static::randomElement(array_values(static::$mimeTypes)); + + return is_array($random_extension) ? static::randomElement($random_extension) : $random_extension; + } + + /** + * Copy a random file from the source directory to the target directory and returns the filename/fullpath + * + * @param string $sourceDirectory The directory to look for random file taking + * @param string $targetDirectory + * @param boolean $fullPath Whether to have the full path or just the filename + * @return string + */ + 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.'); + } + + // Drop . and .. and reset array keys + $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; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/Image.php b/vendor/fzaninotto/faker/src/Faker/Provider/Image.php new file mode 100644 index 0000000..40aeac5 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/Image.php @@ -0,0 +1,88 @@ + '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','ā' => 'a','ţ' => 't','ʼ' => "'", '̧' => '', + 'ḩ' => 'h','ʼ' => "'",'‘' => "'",'’' => "'",'ừ' => 'u','/' => '', + 'ế' => 'e','ả' => 'a','ị' => 'i','ậ' => 'a','ệ' => 'e','ỉ' => 'i', + 'ồ' => 'o','ề' => 'e','ơ' => 'o','ạ' => 'a','ẵ' => 'a','ư' => 'u', + 'ằ' => 'a','ầ' => 'a','ḑ' => 'd','Ḩ' => 'H','Ḑ' => 'D','ḑ' => 'd', + 'Ģ' => 'G','Š' => 'S','ļ' => 'l','ž' => 'z','Ē' => 'E','ņ' => 'n', + 'Č' => 'C','ș' => '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', + ); + + return str_replace(array_keys($transliterationTable), array_values($transliterationTable), $string); + } + + private static function transliterate($string) + { + $transId = 'Any-Latin; Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC; Lower();'; + if (function_exists('transliterator_transliterate') && $transliterator = \Transliterator::create($transId)) { + $transString = $transliterator->transliterate($string); + } else { + $transString = static::toAscii($string); + } + + return preg_replace('/[^A-Za-z0-9_.]/u', '', $transString); + } + + /** + * @example 'jdoe@acme.biz' + */ + public function email() + { + $format = static::randomElement(static::$emailFormats); + + return $this->generator->parse($format); + } + + /** + * @example 'jdoe@example.com' + */ + final public function safeEmail() + { + return preg_replace('/\s/u', '', $this->userName() . '@' . static::safeEmailDomain()); + } + + /** + * @example 'jdoe@gmail.com' + */ + public function freeEmail() + { + return preg_replace('/\s/u', '', $this->userName() . '@' . static::freeEmailDomain()); + } + + /** + * @example 'jdoe@dawson.com' + */ + public function companyEmail() + { + return preg_replace('/\s/u', '', $this->userName() . '@' . $this->domainName()); + } + + /** + * @example 'gmail.com' + */ + public static function freeEmailDomain() + { + return static::randomElement(static::$freeEmailDomain); + } + + /** + * @example 'example.org' + */ + final public static function safeEmailDomain() + { + $domains = array( + 'example.com', + 'example.org', + 'example.net' + ); + + return static::randomElement($domains); + } + /** + * @example 'jdoe' + */ + public function userName() + { + $format = static::randomElement(static::$userNameFormats); + $username = static::bothify($this->generator->parse($format)); + + return static::transliterate($username); + } + /** + * @example 'fY4èHdZv68' + */ + public function password($minLength = 6, $maxLength = 20) + { + $pattern = str_repeat('*', $this->numberBetween($minLength, $maxLength)); + + return $this->asciify($pattern); + } + + /** + * @example 'tiramisu.com' + */ + public function domainName() + { + return $this->domainWord() . '.' . $this->tld(); + } + + /** + * @example 'faber' + */ + public function domainWord() + { + $lastName = $this->generator->format('lastName'); + + return static::transliterate($lastName); + } + + /** + * @example 'com' + */ + public function tld() + { + return static::randomElement(static::$tld); + } + + /** + * @example 'http://www.runolfsdottir.com/' + */ + public function url() + { + $format = static::randomElement(static::$urlFormats); + + return $this->generator->parse($format); + } + + /** + * @example 'aut-repellat-commodi-vel-itaque-nihil-id-saepe-nostrum' + */ + 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, '-'); + } + + /** + * @example '237.149.115.38' + */ + public function ipv4() + { + return long2ip(mt_rand(0, 1) == 0 ? mt_rand(-2147483648, 0) : mt_rand(1, 2147483647)); + } + + /** + * @example '35cd:186d:3e23:2986:ef9f:5b41:42a4:e6f1' + */ + public function ipv6() + { + $res = array(); + for ($i=0; $i < 8; $i++) { + $res []= dechex(mt_rand(0, "65535")); + } + + return join(':', $res); + } + + /** + * @example '10.1.1.17' + */ + public static function localIpv4() + { + if (static::numberBetween(0, 1) === 0) { + // 10.x.x.x range + $ip = long2ip(static::numberBetween(167772160, 184549375)); + } else { + // 192.168.x.x range + $ip = long2ip(static::numberBetween(3232235520, 3232301055)); + } + + return $ip; + } + + /** + * @example '32:F1:39:2F:D6:18' + */ + public static function macAddress() + { + for ($i=0; $i<6; $i++) { + $mac[] = sprintf('%02X', static::numberBetween(0, 0xff)); + } + $mac = implode(':', $mac); + + return $mac; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/Lorem.php b/vendor/fzaninotto/faker/src/Faker/Provider/Lorem.php new file mode 100644 index 0000000..7ba0ced --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/Lorem.php @@ -0,0 +1,215 @@ + array( + "4539########", + "4539###########", + "4556########", + "4556###########", + "4916########", + "4916###########", + "4532########", + "4532###########", + "4929########", + "4929###########", + "40240071####", + "40240071#######", + "4485########", + "4485###########", + "4716########", + "4716###########", + "4###########", + "4##############" + ), + 'MasterCard' => array( + "51#############", + "52#############", + "53#############", + "54#############", + "55#############" + ), + 'American Express' => array( + "34############", + "37############" + ), + 'Discover Card' => array( + "6011###########" + ), + ); + + /** + * @var array list of IBAN formats, source: @link http://www.swift.com/dsp/resources/documents/IBAN_Registry.txt + */ + 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)), + '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('c', 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('c', 1), array('c', 16)), + 'VG' => array(array('a', 4), array('n', 16)), + ); + + /** + * @return string Returns a credit card vendor name + * + * @example 'MasterCard' + */ + public static function creditCardType() + { + return static::randomElement(static::$cardVendors); + } + + /** + * Returns the String of a credit card number. + * + * @param string $type Supporting any of 'Visa', 'MasterCard', 'Amercian Express', and 'Discover' + * @param boolean $formatted Set to true if the output string should contain one separator every 4 digits + * @param string $separator Separator string for formatting card number. Defaults to dash (-). + * @return string + * + * @example '4485480221084675' + */ + 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; + } + + /** + * @param boolean $valid True (by default) to get a valid expiration date, false to get a maybe valid date + * @return \DateTime + * @example 04/13 + */ + public function creditCardExpirationDate($valid = true) + { + if ($valid) { + return $this->generator->dateTimeBetween('now', '36 months'); + } + + return $this->generator->dateTimeBetween('-36 months', '36 months'); + } + + /** + * @param boolean $valid True (by default) to get a valid expiration date, false to get a maybe valid date + * @param string $expirationDateFormat + * @return string + * @example '04/13' + */ + public function creditCardExpirationDateString($valid = true, $expirationDateFormat = null) + { + return $this->creditCardExpirationDate($valid)->format(is_null($expirationDateFormat) ? static::$expirationDateFormat : $expirationDateFormat); + } + + /** + * @param boolean $valid True (by default) to get a valid expiration date, false to get a maybe valid date + * @return array + */ + public function creditCardDetails($valid = true) + { + $type = static::creditCardType(); + + return array( + 'type' => $type, + 'number' => static::creditCardNumber($type), + 'name' => $this->generator->name(), + 'expirationDate' => $this->creditCardExpirationDateString($valid) + ); + } + + /** + * International Bank Account Number (IBAN) + * + * @link http://en.wikipedia.org/wiki/International_Bank_Account_Number + * @param string $countryCode ISO 3166-1 alpha-2 country code + * @param string $prefix for generating bank account number of a specific bank + * @param integer $length total length without country code and 2 check digits + * @return string + */ + protected static function iban($countryCode, $prefix = '', $length = null) + { + $countryCode = strtoupper($countryCode); + $format = !isset(static::$ibanFormats[$countryCode]) ? array() : static::$ibanFormats[$countryCode]; + if ($length === null) { + if ($format === null) { + $length = 24; + } else { + $length = 0; + foreach ($format as $part) { + list($class, $groupCount) = $part; + $length += $groupCount; + } + } + } + + $result = $prefix; + $length -= strlen($prefix); + $nextPart = array_shift($format); + if ($nextPart !== false) { + list($class, $groupCount) = $nextPart; + } else { + $class = 'n'; + $groupCount = 0; + } + $groupCount = $nextPart === false ? 0 : $nextPart[1]; + for ($i = 0; $i < $length; $i++) { + if ($nextPart !== false && $groupCount-- < 1) { + $nextPart = array_shift($format); + list($class, $groupCount) = $nextPart; + } + 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; + } + } + + $result = static::addBankCodeChecksum($result, $countryCode); + + $countryNumber = 100 * (ord($countryCode[0])-55) + (ord($countryCode[1])-55); + $tempResult = $result . $countryNumber . '00'; + // perform MOD97-10 checksum calculation + $checksum = (int) $tempResult[0]; + for ($i = 1, $size = strlen($tempResult); $i < $size; $i++) { + $checksum = (10 * $checksum + (int) $tempResult[$i]) % 97; + } + $checksum = 98 - $checksum; + if ($checksum < 10) { + $checksum = '0'.$checksum; + } + + return $countryCode . $checksum . $result; + } + + /** + * Calculates a checksum for the national bank and branch code part in the IBAN. + * + * @param string $iban randomly generated $iban + * @param string $countryCode ISO 3166-1 alpha-2 country code + * @return string IBAN with one character altered to a proper checksum + */ + protected static function addBankCodeChecksum($iban, $countryCode = '') + { + return $iban; + } + + /** + * Return the String of a SWIFT/BIC number + * + * @example 'RZTIAT22263' + * @link http://en.wikipedia.org/wiki/ISO_9362 + * @return string Swift/Bic number + */ + public static function swiftBicNumber() + { + return self::regexify("^([A-Z]){4}([A-Z]){2}([0-9A-Z]){2}([0-9A-Z]{3})?$"); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/Person.php new file mode 100644 index 0000000..bd7cd45 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/Person.php @@ -0,0 +1,126 @@ +generator->parse($format); + } + + /** + * @param string|null $gender 'male', 'female' or null for any + * @return string + * @example 'John' + */ + 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); + } + + /** + * @example 'Doe' + * @return string + */ + public function lastName() + { + return static::randomElement(static::$lastName); + } + + /** + * @example 'Mrs.' + * @param string|null $gender 'male', 'female' or null for any + * @return string + */ + 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)); + } + + /** + * @example 'Mr.' + */ + public static function titleMale() + { + return static::randomElement(static::$titleMale); + } + + /** + * @example 'Mrs.' + */ + public static function titleFemale() + { + return static::randomElement(static::$titleFemale); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/PhoneNumber.php new file mode 100644 index 0000000..65b24fc --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/PhoneNumber.php @@ -0,0 +1,16 @@ + 5) { + throw new \InvalidArgumentException('indexSize must be at most 5'); + } + + + $words = $this->getConsecutiveWords($indexSize); + $result = array(); + $resultLength = 0; + // take a random starting point + $next = static::randomKey($words); + while ($resultLength < $maxNbChars && isset($words[$next])) { + // fetch a random word to append + $word = static::randomElement($words[$next]); + + // calculate next index + $currentWords = static::explode($next); + $currentWords[] = $word; + array_shift($currentWords); + $next = static::implode($currentWords); + + // ensure text starts with an uppercase letter + if ($resultLength == 0 && !static::validStart($word)) { + continue; + } + + // append the element + $result[] = $word; + $resultLength += static::strlen($word) + static::$separatorLen; + } + + // remove the element that caused the text to overflow + array_pop($result); + + // build 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; + } + // cache look up words for performance + $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) + { + return preg_match('/^\p{Lu}/u', $word); + } + + protected static function appendEnd($text) + { + return $text.'.'; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/UserAgent.php b/vendor/fzaninotto/faker/src/Faker/Provider/UserAgent.php new file mode 100644 index 0000000..132b480 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/UserAgent.php @@ -0,0 +1,162 @@ +> 8) | (($tLo & 0xff000000) >> 24); + $tMi = (($tMi & 0x00ff) << 8) | (($tMi & 0xff00) >> 8); + $tHi = (($tHi & 0x00ff) << 8) | (($tHi & 0xff00) >> 8); + } + + // apply version number + $tHi &= 0x0fff; + $tHi |= (3 << 12); + + // cast to string + $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; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Address.php new file mode 100644 index 0000000..6f4f258 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Address.php @@ -0,0 +1,152 @@ +generator->parse($format)); + } + + /** + * @example 'wewebit.jo' + */ + public function domainName() + { + return static::randomElement(static::$lastNameAscii) . '.' . $this->tld(); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Person.php new file mode 100644 index 0000000..7fcadb3 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ar_JO/Person.php @@ -0,0 +1,108 @@ + 5) { + throw new \InvalidArgumentException('indexSize must be at most 5'); + } + + $words = $this->getConsecutiveWords($indexSize); + $result = array(); + $resultLength = 0; + // take a random starting point + $next = static::randomKey($words); + while ($resultLength < $maxNbChars && isset($words[$next])) { + // fetch a random word to append + $word = static::randomElement($words[$next]); + + // calculate next index + $currentWords = explode(' ', $next); + + $currentWords[] = $word; + array_shift($currentWords); + $next = implode(' ', $currentWords); + + if ($resultLength == 0 && !preg_match('/^\p{Arabic}/u', $word)) { + continue; + } + // append the element + $result[] = $word; + $resultLength += strlen($word) + 1; + } + + // remove the element that caused the text to overflow + array_pop($result); + + // build result + $result = implode(' ', $result); + + return $result.'.'; + } + + /** + * License: Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) + * + * Title: حي بن يقظان + * Author: ابن الطفيل + * Language: Arabic + * + * @see https://ar.wikisource.org/wiki/%D8%A7%D8%A8%D9%86_%D8%A7%D9%84%D8%B7%D9%81%D9%8A%D9%84_-_%D8%AD%D9%8A_%D8%A8%D9%86_%D9%8A%D9%82%D8%B8%D8%A7%D9%86 + * @var string + */ + protected static $baseText = <<<'EOT' +ذكر سلفنا الصالح - رضي الله عنهم - أن جزيرة من جزائر الهند التي تحت خط الاستواء، وهي الجزيرة التي يتولد بها الإنسان من غير أم ولا أب، وبها شجر يثمر نساء، وهي التي ذكر المسعودي أنها جزيرة الوقواق لان تلك الجزيرة اعدل بقاع الأرض هواء؛ أتممها لشروق النور الأعلى عليها استعدادً، وان كان ذلك خلاف ما يراه جمهور الفلاسفة وكبار الأطباء، فانهم يرون إن اعدل ما في المعمورة الإقليم الرابع، فان كانوا قالوا ذلك لأنه صح عندهم انه ليس على خط الاستواء عمارة لمانع من الموانع الأرضية، فلقولهم: أن الإقليم الرابع اعدل بقاع الأرض وجه، وان كانوا إنما أرادوا بذلك إن ما على خط الاستواء شديد الحرارة، كالذي يصرح به أكثرهم فهو خطأ يقوم البرهان على خلافه. + +وذلك أنه قد تبرهن في العلوم الطبيعية أنه لا سبب لتكون الحرارة إلا الحركة أو ملاقاة الأجسام الحارة والإضاءة؛ وتبين فيها أيضاً إن الشمس بذاتها غير حارة ولا متكيفة بشيء من هذه الكيفيات المزاجية؛ وقد تبين فيها أيضاً إن الأجسام التي تقبل الإضاءة أتم القبول، هي الأجسام الصقيلة غير الشفافة، ويليها في قبول ذلك الأجسام الكثيفة غير الصقيلة، فأما الأجسام الشفافة التي لاشيء فيها من الكثافة فلا تقبل الضوء بوجه. + +وهذا وحده مما برهنه الشيخ أبو علي خاصة، ولم يذكره من تقدمه، فإذا صحت هذه المقدمات، فاللازم عنها أن الشمس لا تسخن الأرض كما تسخن الأجسام الحارة أجسام أخر تماسها، لان الشمس في ذاتها غير حارة ولا الأرض أيضاً تسخن بالحركة لأنها ساكنة وعلى حالة واحدة في شروق الشمس عليها وفي وقت مغيبها عنها وأحوالها في التسخين والتبريد، ظاهرة الاختلاف للحس في هذين الوقتين. + +ولا الشمس أيضاً تسخن الهواء أولاً ثم تسخن بعد ذلك الأرض بتوسط سخونة الهواء، وكيف يكون ذلك ونحن نجد أن ما قرب من الهواء من الأرض في وقت الحر، أسخن كثيراً من الهواء الذي يبعد منه علواً؟ فبقي أن تسخين الشمس للأرض إنما هو على سبيل الإضاءة لا غير، فان الحرارة تتبع الضوء أبداً: حتى إن الضوء إذا افرط في المرأة المقعرة، أشعل ما حاذاها. + +وقد ثبت في علوم التعاليم بالبراهين القطعية، أن الشمس كروية الشكل، وأن الأرض كذلك، وأن الشمس أعظم من الأرض كثيراً، وأن الذي يستضيء من الشمس أبداً هو أعظم من نصفها، وأن هذا النصف المضيء من الأرض في كل وقت أشد ما يكون الضوء في وسطه، لأنه أبعد المواضع من المظلمة، ولأنه يقابل من الشمس أجزاءاً أكثر، وما قرب من المحيط كان أقل ضوءاً حتى ينتهي إلى الظلمة عند محيط الدائرة الذي ما أضاء موقعه من الأرض قط، وإنما يكون الموضع وسط دائرة الضياء إذا كانت الشمس على سمت رؤوس الساكنين فيه، وحينئذ تكون الحرارة في ذلك الموضع أشد ما يكون فان كان الموضع مما تبعد الشمس عن مسامتة رؤوس أهله، كان شديد البرودة جداً، وان كان مما تدوم فيه المسامتة كان شديد الحرارة، وقد ثبت في علم الهيئة أن بقاع الأرض التي على خط الاستواء لا تسامت الشمس رؤوس أهلها سوى مرتين في العام: عند حلولها برأس الحمل؛ وعند حلولها برأس الميزان. + +وهي في سائر العام ستة أشهر جنوباً منهم، وستة أشهر شمالاً منهم: فليس عندهم حر مفرط، ولا برد مفرط. وأحوالهم بسبب ذلك متشابهة. + +وهذا القول يحتاج إلى بيان أكثر من هذا، لا يليق بما نحن بسبيله؛ وإنما نبهناك عليه، لأنه من الأمور التي تشهد بصحة ما ذكر من تجويز تولد الإنسان بتلك البقعة من غير أم ولا أب. + +فمنهم من بت الحكم وجزم القضية بأن حي بن يقظان من جملة من تكون في تلك البقعة من غير أم ولا أب، ومنهم من أنكر ذلك وروى من أمره خبراً نقصه عليك، فقال: انه كان بازاء تلك الجزيرة، جزيرة عظيمة متسعة الأكتاف، كثيرة الفوائد، عامرة بالناس، يملكها رجل منهم شديد الأنفة والغيرة، وكانت له أخت ذات جمال وحسن باهر فعضلها ومنعها الأزواج إذا لم يجد لها كفواً. وكان له قريب يسمى يقظان فتزوجها سراً على وجه جائز في مذهبهم المشهور في زمنهم. + +ثم إنها حملت منه ووضعت طفلاً. فلما خافت أن يفتضح أمرها وينكشف سرها، وضعته في تابوت أحكمت زمه بعد أن أروته من الرضاع؛ وخرجت به في أول الليل في جملة من خدمها وثقاتها إلى ساحل البحر، وقلبها يحترق صبابةً به، وخوفاً عليه، ثم إنها ودعته وقالت: "اللهم انك خلقت هذا الطفل ولم يكن شيئاً مذكوراً، ورزقته في ظلمات الأحشاء، وتكفلت به حتى تم واستوى. وأنا قد سلمته إلى لطفك، ورجوت له فضلك، خوفاً من هذا الملك الغشوم الجبار العنيد. + +فكن له، ولا تسلمه، يا أرحم الراحمين" ثم قذفت به في اليم. فصادف ذلك جري الماء بقوة المد، فاحتمله من ليلته إلى ساحل الجزيرة الأخرى المتقدم ذكرها. وكان المد يصل في ذلك الوقت إلى موضع لا يصل إليه بعد علم. فأدخله الماء بقوته إلى أجمة ملتفة الشجر عذبة التربة، مستورة عن الرياح والمطر، محجوبة عن الشمس تزاور عنها إذا طلعت، وتميل إذا غربت. ثم أخذ الماء في الجزر. + +وبقي التابوت في ذلك الموضع، وعلت الرمال بهبوب الرياح، وتراكمت بعد ذلك حتى سدت مدخل الماء إلى تلك الأجمة. فكان المد لا ينتهي إليها، وكانت مسامير التابوت قد فلقت، وألواحه قد اضطربت عند رمي الماء في تلك الأجمة. فلما أشتد الجوع بذلك الطفل، بكى واستغاث وعالج الحركة، فوقع صوته في أذن ظبية فقدت طلاها، خرج من كناسه فحمله العقاب، فلما سمعت الصوت ظنته ولدها. + +فتتبعت الصوت وهي تتخيل طلاها حتى وصلت إلى التابوت، ففحصت عنه بأظلافها وهو ينوء ويئن من داخله، حتى طار عن التابوت لوح من أعلاه. فحنت الظبية وحنت عليه ورئفت به، وألقمه حلمتها وأروته لبناً سائغاً. ومازالت تتعهده وتربيه وتدفع عنه الأذى. هذا ما كان من ابتداء أمره عند من ينكره التولد. ونحن نصف هنا كيف تربى وكيف أنتقل في أحواله حتى يبلغ المبلغ العظيم. وأما الذين زعموا أنه تولد من الأرض فانهم قالوا إن بطناً من أرض تلك الجزيرة تخمرت فيه طينه على مر السنين والأعوام، حتى امتزج فيها الحار بالبارد، والرطب باليابس، امتزاج تكافؤ وتعادل في القوى. وكانت هذه الطينة المتخمرة كبيرة جداً وكان بعضها يفضل بعضاً في اعتدال المزاج والتهيؤ لتكون الأمشاج. + +وكان الوسط منها أعدل ما فيها وأتمه مشابهة بمزاج الإنسان: فتمخضت تلك الطينة، وحدث فيها شبه نفاخات الغليان لشدة لزوجتها: وحدث في الوسط منها لزوجة ونفاخة صغيرة جداً، منقسمة بقسمين، بينها حجاب رقيق، ممتلئة بجسم لطيف هوائي في غاية من الاعتدال اللائق به، فتعلق به عند ذلك الروح الذي هو من أمر الله تعالى وتشبث به تشبثاً يعسر انفصاله عنه عند الحس وعند العقل؛ إذ قد تبين أن هذا الروح دائم الفيضان من عند الله عز وجل، وأنه بمنزلة نور الشمس الذي هو دائم الفيضان على العالم. + +فمن الأجسام ما لا يستضيء به، وهو الهواء الشفاف جداً؛ ومنها ما يستضيء به بعض الاستضاءة، وهي الأجسام الكثيفة غير الصقيلة وهذه تختلف في قبول الضياء، وتختلف بحسب ذلك ألوانها، ومنها ما يستضيء به غاية الاستضاءة وهي الأجسام الصقيلة كالمرأة ونحوها. + +فإذا كانت هذه المرأة مقعرة على شكل مخصوص، حدث فيها النار لإفراط الضياء. الذي هو الروح، الذي هو من أمر الله تعالى، فياض أبداً على جميع الموجودات؛ فمنها ما لا يظهر أثره فيه اعدم الأستعداد، وهي الجمادات التي لا حياة لها، وهذه بمنزلة الهواء في المثال المتقدم، ومنها ما يظهر أثره فيه، وهي أنواع النبات بحسب استعداداتها وهذه بمنزلة الأجسام الكثيفة في المثال المتقدم؛ ومنها ما يظهر أثره فيه ظهوراً كثيراً، وهي الأجسام الصقيلة في المثال المتقدم. + +ومن هذه الأجسام الصقيلة ما يزيد على شدة قبوله لضياء الشمس أنه يحكي صورة الشمس، ومثالها. وكذلك أيضاً من الحيوان ما يزيد على شدة قبوله للروح أنه يحكي الروح ويتصور بصورته وهو الإنسان خاصة. + +واليه الإشارة بقوله صلى الله عليه وسلم: "إن الله خلق أدم على صورته". فان قويت في هذه الصورة حتى تتلاشى جميع الصور في حقها، وتبقى هي وحدها، وتحرق سبحات نورها كل ما أدركته، كانت حينئذ بمنزلة المرأة المنعكسة على نفسها المحرقة لسوها وهذا لا يكون إلا للأنبياء صلوات الله عليهم أجمعين. وهذا كله مبين في مواضعه اللائقة به، فليرجع إلى تمام ما حكوه من وصف ذلك التخلق. + +قالوا: فلما تعلق هذا الروح بتلك القرارة، خضعت له جميع القوى وسجدت له وسخرت بأمر الله تعالى في كمالها، فتكون بازاء تلك القرارة نفاخة أخرى منقسمة إلى ثلاث قرارت بينهما حجب لطيفة، ومسالك نافذة، وامتلأت بمثل ذلك الهوائي الذي امتلأت منه القرارة الأولى؛ إلا أنه ألطف منه. وفي هذه البطون الثلاثة المنقسمة من واحد، طائفة من تلك القوى التي خضعت له وتوكلت بحراستها والقيام عليها، وإنهاء ما يطرأ فيها من دقيق الأشياء وجليلها إلى الروح الأول المتعلق بالقرارة الأولى. + +وتكون بازاء هذه القرارة من الجهة المقابلة للقراءة الثانية، نفاخة ثالثة مملوءة جسماً هوائياً، إلا أنه أغلظ من الأولين وسكن في هذه القرارة فريق من تلك القوى الخاضعة، وتوكلت بحفظها و القيام عليها؛ فكانت هذه القرارة الأولى والثانية والثالثة، أول ما تخلق من تلك الطينة المتحمرة على الترتيب الذي ذكرناه. واحتاج بعضها إلى بعض: فالأولى منها حاجتها إلى الآخرين، حاجة استخدام وتسخير. + +والأخريان حاجتهما إلى الأولى حاجة المرؤوس إلى الرئيس، والمدبر إلى المدبر؛ وكلاهما لما يتخلق بعدهما من الأعضاء رئيس لا مرؤوس. وأحدهما، وهو الثاني، أتمم رئاسة من الثالث فالأول منهما لما تعلق به الروح، واشتعلت حرارته تشكل بشكل النار لصنوبري وتشكل أيضاً الجسم الغليظ المحدق به على شكله، وتكون لحماً صلباً، وصار عليه غلاف صفيق يحفظه وسمي العضو كله قلباً واحتاج لما يتبع الحرارة من التحليل وافناء الرطوبات إلى شيء يمده ويغذوه، ويخلف ما تحلل منه على الدوام، وإلا لم يطل بقاؤه، واحتاج أيضاً إلى تحسس بما يلائمه فيجذبه، وبما يخالفه فيدفعه. فتكفل له العضو الواحد بما فيه من القوى التي أصلها منه بحاجته الواحدة، وتكفل له العضو الآخر بحاجته الأخرى. + +وكان المتكفل بالحس هو الدماغو المتكفل بالغذاء هو الكبد؛ واحتاج كل واحد من هذين إليه في أن يمدها بحرارته، وبالقوى المخصوصة بهما التي أصلها منه ، فانتسجت بينهما لذلك كله مسالك وطرق: بعضها أوسع من بعض بحسب ما تدعواليه الضرورة، فكانت الشرايين و العروق. وصفه الطبيعيون في خلقة الجنين في الرحم، لم يغادروا من ذلك شيئاً، إلى أن كمل خلقه، وتمت أعضاؤه، وحصل في حد خروج الجنين من البطن، واستعانوا في وصف كمال ذلك بتلك الطينة الكبيرة المتخمرة، وأنها كانت قد تهيأت لان يتخلق منها كل ما يحتاج إليه في خلق الإنسان من الأغشية المجللة لجملة بدنه وغيرها فلما كمل انشقت عنه تلك الأغشية، بشبه المخاض، وتصدع باقي الطينة إذ كان قد لحقه الجفاف. + +ثم استغاث ذلك الطفل عند فناء مادة غذائه واشتداد جوعه، فلبته ظبية فقدت طلاها. ثم استوى عبد ما وصفه هؤلاء بعد هذا الموضع، وما وصفه الطائفة الأولى في معنى التربية؛ فقالوا جميعاً: إن الظبية التي تكفلت به وافقت خصباً ومرعى أثيثاً، فكثر لحمها وكثر لبنها، حتى قام بغذاء ذلك الطفل أحسن قيام. وكانت معه لا تبعد عنه إلا لضرورة الرعي. وألف الطفل تلك الظبية حتى كان بحيث إذا هي أبطأت عنه اشتد بكاؤه فطارت إليه. + +ولم يكن بتلك الجزيرة شيء من السباع العادية، فتربى الطفل ونما واغتذى بلبن تلك الظبية إلى أن تم له حولان، وتدرج في المشي وأثغر فكان يتبع تلك الظبية، وكانت هي ترفق به و ترحمه وتحمله إلى مواضع فيها شجر مثمر فكانت تطعمه ما تساقط من ثمراتها الحلوة النضيجة؛ وما كان منها صلب القشر كسرته له بطواحنها؛ ومتى عاد إلى اللبن أروته، ومتى ظمئ إلى الماء أرودته، متى ضحا ظللته؛ ومتى خصر أدفأته. + +وإذا جن الليل صرفته إلى مكان الأول وجللته بنفسها وبريش كان هناك؛ مما ملئ به التابوت أولاً في وقت وضع الطفل فيه. وكان في غدوهما ورواحهما قد ألفهما ربرب يسرح ويبيت معهما حيث مبيتهما. فما زال الطفل مع الظباء على تلك الحال: يحكي نغمتها بصوته حتى لا يكاد يفرق بينهما؛ وكذلك كان يحكي جميع ما يسمعه من أصوات الطير وأنواع سائر الحيوان محاكاة شديدة لقوة انفعاله لما يريده ما كانت محاكاته لأصوات الظباء في الاستصراخ والاستئلاف والاستدعاء والاستدفاع. إذ للحيوانات في هذه الأحوال المختلفة أصوات مختلفة فألفته الوحوش وألفها؛ ولم تنكره ولا أنكرها. + +فلما ثبت في نفسه أمثلة الأشياء بعد مغيبها عن مشاهدته، حدث له نزوغ إلى بعضها؛ وكراهية لبعض. وكان في ذلك كله ينظر إلى جميع الحيوانات فيراها كاسية بالاوبار و الأشعار و أنواع الريش، وكان يرى ما لها من العدو وقوة البطش، وما لها من الأسلحة المعدة لمدافعة من ينازعها، مثل القرون و الأنياب و الحوافر و الصياصي و المخالب. ثم يرجع إلى نفسه، فيرى ما به من العري وعدم السلاح، وضعف العدو، وقلة البطش، عندما كانت تنازعه الوحوش أكل الثمرات، وتستبد بها دونه، وتغلبه عليها، فلا يستطيع المدافعة عن نفسه، ولا الفرار عن شيء منها. وكان يرى أترابه من أولاد الظباء، قد تبتت لها قرون، بعد أن لم تكن، وصارت قوية بعد ضعفها في العدو. + +ولم ير لنفسه شيئاً من ذلك فكان يفكر في ذلك ولا يدري ما سببه. وكان ينظر إلى ذوي العاهات والخلق الناقص فلا يجد لنفسه شبيهاً فيهم. وكان أيضاً ينظر إلى مخارج الفضول من سائر الحيوانات، فيراها مستورة: أما مخرج أغلظ الفضلتين فبالاذناب، وأما مخرج وأما مخرج أرقهما فبالاوبار وما أشبههما. ولأنها كانت أيضاً اخفى قضباناً منه. فكان ذلك ما يكربه ويسؤه. + +فلما طال همه في ذلك كله، وهو قد قارب سبعة اعوام، ويئس من أن يكمل له ما قد أضر به نقصه، اتخذ من أوراق الشجر العريضة شيئاً جعل بعضه خلفه و بعضه قدمه، وعمل من الخوض والحلفاء شبه حزام على وسطه، علق به تلك الأوراق فلم يلبث إلا يسيراً حتى ذوى ذلك الورق وجف وتساقط. فما زال يتخذ غيره ويخصف بعضه ببعض طاقات مضاعفة، وربما كان ذلك أطول لبقائه إلا انه على كل حال قصير المدة. + +واتخذ من أغصان الشجر عصياً وسوى أطرافها وعدل متنها. وكان بها على الوحوش المنازعة له، فيحمل على الضعيف منها، ويقاوم القوي منها، فنبل بذلك قدره عند نفسه بعض نباله، ورأى أن ليده فضلاً كثيراً على أيديها: إذ أمكن له بها ستر عورته واتخاذ العصي التي يدافع بها عن حوزته، ما استغنى به عما أراده من الذنب والعذاب الطبيعي. وفي خلال ذلك ترعرع واربى على السبع سنين، وطال به العناء في تجديد الأوراق التي كان يستتر بها. + +فكانت نفسه عند ذلك تنازعه إلى اتخاذ ذنب من ذنوب الوحوش الميتة ليعلقه على نفسه، إلا أنه كان يرى أحياء الوحوش تتحامى ميتها وتفر عنه فلا يتأتى له الأقدام على ذلك الفعل، إلى أن صادف في الأيام نسراً ميتاً فهدي إلى نيل أمله منه، واغتنم الفرصة في، إذ لم ير للوحوش عنه نفرةً فأقدم عليه، وقطع جناحيه وذنبه صحاحاً كما هي، وفتح ريشها وسواها، وسلخ عنه سائر جلده، وفصله على قطعتين: ربط إحداهما على ظهره، وأخرى على سرته وما تحتها، وعلق الذنب من خلفه، وعلق الجناحين على عضديه، فأكسبه ذلك ستراً ودفئاً ومهابة في نفوس جميع الوحوش، حتى كانت لا تنازعه ولا تعارضه. فصار لايدنو إليه شيء منها سوى الظبية التي كانت أرضعته وربته: فانها لم تفارقه ولا فارقها، إلى أن اسنت وضعغت، فكان يرتاد بها المراعي الخصبة ويجتني لها الثمرات الحلوة، ويطعمها. + +ومازل الهزل والضعف يستولي عليها ويتوالى، إلى أن أدركها الموت، فسكنت حركاتها بالجملة، وتعطلت جميع أفعالها. فلما رأها الصبي على تلك الحالة، جزع جزعاً شديداً، وكادت نفسه تفيض أسفاً عليها. فكان يناديها بالصوت الذي كانت عادتها أن تجيبه عند سماعه، ويصيح بأشد ما يقدر عليه، فلا لها عند ذلك حركة ولا تغييراً. فكان ينظر إلى أذنيها والى عينيها فلا يرى بها آفة ظاهرة، وكذلك كان ينظر إلى جميع أعضائها فلا يرى بشيء منها آفة. + +فكان يطمع إن يعثر على موضع الآفة فيزيلها عنها، فترجع إلى ما كانت عليه فلم ياتت له شيء من ذلك ولا استطاعة. وكان الذي أرشده لهذا الرأي ما كان قد اعتبره في نفسه قبل ذلك: لانه كان يرى انه إذا غمض عينيه أو حجبهما بشيء لا يبصر حتى نزول ذلك العائق، وكذلك كان يرى انه اذا ادخل إصبعه في أذنيه وسدها لا يسمع شيئاً حتى يزول ذلك العارض، وإذا امسك أنفه بيده لا يشم شيئاً من الروائح حتى يفتح أنفه. فاعتقد من اجل ذلك إن جميع ماله من الادراكات و الأفعال قد تكون لها عوائق تعوقها، فإذا أزيلت العوائق عادت الأفعال. + +فلما نظر إلى جميع أعضاء الظاهرة ولم ير فيها آفة ظاهرة - وكان يرى مع ذلك العطلة قد اشتملها ولم يختص بها عضو دون عضو - وقع في خاطرة أن الآفة التي نزلت بها، إنما هي العضو غائب عن العيان مستكن في باطن الجسد، وان ذلك العضو لا يغني عنه في فعله شيء من هذه الأعضاء الظاهرة. فلما نزلت به الآفة عمت المضرة، وشملت العطلة، وطمع لو أنه عثر على ذلك العضو وأزال عنه ما يزال به لاستقامت أحواله وفاض على سائر البدن نفعه، وعادت الأفعال إلى ما كانت عليه. + +وكان قد شاهد قبل ذلك في الأشباح الميتة من الوحوش وسواها أن جميع أعضائها مصمتة لا تجويف فيها إلا القحف، والصدر، والبطن. فوقع في نفسه أن العضو الذي بتلك الصفة لن يعدو أحد هذه المواضع الثلاثة، وكان يغلب على ظنه غلبة قوية أنه إنما هو في الموضع المتوسط من هذه المواضع الثلاثة، إذ استقر في نفسه أن جميع الأعضاء محتاجة إليه، وأن الواجب بحسب ذلك أن يكون مسكنه في الوسط. + +وكان أيضاً إذا رجع إلى ذاته، شعر بمثل هذا العضو في صدره لانه كان يعترض سائراً اعضائه كاليد، والرجل، والأذن، والانف، والعين، ويقدر مفارقتها، فيتاى له أنه كان يستغني عنها، وكان يقدر في رأسه مثل ذلك ويظن أنه يستغني عنه، فإذا فكر في الشيء الذي يجده في صدره، لم يتأت له الاستغناء عنه طرفة عين. + +وكذلك كان عند محاربته للوحوش أكثر ما كان يتقي من صياصيهم على صدره، لشعوره بالشيء الذي فيه. فلما جزم الحكم بان العضو الذي نزلت به الآفة إنما هو في صدورها، اجمع على البحث عليه والتنقير عنه، لعله يظفر به، ويرى آفته فيزيلها ثم انه خاف أنه يكون نفس فعله هذا أعظم من الآفة التي نزلت بها أولاً فيكون سعيه عليها. ثم أنه تفكر: هل رأى من الوحوش وسواها، من ضار في مثل تلك الحال، ثم عاد إلى مثل حاله الأول؟ فلم يجد شيئاً! فحصل له من ذلك، اليأس من رجوعها إلى حالها الأولى إن هو تركها، وبقي له بعض الرجاء في رجوعها إلى تلك الحال إن هو وجد ذلك العضو وأزال الآفة عنه. فعزم على شق صدرها وتفتيش ما فيه، فاتخذ من كسور الأحجار الصلدة وشقوق القصب اليابسة، أشباه السكاكين، وشق بها بين أضلاعها حتى قطع اللحم الذي بين الأضلاع، وأفضى إلى الحجاب المستبطن للأضلاع فراه قوياً، فقوي ظنه مثل ذلك الحجاب لا يكون إلا لمثل ذلك العضو وطمع بأنه إذا تجاوزه ألفى مطلوبه فحاول شقه، فصعب عليه، لعدم الآلات، ولأنها لم تكن إلا من الحجارة والقصب، فاستجدها ثانية واستحدها وتلطف في خرق الحجاب حتى انخرق له، فأفضى إلى الرئة فظن أنها مطلوبه، فما زال يقلبها ويطلب موضع الآفة بها. + +وكان أولاً نصفها الذي هو في الجانب الواحد. فلما راها مائلة إلى جهة واحدة، وكان قد اعتقد أن ذلك العضو لا يكون إلا في الوسط في عرض البدن، كما في الوسط في طوله. فمازال يفتش في وسط الصدر حتى ألفى القلب وهو مجلل بغشاء في غاية القوة مربوط بعلائق في غاية الوثاقة، والرثة مطيفة به من الجهة التي بدأ بالشق منها، فقال في نفسه: إن كان لهذا العضو من الجهة الأخرى مثل ما له من الجهة فهو في حقيقة الوسط، ولا محالة أنه مطلوبي. لا سيما مع ما أرى له حسن الوضع، وجمال الشكل، وقلة التشتت، وقوة اللحم، وأنه محجوب بمثل هذا الحجاب الذي لم أر مثله لشيء من الأعضاء. فبحث عن الجانب الآخر من الصدر، فوجد فيه الحجاب المستبطن للأضلاع، ووجد الرئة كمثل ما وجد من هذه الجهة. + +فحكم بان ذلك العضو هو مطلوبه، فحاول هتك حجابه، وشق شغافه، فبكد واستكراه ما، قدر على ذلك، بعد استفراغ مجهوده. وجرد القلب فراه مصمتاً من كل جهة، فنظر هل يرى فيه آفة ظاهرة؟ فلم ير فيه شيئاً! فشد على يده، فتبين له أن فيه تجويفاً، فقال: لعل مطلوبي الأقصى إنما هو في داخل هذا العضو، وأنا حتى الآن لم أصل إليه. فشق عليه، فألقى فيه تجويفين اثنين احدهما من الجهة اليمنى والآخر من الجهة اليسرى، والذي من الجهة اليمنى مملوء بعقد منعقد، والذي من الجهة اليسرى خال لا شيء به. + +فقال: لن يعدو مطلوبي أن يكون مسكنه أحد هذين البيتين. ثم قال: أما هذا البيت الأيمن، فلا أرى فيه إلا هذا الدم المنعقد. ولا شك أنه لم ينعقد حتى صار الجسد كله إلى هذا الحال - إذ كان قد شاهد الدماء متى سالت وخرجت انعقدت وجمدت ولم يكن هذا إلا دماً كسائر الدماء - وأنا أرى أن هذا الدم موجود في سائر الأعضاء لا يختص به عضو دون أخر، وأنا ليس مطلوبي شيئاً بهذه الصفة إنما مطلوبي الشيء الذي يختص به هذا الموضع الذي أجدني لا أستغني عنه طرفة العين، واليه كان انبعاثي من أول. واما هذا الدم فكم مرة جرحتني الوحوش في المحاربة فسال مني كثير منه فما ضرني ذلك ولا افقدني شيئاً من أفعالي، فهذا بيت ليس فيه مطلوبي. وأما هذا البيت الأيسر فأراه خالياً لاشيء فيه، وما أرى ذلك لباطل، فاني رأيت كل عضو من الأعضاء إنما لفعل يختص به، فكيف يكون هذا البيت على ما شاهدت من شرفه باطلاً؟ ما أرى إلا أن مطلوبي كان فيه! فارتحل عنه وأخلاه. وعند ذلك، طرأ على هذا الجسد من العطلة ما طرأ، ففقد الإدراك وعدم الحراك. فلما رأى أن الساكن في ذلك البيت قد ارتحل قبل انهدامه وتركه وهو بحاله، تحقق أنه أحرى أن لا يعود إليه بعد أن حدث فيه من الخراب والتخريق ما حدث. فصار عنده الجسد كله خسيساً لا قدر له بالإضافة إلى ذلك الشيء الذي اعتقد في نفسه أنه يسكنه مدة ويرحل عنه بعد ذلك. + +فاقتصر على الفكرة في ذلك الشيء ما هو؟ وكيف هو؟ وما الذي ربطه بهذا الجسد؟ والى اين صار؟ ومن أي الأبواب خرج عند خروجه من الجسد؟ وما السبب الذي أزعجه إن كان خرج كارهاً؟ وما السبب الذي كره إليه الجسد، حتى فارقه إن كان خرج مختاراً؟ وتشتت فكره في ذلك كله، وسلا عن الجسد وطرحه، وعلم أن أمه التي عطفت عليه وأرضعته، إنما كانت ذلك الشيء المرتحل، وعنه كانت تصدر تلك الأفعال كلها، لا هذا الجسد العاطل وأن هذا الجسد بجملته، إنما هو كالآلة وبمنزلة العصي التي اتخذها هو لقتال الوحوش. فانتقلت علاقته عن الجسد إلى صاحب الجسد ومحركه، ولم يبق له شوق إلا إليه. وفي خلال ذلك نتن ذلك الجسد، وقامت منه روائح كريهة، فزادت نفرته عنه، وود أن لا يراه ثم انه سنح لنظره غرابان يقتتلان حتى صرع أحدهما الآخر ميتاً. ثم جعل الحي يبحث في الأرض حتى حفر حفرة فوارى فيها ذلك الميت بالتراب فقال في نفسه: ما أحسن ما صنع هذا الغراب في مواراة جيفة صاحبه وان كان قد أساء في قتله اياه! وأنا كنت أحق بالاهتداء إلى هذا الفعل بآمي! فحفر حفرة وألقى فيها جسد أمه، وحثا عليها التراب. + +وبقي يتفكر في ذلك الشيء المصرف للجسد لا يدري ما هو! غير أنه كان ينظر إلى أشخاص الظباء كلها، فيراها على شكل أمه، وعلى صورتها فكان يغلب على ظنه، أن كل واحد منها إنما يحركه ويصرفه شيء هو مثل الشيء الذي كان يحرك أمه ويصرفها، فكان يألف الظباء ويحن إليها لمكان ذلك الشبه. وبقي على ذلك برهة من الزمن، يتصفح أنواع الحيوان والنبات ويطوف بساحل تلك الجزيرة، ويتطلب هل يرى أو يجد لنفسه شبيهاً حسبما يرى لكل واحد من أشخاص الحيوان والنبات أشباهاً كثيرة، فلا يجد شيئاً من ذلك. وكان يرى البحر قد أحدق بالجزيرة من كل جهة، فيعتقد أنه ليس في الوجود أرض سوى جزيرته تلك. + +واتفق في بعض الاحيان أن انقدحت نار في أجمة قلخ على سبيل المحاكة. فلما بصر بها رأى منظراً هاله، وخلقاً لم يعهده قبل، فوقف يتعجب منها ملياً، ومازال يدنو منها شيئاً فشيئاً، فرأى ما للنار من الضوء الثاقب والفعل الغالب حتى لا تعلق بشيء إلا أتت عليه وأحالته إلى نفسها، فحمله، العجب بها، وبما ركب الله تعالى في طباعه من الجراءة و القوة، على أن يده إليها، وأراد أن يأخذ منها شيئاً فلما باشرها أحرقت يده فلم يستطع القبض عليها فاهتدى إلى أن يأخذ قبساً لم تستول النار على جميعه، فأخذ بطرفه السليم والنار في طرفه الآخر، فتاتي له ذلك وحمله إلى موضعه الذي كان يأوي إليه - وكان قد خلا في جحر استحسنه للسكنى قبل ذلك. ثم مازال يمد تلك النار بالحشيش والحطب الجزل، ويتعهدهاً ليلاً ونهاراً استحساناً منه وتعجباً منها. + +وكان يزيد انسه بها ليلاً، لأنها كانت تقوم له مقام الشمس في الضياء و الدفء، فعظم بها ولوعه، واعتقد أنها أفضل الأشياء التي لديه: وكان دائماً يراها تتحرك إلى جهة فوق وتطلب العلو، فغلب على ظنه أنها من جملة الجواهر السماوية التي كان يشاهدها. وكان يختبر قوتها في جميع الأشياء بأن يلقيها فيها، فيراها مستولية عليه أما بسرعة واما ببطء بحسب قوة استعداد الجسم الذي كان يلقيه للاحتراق أو ضعفه. وكان من جملة ما القى فيها على سبيل الاختبار لقوتها، شيء من أصناف الحيوانات البحرية - كان قد ألقاه البحر إلى ساحله - فلما أنضجت ذلك الحيوان وسطع قتاره تحركت شهوته إليه، فأكل منه شيئاً فاستطابه، فاعتاد بذلك أكل اللحم، فصرف الحيلة في صيد البر والبحر، حتى مهر في ذلك. وزادت محبته للنار، إذ تأتي له بها من وجوه الاغتذاء الطيب شيء لم يتأت له قبل ذلك. + +فلما اشتد شغفه بها لما رأى من أحسن آثارها وقوة اقتدارها، وقع في نفسه أن الشيء الذي ارتحل من قلب أمه الظبية التي أنشأته، كان من جوهر هذا الوجود أو من شيء يجانسه، وأكد ذلك في ظنه، ما كان يراه من حرارة الحيوان طول مدة حياته، وبرودته من بعد موته، وكل هذا دائم لا يختل، وما كان يجده في نفسه من شدة الحرارة عند صدره، بازاء الموضع الذي كان قد شق عليه من الظبية، فوقع في نفسه أنه لو أخذ حيواناً حياً وشق قلبه ونظر إلى ذلك التجويف الذي صادفه خالياً عندما شق عليه في أمه الظبية، لرأه في الحيوان الحي وهو مملوء بذلك الشيء الساكن فيه وتحقق هل هو من جوهر النار؟ وهل فيه شيء من الضوء والحرارة، آم لا؟ فعمد إلى بعد الوحوش واستوثق منه كتافاً وشقه على الصفة التي شق بها الظبية حتى وصل القلب. فقصد أولاً إلى الجهة اليسرى منه وشقها، فرأى ذلك الفراغ مملوءاً بهواء بخاري، يشبه الضباب الابيض، فأدخل إصبعه فيه، فوجده من الحرارة في حد كاد يحرقه، ومات ذلك الحيوان على الفور. + +فصح عنده أن ذلك البخار الحار هو الذي كان يحرك هذا الحيوان، وأن في كل شخص من أشخاص الحيوانات مثل ذلك، ومتى انفصل عن الحيوان مات. ثم تحركت في نفسه الشهوة للبحث عن سائر أعضاء الحيوان وترتيبها وأوضاعها وكميتها وكيفية ارتباط بعضها ببعض، وكيف تستمد من هذا البخار الحار حتى تستمر لها الحياة به، وكيف بقاء هذا البخار المدة التي يبقى، ومن أين يستمد، وكيف لا تنفذ حرارته؟ فتتبع ذلك كله بتشريح الحيوانات الأحياء و الاموات، ولم يزل ينعم النظر فيها ويجيد الفكرة، حتى بلغ في ذلك كله مبلغ كبار الطبيعيين، فتبين له أن كل شخص من أشخاص الحيوان، وان كان كثيراً بأعضائه وتفنن حواسه وحركاته فانه واحد بذلك الروح الذي مبدؤه من قرار واحد، وانقسامه وانقسامه في سائر الأعضاء منبعث منه. وأن جميع الأعضاء إنما هي خادمة له، أو مؤدية عنه، وأن منزلة ذلك الروح في تصريف الجسد، كمنزلة من يحارب الأعداء بالسلاح التام، ويصيد جميع صيد البر والبحر، فيمد لكل جنس آلة يصيده بها والتي يحارب بها تنقسم: إلى ما يدفع به نكيلة غيره، والى ما ينكي بها غيره. + +وكذلك آلات الصيد تنقسم: إلى ما يصلح لحيوان البحر، والى ما يصلح لحيوان البر، وكذلك الأشياء التي يشرح بها تنقسم: إلى ما يصلح للشق، والى ما يصلح للكسر، والى ما يصلح للثقب، والبدن الواحد، وهو يصرف ذلك أنحاء من التصريف بحسب ما تصلح له كل آلة، وبحسب الغايات التي تلتمس بذلك التصرف. كذلك؛ ذلك الروح الحيواني واحد، وإذا عمل بالة العين كان فعله أبصاراً، وإذا عمل بآلة الآذن كان فعله سمعاً، وإذا عمل بآلة الآنف كان فعله شماً، وإذا عمل بآلة اللسان كان فعله ذوقاً، وإذا عمل بالجلد واللحم كان فعله لمساً، وإذا عمل بالعضد كان فعله حركه، وإذا عمل بالكبد كان فعله غذاء واغتذاء. + +ولكل واحد من هذه، أعضاء تخدمه. ولا يتم لشيء من هذه فعل إلا بما يصل إليها من ذلك الروح، على الطريق التي تسمى عصباً. ومتى انقطعت تلك الطرق أو انسدت، تعطل فعل ذلك العضو. وهذه الأعصاب إنما تستمد الروح من بطون الدماغ يستمد الروح من القلب، والدماغ فيه أرواح كثير، لانه موضع تتوزع فيه أقسام كثيرة: فآي عضو عدم هذا الروح بسبب من الأسباب تعطل فعله وصار بمنزلة الآلة المطرحة، التي يصرفها الفاعل ولا ينتفع بها. فان خرج هذا الروح بجملته عن الجسد، أو فني، أو تحلل بوجه من الوجوه، تعطل الجسد كله، وصار إلى حالة الموت، فانتهى به إلى هذا من منشئه، وذلك أحد وعشرون عاماً. + +وفي خلال هذه المدة المذكورة تفنن في وجوه حيله، واكتسى بجلود الحيوانات التي كان يشرحها، واحتذى بها، واتخذ الخيوط من الأشعار ولحا قصب الخطمية والخباري والقنب، وكل نبات ذي خيط. وكان أصل اهتدائه إلى ذلك، أنه أخذ من الحلفاء وعمل خطاطيف من الشوك القوي والقصب المحدد على الحجارة. + +واهتدى إلى البناء بما رأى من فعل الخطاطيف فاتخذ مخزناً وبيتاً لفضلة غذائه، وحصن عليه بباب من القصب المربوط بعضه إلى بعض، لئلا يصل إليه شيء من الحيوانات عند مغيبه عن تلك الجهة في بعض شؤونه. واستألف جوانح الطير ليستعين بها في الصيد، واتخذ الدواجن ببيضها وفراخها، واتخذ من الصياصي البقر الوحشية شبه الاسنة، وركبها في القصب القوي، وفي عصي الزان وغيرها، واستعان في ذلك بالنار وبحروف الحجارة، حتى صارت شبه الرماح، واتخذ ترسه من جلود مضاعة: كل ذلك لما رأى من عدمه السلاح الطبيعي. ولما رأى أن يده تفي له بكل ما فاته من ذلك، وكان لا يقاومه شيء من الحيوانات على اختلاف أنواعها، إلا أنها كانت عنه فتعجزه هرباً، فكر في وجه الحيلة في ذلك، فلم ير شيئاً أنجع له من أن يتالف بعض الحيوانات الشديدة العدو، ويحسن إليها بأعداد الغذاء الذي يصلح لها، حتى يتأتى له الركوب عليها ومطاردة سائر الأصناف بها. + +وكان بتلك الجزيرة خيل البرية وحمر وحشية، فاتخذ منها ما يصلح له، وراضها حتى كمل بها غرضه، وعمل عليها من الشرك والجلود أمثال الشكائم والسروج فتاتي له بذلك ما امله من طرد الحيوانات التي صعبت عليه الحيلة في أخذها. وانما تفنن في هذه الأمور كلها ف وقت اشتغاله التشريح، وشهوته في وقوفه على خصائص أعضاء الحيوان، وبماذا تختلف، وذلك في المدة التي حددنا منتهاها بأحد وعشرين عاماً. ثم انه بعد ذلك أخذ في مآخذ أخر من النظر، فتصفح جميع الأجسام التي في عالم الكون والفساد: من الحيوانات على اختلاف أنواعها، والنبات والمعادن وأصناف الحجارة والتراب والماء والبخار والثلج والبرد، والدخان واللهيب والجمر، فرأى لها أصوافاً كثيرة وأفعالاً مختلفة، وحركات متفقة ومضادة، وأنعم النظر في ذلك والتثبت، فرأى أنها تتفق ببعض الصفات وتختلف ببعض، وأنها من الجهة التي تتفق بها واحدة، ومن الجهة التي تختلف فيها متغايرة ومتكثرة فكان تارة ينظر خصائص الأشياء وما يتفرد به بعضها عن بعض، فتكثر عنده كثرة تخرج عن الحصر، وينتشر له الوجود انتشار لا يضبط. كل عضو منها فيرى أنه يحتمل القسمة إلى أجزاء كثيرة جداً، فيحكم على ذاته بالكثرة، وكذلك على ذات كل شيء. + +ثم كان يرجع إلى نظر آخر من طريق ثان، فيرى أن أعضاءه، وان كانت كثيرة فهي متصلة كلها بعضها ببعض، لا انفصال بينها بوجه، فهي في الحكم الواحد، وأنها لا تختلف إلا بحسب اختلاف أفعالها، أن ذلك الاختلاف إنما هو بسبب ما يصل إليها من قوة الروح الحيواني، الذي انتهى إليه نظره أولاً، وأن ذلك الروح واحد ذاته، وهو حقيقة الذات، وسائر الأعضاء كلها كالآلات، فكانت تتحد عنده ذاته بهذا الطريق. + +ثم أنه كان ينتقل إلى جميع أنواع الحيوانات، فيرى كل شخص منها واحداً بهذا النوع من النظر. ثم كان ينظر إلى نوع منها: كالظباء والخيل وأصناف الطير صنفاً صنفاً، فكان يرى أشخاص كل نوع يشبه بعضه بعضاً في الأعضاء الظاهرة والباطنة الادراكات والحركات والمنازع، ولا يرى بينها اختلافاً إلا في أشياء يسيرة بالإضافة إلى ما اتفقت فيه. + +وكان يحكم بان الروح الذي لجميع ذلك النوع شيء واحد، وأنه لم يختلف إلا أنه انقسم على قلوب كثيرة، وأنه لو أمكن أن يجمع جميع الذي افترق في تلك القلوب منه ويجعل في وعاء واحد، لكان كله شيئاً واحداً، بمنزلة ماء واحد، أو شراب واحد، يفرق على أوان كثيرة، ثم يجمع بعد ذلك. فهو في حالتي تفريقه وجمعه شيء واحد، إنما الغرض له التكثر بوجه ما، فكان يرى النوع بهذا النظر واحداً، ويجعل كثرة أشخاصه بمنزلة كثيرة أعضاء الشخص الواحد، التي لم تكن كثرة في الحقيقة. + +ثم كان يحضر أنواع الحيوانات كلها في نفسه ويتأملها فيراها تتفق في أنها تحس، وتغتذي، وتتحرك بالإرادة إلى أي جهة شاءت، وكان قد علم أن هذه الأفعال هي أخص أفعال الروح الحيواني، وأن سائر الأشياء التي تختلف بها بعد هذا الاتفاق، ليست شديدة الاختصاص بالروح الحيواني. فظهر له بهذا التأمل، أن الروح الحيواني الذي لجميع جنس الحيوان واحد بالحقيقة، وان كان فيه اختلاف يسير، اختص به نوع دون نوع: بمنزلة ماء واحد مقسوم على أوان كثيرة، بعضه أبرد من بعض. + +وهو في أصله واحد وكل ما كان في طبقة واحدة من البرودة، فهو بمنزلة اختصاص ذلك الروح الحيواني بنوع واحد، وان عرض له التكثر بوجه ما. فكان يرى جنس الحيوان كله واحداً بهذا النوع من النظر. ثم كان يرجع إلى أنواع النبات على اختلافها. فيرى كل نوع منها تشبه أشخاصه بعضها بعضاً في الأغصان، والورق، والزهر والثمر، والأفعال فكان يقيسها بالحيوان، ويعلم أن لها شيئاً واحداً فيه: هو لها بمنزلة الروح الحيواني وأنها بذلك الشيء واحد. وكذلك كان ينظر إلى جنس النبات كله، فيحكم باتحاده بحسب ما يراه من اتفاق فعله في أنه يتغذى وينمو. + +ثم كان يجمع في نفسه جنس الحيوان وجنس النبات، فيراهما جميعاً متفقين في الاغتذاء والنمو، ألا أن الحيوان يزيد على النبات، بفضل الحس والادراك والتحرك؛ وربما ظهر في النبات شيء شبيه به، مثل تحول وجوه الزهر إلى جهة الشمس، وتحرك عروقه إلى الغذاء، بسبب شيء واحد مشترك بينهما، هو في أحدهما أتمم وأكمل، وفي الآخر قد عاقه عائق ما، وأن ذلك بمنزلة ماء واحد قسم بقسمين، أحدهما جامد والآخر سيال، فيتحد عنده النبات والحيوان. ثم ينظر إلى الأجسام التي لا تحس ولا تغتذي ولا تنمو، من الحجارة، والتراب، والماء، والهواء، واللهب، فيرى أنها أجسام مقدر لها الطول وعرض وعمق وأنها لاتختلف، إلا أن بعضها ذو لون وبعضها لا لون له وبعضها حار والآخر بارد، ونحو ذلك من الاختلافات وكان يرى أن الحار منها يصير بارداً، والبارد يصير حار وكان يرى الماء يصير بخاراً والبخار ماء، والأشياء المحترقة تصير جمراً، ورماداً، ولهيباً، ودخاناً، والدخان إذا وافق في صعوده قبة حجر انعقد فيه وصار بمنزلة سائر الأشياء الأرضية، فيظهر له بهذا التأمل، أن جميعها شيء واحد في الحقيقة، وان لحقتها الكثرة بوجه ما، فذلك مثل ما لحقت الكثرة للحيوان والنبات. + +ثم ينظر إلى الشيء الذي اتحد به عند النبات والحيوان، فيرى أنه جسم ما مثل هذه الأجسام: له طول وعرض وعمق، وهو إما حار واما بارد، كواحد من هذه الأجسام التي لا تحس ولا تتغذى، وانما خالفها بأفعاله التي تظهر عنه بالآلات الحيوانية والنباتية لا غير، ولعل تلك الأفعال ليست ذاتية، وانما تسري إليه من شيء آخر ولو سرت إلى هذه الأجسام الآخر، لكانت مثله فكان ينظر إليه بذاته مجرداً عن هذه الأفعال، التي تظهر ببادئ الرأي، أنها صادرة عنه، فكان يرى أنه ليس إلا جسماً من هذه الأجسام، فيظهر له بهذا التأمل، أن الأجسام كلها شيء واحد: حيها وجمادها، متحركها وساكنها، إلا أنه يظهر أن لبعضها أفعالاً بالات، ولا يدري هل تلك الأفعال ذاتية لها، أو سارية أليها من غيرها. وكان في هذه الحال لا يرى شيئاً غير الأجسام فكان بهذا الطريق يرى الوجود كله شيئاً واحداً، وبالنظر الأول كثرة لا تنحصر ولا تتناهى. وبقي بحكم هذه الحالة مدة. + +ثم انه تأمل جميع الأجسام حيها وجامدها. وهي التي هي عنده تارةً شيء واحد وتارةً كثيرة كثرة لا نهاية لها، فرأى إن كل واحد منها، لا يخلو من أحد أمرين: إما أن يتحرك إلى جهة العلو مثل الدخان واللهيب والهواء، إذا حصل تحت الماء واما أن يتحرك إلى الجهة المضادة لتلك الجهة، وهي جهة السفل، مثل الماء، وأجزاء الحيوان و النبات، وأن كل جسم من هذه الأجسام لن يعرى عن إحدى هاتين الحركتين وأنه لا يسكن إلا إذا منعه مانع يعوقه عن طريقه، مثل الحجر النازل يصادف وجه الأرض صلباً، فلا يمكن أن يخرقه، ولو أمكنه ذلك لما انثنى عن حركته فيما يظهر، ولذلك إذا رفعته، وجدته يتحامل عليك بميله إلى جهة السفل، طالباً للنزول. وكذلك الدخان في صعوده، لا ينثني إلا أن يصادف قبة صلبة تحبسه، فحينئذً ينعطف يميناً وشمالاً ثم إذا تخلص من تلك القبة، خرق الهواء صاعداً لأن الهواء لا يمكنه أن يحبسه. + +وكان يرى إن الهواء إذا ملئ به زق جلد، وربط ثم غوص تحت الماء طلب الصعود وتحامل على من يمسكه تحت الماء، ولا يزال يفعل ذلك حتى يوافي موضع الهواء، وذلك بخروجه من تحت الماء فحينئذً يسكن ويزول عنه ذلك التحامل والميل إلى جهة العلو الذي كان يوجد منه قبل ذلك. ونظر هل يجد جسماً يعرى عن إحدى هاتين الحركتين أو الميل إلى إحداهما في الوقت ما؟ فلم يجد ذلك في الأجسام التي لديه، وانما طلب ذلك، لانه طمع أن يجده، فيرى طبيعة الجسم من حيث هو جسم، دون أن تقترن به وصف من الأوصاف، التي هي منشأ التكثر. فلما أعياه ذلك ونظر إلى الأجسام التي هي أقل الأجسام حملاً للأوصاف فلم يرها تعرى عن أحد هذين الوصفين بوجه، وهما اللذان يعبر عنهما بالثقل والخفة فنظر إلى الثقل والخفة، هل هما للجسم من حيث هو جسم؟ أو هما لمعنى زائد على الجسمية؟ فظهر له أنهما لمعنى زائد على الجسمية لانهما لو كانا للجسم من حيث هو جسم، لما وجد إلا وهما له. + +ونحن نجد الثقيل لا توجد فيه الخفة، والخفيف لا يوجد فيه الثقل، وهما لا محالة جسمان ولكل واحد منهما معنى منفرد به عن الأخر زائد على جسميته. وذلك المعنى، الذي به غاير كل واحد منهما الآخر، ولولا ذلك لكانا شيئاً واحداً من جميع الوجوه. + +فتبين له أن حقيقة كل واحد من الثقيل والخفيف، مركبة من معنيين: أحدهما ما يقع فيه الاشتراك منهما جميعاً، وهو معنى الجسمية؛ والآخر ما تنفرد به حقيقة كل واحد منهما على الاخر، وهما أما الثقل في احدهما واما الخفة في الاخر، المقترنان بمعنى الجسمية، أي المعنى الذي يحرك أحدهما الأخر علواً والأخر سفلاً. وكذلك نظر إلى سائر الأجسام من الجمادات والأحياء، فرأى أن حقيقة وجود كل واحد منهما مركبة من معنى الجسمية، ومن شيء أخر زائد على الجسمية: أما واحد، واما أكثر من واحد؛ فلاحت له صور الأجسام على اختلافها وهو أول ما لاح له من العالم الروحاني، اذ هي صور لا تدرك بالحس، وانما تدرك بضرب ما من النظر العقلي. + +ولاح له في جملة ما لاح من ذلك، أن الروح الحيواني الذي مسكنه القلب - وهو الذي تقدم شرحه أولاً - لابد له أيضاً من معنى زائد على جسميته يصلح بذلك المعنى لأن يعمل هذه الأعمال الغريبة، التي تختص به من ضروب الاحساسات، وفنون الادراكات وأصناف الحركات، وذلك المعنى هو صورته وفضله الذي انفصل به عن سائر الأجسام، وهو الذي يعبر عنه النظار بالنفس الحيوانية. وكذلك ايضاً للشيء الذي يقوم للنبات مقام الحار الغريزي للحيوان، شيء يخصه هو صورته، وهو الذي يعبر عنه النظار بالنفس النباتية. وكذلك لجميع الأجسام الجمادات: وهي ما عدا الحيوان والنبات مما في عالم الكون والفساد شيء يخصها به، يفعل كل واحد منها فعله الذي يختص به مثل صنوف الحركات وضروب الكيفيات المحسوسة عنها، وذلك الشيء هو صورة كل واحد منها، وهو الذي يعبر النظار عنه بالطبيعة. + +فلما وقف بهذا النظر على ان حقيقة الروح الحيواني، الذي كان تشوقه اليه ابداً، مركبة من معنى الجسمية، ومن معنى أخر زائد على الجسمية، وان معنى الجسمية مشترك، ولسائر الأجسام، والمعنى الأخر المقترن به هو وحده، هان عنده معنى الجسمية فاطرحه، وتعلق فكره بالمعنى الثاني، وهو الذي يعبر عنه النفس؛ فتشوق إلى التحقق به فالتزم الفكرة فيه، وجعل مبدأ النظر في ذلك تصفح الأجسام كلها، لا من جهة ما هي أجسام، بل من وجهة ما هي ذوات صور تلزم عنها خواص، ينفصل بها بعضها ببعض. فتتبع ذلك وحصره في نفسه، فرأى جملة من الأجسام، تشترك في صورة ما يصدر عنها فعل ما، أو أفعال ما، ورأى فريقاً من تلك الجملة، مع أنه يشارك الجملة بتلك الصورة، يزيد عليها بصورة أخرى، يصدر عنها ما، ورأى طائفة من ذلك الفريق، مع أنها تشارك الفريق في الصورة الأولى والثانية، تزيد عليه بصوره ثالثة، تصدر عنها أفعال ما خاصة بها. مثال ذلك: إن الأجسام الأرضية، مثل التراب والحجارة والمعادن والنبات والحيوان، وسائر الأجسام الثقيلة، وهي جملة واحدة تشترك في صورة واحدة تصدر عنها الحركة إلى الأسفل، ما لم يعقها عائق عن النزول: ومتى تحركت إلى جهة العلو بالقسر ثم تركت، تحركت بصورتها إلى الأسفل. وفريق من هذه الجملة، وهو النبات والحيوان، مع مشاركة الجملة المتقدمة في تلك الصورة، يزيد عليها صورة أخرى، يصدر عنها التغذي والنمو. والتغذي: هو أن يخلف المتغذي، بدل ما تحلل منه، بان يحيل إلى ما التشبه بجوهره مادة قريبة منه، يجتذبها إلى نفسه. + +والنمو: هو الحركة في الأقطار الثلاثة، على نسبة محفوظة في الطول والعرض والعمق. + +فهذان الفعلان عامان للنبات والحيوان، وهما لا محالة صادران عن صورة مشتركة لهما، وهي المعبر عنها بالنفس النباتية. وطائفة من هذا الفريق، وهو الحيوان خاصة، مع مشاركته الفريق المتقدم في الصورة الأولى والثانية، تزيد عليه بصورة ثالثة، يصدر عنها الحس والتنقل من حين إلى أخر. ورأى أيضاً كل نوع من أنواع الحيوان، له خاصية ينحاز بها عن سائر الأنواع، وينفصل بها متميزاً عنها. فعلم إن ذلك صادر عن صورة له تخصه هي زائدة عن معنى الصورة المشتركة له ولسائر الحيوان، وكذلك لكل واحد من أنواع النبات مثل ذلك. فتبين له إن الأجسام المحسوسة التي في عالم الكون والفساد، بعضها تلتئم حقيقته من معان كثيرة، زائدة على معنى الجسمية، وبعضها من معان اقل؛ وعلم إن معرفة الأقل أسهل من معرفة الأكثر؛ فطلب أولاً الوقوف على الحقيقة لشيء الذي تلتئم حقيقته من اقل الأشياء، ورأى إن الحيوان والنبات، لا تلتئم حقائقها إلا من معان كثيرة، لتفنن أفعالها؛ فأخر التفكير في صورهما. وكذلك رأى إن أجزاء الأرض بعضها ابسط من بعض، فقصد منها إلى ابسط ما قدر عليه وكذلك رأى إن الماء شيء قليل التركيب، لقلة ما يصدر عن صورته من أفعال، وكذلك راى النار والهواء. وكان قد سبق إلى ظنه أولاً، أن هذه الأربعة يستحيل بعضها إلى بعض، وان لها شيئاً واحداً تشترك فيه، وهو معنى الجسمية، وان ذلك الشيء ينبغي إن يكون خلواً من المعاني التي تميز بها كل واحد من هذه الأربعة عن الأخر، فلا يمكن أن يتحرك إلى فوق ولا إلى اسفل، ولا إن يكون حاراً ولا يكون بارداً، ولا يكون رطباً، ولا يابساً، لان كل واحد من هذه الاوصاف، لا يعم جميع الأجسام، فليست إذن للجسم بما هو جسم. + +فإذا أمكن وجود جسم لا صورة فيه زائدة على الجسمية، فليس تكون فيه صفة من هذه الصفات، ولا يمكن إن تكون فيه صفة إلا وهي تعم سائر الأجسام المتصورة، بضروب الصور. فنظر هل يجد وصفاً واحداً يعم جميع الأجسام: حيها وجمادها، فلم يجد شيئاً يعم الأجسام كلها. إلا معنى الامتداد الموجود في جميعها في الأقطار الثلاثة، التي يعبر عنها بالطول، والعرض، والعمق، فعلم هذا المعنى هو للجسم من حيث هو جسم، لكنه لم يتأت له بالحس وجود جسم بهذه الصفة وحدها، حتى لا يكون فيه معنى زائد على الامتداد المذكور ويكون بالجملة خلواً من سائر الصور. ثم تفكر في هذا الامتداد إلى الأقطار الثلاثة، هل هو معنى الجسم بعينه، وليس ثم معنى أخر أو ليس الأمر كذلك، فرأى أن وراء هذا الامتداد معنى أخر، هو الذي يوجد فيه هذا الامتداد، وان الامتداد وحده لا يمكن إن يقوم بنفسه كما إن ذلك الشيء الممتد، لا يمكن أن تقوم دون امتداد. واعتبر ذلك ببعض هذه الأجسام المحسوسة ذوات الصور، كالطين مثلاً، كان له طول وعرض وعمق على قدر ما. + +ثم إن تلك الكرة بعينها لو أخذت وردت إلى شكل مكعب أو بيض، لتبدل ذلك الطول وذلك العرض وذلك العمق، وصارت على قدر أخر. غير الذي كانت عليه، والطين واحد بعينه لم يتبدل، غير أنه لا بد له من طول وعرض وعمق على أي قدر كان، ولا يمكن إن يعرى عنها؛ غير أنها لتعاقبها عليه، تبين له أنها معنى على حياله؛ ولكونه لا يعرى بالجملة عنها، تبين له أنها من حقيقة. فلاح له بهذا الاعتبار، إن الجسم، بما هو جسم، مركب على الحقيقة من معنين: أحدهما يقوم منه مقام الطين للكرة في هذا المثال. والأخر: يقوم مقام طول الكرة وعرضها وعمقها، أو المكعب، أو أي شكل كان له. وانه لا يفهم الجسم إلا مركباً من هذين المعنين، وان احدهما لا يستغني عن الأخر. ولكن الذي يمكن أن يتبدل ويتعاقب على أوجه كثيرة، وهو معنى الامتداد يشبه الصورة التي لسائر الأجسام ذوات الصور، والذي يثبت على حال واحدة، وهو الذي ينزل منزلة الطين في المثال المتقدم، يشبه معنى الجسمية التي لسائر الأجسام ذوات الصور. + +وهذا الشيء الذي هو بمنزلة الطين في هذا المثال هو الذي يسميه النظار المادة والهيولى وهي عارية عن الصورة جملة. فلما نظره إلى هذا الحد، وفارق المحسوس بعض مفارقة، وأشرف على تخوم العالم العقلي، استوحش وحن إلى ما ألفه من عالم الحس، فتقهقر قليلاً وترك الجسم على الإطلاق، إذ هو أمر لا يدركه الحس، ولا يقدر على تناوله. فاخذ أبسط الأجسام المحسوسة التي شاهدها، وهي تلك الأربعة التي كان قد وقف نظره عليها. + +فأول ما نظر إلى الماء فرأى انه إذا خلي وما تقتضيه صورته، ظهر منه برد محسوس، وطلب النزول إلى اسفل فإذا سخن أما بالنار واما بحرارة الشمس، زال عنه البرد أولاً وبقي فيه طلب النزول، فإذا أفرط عليه بالتسخين، زال عنه طلب النزول إلى اسفل. وصار يطلب الصعود إلى فوق. فزال عنه بالجملة الوصفان اللذان كانا أبداً يصدران عن صورته، ولم يعرف من صورته أكثر من صدور هذين الفعلين عنها. فلما زال هذان الفعلان بطل حكم الصورة، فزالت الصورة المائية عن ذلك الجسم عندما ظهرت منه أفعال من شأنها أن تصدر عن صورة أخرى، وحدثت له صورة أخرى، بعد أن لم تكن، وصدر عنه بها أفعال لم يكن من شأنها أن تصدر عنه وهو بصورته الأولى. فعلم بالضرورة أن كل حادث لا بد له من محدث. فارتسم في نفسه بهذا الاعتبار، فاعل للصورة، ارتساماً على العموم دون تفصيل. ثم أنه تتبع الصور التي كان قد عاينها قبل ذلك، صورة صورة، فرأى أنها كلها حادثة، وأنها لا بد لها من فاعل. ثم نظر إلى ذوات، الصور، فلم ير أنها شيء أكثر من استعداد الجسم لان يصدر عنه ذلك الفعل، مثل الماء، فانه إذا افرط عليه التسخين، استعد للحركة إلى فوق وصلح لها. + +فذلك الاستعداد هو صورته، إذ ليس ها هنا إلا جسم وأشياء تحس عنه، بعد أن لم تكن؛ فصلوح الجسم لبعض الحركات دون بعض، واستعداده بصورته، ولاح له مثل ذلك في جميع الصور، فتبين له أن الأفعال الصادرة عنها، ليست في الحقيقة لها، وانما هي لفاعل يفعل بها الأفعال المنسوبة إليها؛ وهذا المعنى الذي لاح له، هو قول الرسول الله عليه الصلاة والسلام: "كنت سمعه الذي يسمع به وبصره الذي يبصر به" وفي محكم التنزيل: "بسم الله الرحمن الرحيم" فان تقتلوهم ولكن الله قتلهم؛ وما رميت إذا رميت، ولكن الله رمى! صدق الله العظيم. فلما لاح له من أمر هذا الفاعل، ما لاح على الإجمال دون تفصيل، حدث له شوق حثيث إلى معرفته على التفصيل، ولانه لم يكن بعد فارق عالم الحس، جعل يطلب هذا الفاعل على جهة المحسوسات، وهو لا يعلم بعد هل هو واحد أو كثير؟ فتصفح جميع الأجسام التي لديه، وهي التي كانت فكرته أبداً فيها، فرأها كلها تتكون تارة وتفسد أخرى، وما لم يقف على فساد جملته، وقف على الفساد أجزائه مثل الماء والأرض، فانه راى أجزاءهما تفسد بالنار، وكذلك الهواء رآه يفسد بشدة البرد، حتى بتكون منه الثلج فيسيل ماء. وكذلك سائر الأجسام التي كانت لديه، ولم ير منها شيئاً بريئاً عن الحدوث والافتقار إلى الفاعل المختار، فاطرحها كلها وانتقلت فكرته إلى الأجسام السماوية. + +وانتهى إلى هذا النظر على رأس أربعة أسابيع من منشئه، وذلك ثمانية وعشرون عاماً. فعلم إن السماء وما فيها من كواكب الأجسام، لأنها ممتدة في الأقطار الثلاثة: الطول، والعرض، والعمق؛ لا ينفك شيء منها عن هذه الصفة، وكل ما لا ينفك عن هذه الصفة، فهو جسم؛ فهي إذن كلها أجسام. ثم تفكر هل هي ممتدة إلى ما لا نهاية، وذاهبة أبداً في الطول والعرض والعمق إلى ما لا نهاية، أو هي متناهية محدودة بحدود تنقطع عندها، ولا يمكن أن يكون وراءها شيء من الامتداد؟ فتحير بعد ذلك بعض الحيرة. ثم انه بقوة فطرته، وذكاء خاطره، راى أن جسماً لا نهاية له أمر باطل، وشيء لا يمكن، ومعنى لا يعقل، وتقوى هذا الحكم عنده بحجج كثيرة، سنحت له بينه وبين نفسه وذلك أنه قال: أما الجسم السماوي فهو متناه من الجهة التي تليني والناحية التي وقع عليها حسي، فهذا لا شك فيه لأنني أدركه ببصر، وأما الجهة التي تقابل هذه الجهة، وهي التي يداخلني فيها الشك، فاني أيضاً أعلم من المحال أن تمتد إلى غير نهاية، لأني إن تخيلت أن خطين اثنين، يبتدئان من هذه الجهة المتناهية، ويمران في سمك الجسم إلى غير نهاية حسب امتداد الجسم، ثم تخيلت أن أحد هذين الخطين، قطع منه جزء كبير من ناحية طرفه المتناهي، ثم أخذ ما بقي منه شيء واطبق الخط المقطوع منه على الخط الذي لم يقطع منه شيء، وذهب الذهن كذلك معهما إلى الجهة التي يقال إنها غير متناهية، فأما أن نجد خطين أبداً يمتدان إلى غير نهاية ولا ينقص أحدهما عن الأخر، فيكون الذي قطع منه جزء مساوياً للذي لم يقطع منه شيء وهو محال، كما أن الكل مثل الجزء المحال؛ واما أن لا يمتد الناقص معه ابداً، بل ينقطع دون مذهبه ويقف عن الامتدادمعه، فيكون متناهياً، فإذا رد عليه القدر الذي قطع منه أولاً، وقد كان متناهياً، صار كله أيضاً متناهياً، وحينئذ لا يقصر عن الخط الأخر الذي يقطع منه شيء، ولا يفضل عليه فيكون إذن مثله وهو متناه، فذلك أيضاً متناه، فالجسم الذي تفرض فيه هذه الخطوط متناه، وكل جسم يمكن أن تفرض فيه هذه الخطوط، فكل جسم متناه. + +فإذا فرضنا أن جسماً غير متناه، فقد فرضنا باطلاً ومحالاً. فلما صح عنده بفطرته الفائقة التي لمثل هذه الجهة، أن جسم السماء متناه، أراد أن يعرف على أي شكل هو، وكيفية انقطاعه بالسطوح التي تحده. فنظر أولاً إلى الشمس والقمر وسائر الكواكب، فرأها كلها تطلع من جهة المشرق، وتغرب من جهة المغرب، فما كان يمر على سمت رأسه، رأه يقطع دائرة عظمى، وما مال عن سمت رأسه إلى الشمال أو إلى الجنوب، رأه يقطع دائرة أصغر من تلك. وما كان أبعد عن سمت الرأس إلى أحد الجانبين، كانت دائرته أصغر من دائرة ما هو أقرب. حتى كانت أصغر الدوائر التي تتحرك عليها الكواكب، دائرتين اثنتين: إحداهما حول القطب الجنوبي، وهي مدار سهيل، والاخرى حول القطب الشمالي، وهي المدار الفرقدين. ولما كان مسكنه على خط الاستواء الذي وصفناه أولاً، كانت هذه الدوائر كلها على سطح آفة. ومتشابهة في الجنوب والشمال وكان القطبان معاً ظاهرين له، وكان يترقب إذا طلع كوكب من الكواكب على دائرة كبيرة، وطلع كوكب آخر على دائرة صغيرة، وكان طلوعهما معاً، فكان يرى غروبهما معاً. واطرد له في ذلك جميع الكواكب وفي جميع الأوقات، فتبين له بذلك أن الفلك على شكل الكرة، وقوى ذلك في اعتقاده، ما رآه من رجوع الشمس والقمر وسائر الكواكب إلى المشرق، بعد مغيبها بالمغرب، وما رآه أيضاً من أنها تظهر لبصره على قدر واحد من العظم في حال طلوعها وتوسطها وغروبها، وأنها لو كانت حركتها على غير شكل الكرة لكانت لا محالة في بعض الأوقات، أقرب إلى بصره منها في وقت آخر، ولو كانت كذلك، لكانت مقاديرها واعظامها تختلف عند بصره فيراها في حال القرب أعظم مما يراها في حال البعد، لاختلاف أبعادها عن مركزه حينئذ بخلافها على الأول. + +فلما لم يكن شيء من ذلك؛ تحقق عنده كروية الشكل. وما زال يتصفح حركة القمر، فيراها آخذه من المغرب إلى المشرق وحركات الكواكب السيارة كذلك، حتى تبين له قدر كبير من علم الهيئة، وظهر له أن حركتها لا تكون إلا بأفلاك كثيرة، كلها مضمنة في فلك واحد، هو أعلاها. وهو الذي يحرك الكل من المشرق إلى المغرب في اليوم والليلة. وشرح كيفية انتقاله. ومعرفة ذلك يطول؛ وهو مثبت في الكتب، ولا يحتاج منه في غرضنا إلا للقدر الذي أردناه. فلما انتهى إلى هذه المعرفة، ووقف على أن الفلك بجملته وما يحتوي عليه، كشيء واحد متصل بعضه ببعض، وأن جميع الأجسام التي كان ينظر فيها أولاً: كالأرض والماء والهواء والنبات والحيوان وما شاكلها، هي كلها في ضمنه وغير خارجة عنه، وأنه كله أشبه شيء بشخص من أشخاص الحيوان؛ وما فيه من الكواكب المنيرة هي بمنزلة حواس الحيوان؛ وما فيه من ضروب الأفلاك، المتصل بعضها ببعض، هي بمنزلة أعضاء الحيوان؛ وما في داخله من الكون والفساد هي بمنزلة ما في جوف الحيوان من أصناف الفضول والرطوبات، التي كثيراً ما يتكون فيها أيضاً حيوان، كما يتكون في العالم الأكبر. فلما تبين له أنه كله كشخص واحد في الحقيقة، واتحدت عنده أجزاؤه الكثيرة بنوع من النظر الذي اتحدت به عنده الأجسام التي في عالم الكون والفساد، تفكر في العالم بجملته، هل هو شيء حدث بعد إن لم يكن، وخرج إلى الوجود بعد العدم؟ أو هو أمر كان موجوداً فيما سلف، ولم يسبقه العدم بوجه من الوجوه؟ فتشك في ذلك ولم يترجح عنده أحد الحكمين على الآخر. وذلك أنه كان إذا أزمع على اعتقاد القدم، اعترضه عوارض كثيرة، من استحالة وجود ما لا نهاية له، بمثل الذي استحال عنده به وجود جسم لا نهاية وكذلك أيضاً كان يرى أن هذا الوجود لا يخلو من الحوادث، فهو لا يمكن تقدمه عليها، وما لا يمكن أن يتقدم على الحوادث، فهو أيضاً محدث. وإذا أزمع على اعتقاد الحدوث، اعترضته عوارض أخرى، وذلك أنه كان يرى أن معنى حدوثه، بعد أن لم يكن لا يفهم إلا على أن الزمان تقدمه، والزمان من جملة العالم وغير منفك عنه، فإذن لا يفهم تأخر العالم عن الزمان. وكذلك أيضاً كان يقول: إذا كان حادثاً، فلا بد له من محدث؛ وهذا المحدث الذي أحدثه، لم أحدثه الآن ولم يحدثه قبل ذلك، الطارئ طرأ عليه ولا شيء هناك غيره، أم لتغير حدث في ذاته؟ فان كان فما الذي احدث ذلك التغيير؟ وما زال يتفكر في ذلك عدة سنين. + +فتتعارض عنده الحجج، ولا يترجح عنده أحد الاعتقادين على الآخر. فلما أعياه ذلك، جعل يتفكر ما الذي يلزم عن كل واحد من الاعتقادين، فلعل اللازم عنهما يكون شيئاً واحداً. فرأى انه إن اعتقد حدوث العالم خروجه إلى الوجود بعد العدم، فاللازم عن ذلك ضرورة، انه لا يمكن أن يخرج إلى الوجود بنفسه، وانه لا بد له من فاعل يخرجه إلى الوجود، وان ذلك الفاعل لا يمكن إن يدرك بشيء من الحواس، لانه لو أدرك بشيء من الحواس لكان جسماً من الأجسام، ولو كان جسماً من الأجسام لكان من جملة العالم، وكان حادثاً واحتاج إلى محدث، ولو كان ذلك المحدث الثاني أيضاً جسماً، لحتاج إلى محدث ثالث، والثالث إلى رابع، ويتسلسل ذلك إلى غير نهايةً وهو باطل. فإذن لابد للعالم من فاعل ليس بجسم، وإذا لم يكن جسماً فليس إلى إدراكه لشيء من الحواس سبيل، الآن الحواس الخمس لا تدرك إلا الأجسام، وإذا لا يمكن أن يحس فلا يمكن أن يتخيل، لان التخيل ليس شيئاً إلا إحضار صور المحسوسات بعد غيبتها، وإذا لم يكن جسماً فصفات الأجسام كلها تستحيل عليه، وأول صفات الأجسام هو الامتداد في الطول والعرض والعمق، وهو منزه عن ذلك، وعن جميع ما يتبع هذا الوصف من صفات الأجسام. وإذا كان فاعلاً للعالم فهو لا محالة قادر عليه وعالم به "بسم الله الرحمن الرحيم" إلا يعلم من خلق، وهو اللطيف الخبير؟ صدق الله العظيم. وراى أيضاً انه إن اعتقد قدم العالم، وان العدم لم يسبقه، وانه لم يزل كما هو، فان اللازم عن ذلك أن حركته قديمة لا نهاية لها من جهة الابتداء، إذ لم يسبقها سكون يكون مبدؤها منه، وكل حركة فلابد لها من محرك ضرورة، والمحرك أما أن يكون قوة سارية في جسم من الأجسام - أما جسم المتحرك نفسه، واما جسم أخر خارج عنه - واما أن تكون قوة ليست سارية ولا شائعة قي جسم. وكل قوى سارية في جسم وشائعه فيه، فانها تنقسم بانقسامه، وتتضاعف بتضاعفه، مثل الثقل بالحجر مثلاً. المحرك إلى الأسفل. + +فانه إن قسم الحجر نصفين. وان زيد عليه أخر مثله، زاد في الثقل أخر مثله، فان أمكن أن يتزايد الحجر إلى غير نهاية، كتزايد هذا الثقل إلى غير نهاية، وان وصل الحجر إلى حد ما من العظم ووقف، وصل الثقل إلى ذلك الحد ووقف، لكنه قد تبرهن أن كل جسم فانه لا محالة متناه، فإذن كل قوة في الجسم فهي لا محالة متناهية. فان وجدناها قوة تفعل فعلاً لا نهاية له، فهي قوة ليست في جسم، وقد وجدنا الفلك يتحرك أبداً حركة لانهاية لها ولا انقطاع إذ فرضناه قديماً لا ابتداء له فالواجب على ذلك أن تكون القوة التي تحرك ليست في جسمه، ولا في جسم خارج عنه. فهي إذا لشيء بريء عن الأجسام، وغير موصوف بشيء من أوصاف الجسمية، وقد كان لاح له في نظره الأول في عالم الكون والفساد إن حقيقة وجود كل جسم، إنما هي من جهة صورته التي هي استعداده لضروب الحركات، وان وجوده الذي له من جهة مادته وجود ضعيف لا يكاد يدرك؛ فان وجود العالم كله إنما هو من جهة استعداده لتحريك هذا المحرك البريء عن المادة، وعن صفات الأجسام، المنزه عن أن يدركه حس، أو يتطرق إليه خيال، سبحانه، وإذا كان فاعلاً لحركات الفلك على اختلاف أنواعها، فعلاً لا تفاوت فيه ولا فتور فيه ولا قصور، فهو لا محالة قادر عليها وعالم بها. + +فانتهى نظره بهذا الطريق إلى ما انتهى إليه بالطريق الأول، ولم يضره في ذلك تشككه في قدم العالم أو حدوثه، وصح له على الوجهين جميعاً وجود فاعل غير الجسم، ولا متصل بجسم ولا منفصل عنه، ولا داخل فيه، ولا خارج عنه، إذ: الاتصال، والانفصال، والدخول، هي كلمات من صفات الأجسام، وهو منزه عنها. ولما كانت المادة في كل جسم مفتقرة إلى الصورة، إذ لا تقوم إلا بها ولا تثبت لها حقيقة دونها، وكانت الصورة لا يصح وجودها إلا من فعل هذا الفاعل تبين له افتقار جميع الموجودات في وجودها إلى هذا الفاعل وأنه لا قيام لشيء منها إلا به فهو إذن علة لها، وهي معلومة له، سواء كانت محدثة الوجود، بعد أن سبقها العدم، أو كانت الابتداء لها من جهة الزمان، ولم يسبقها العدم قط، فانها على كلا الحالتين معلولة، ومفتقرة إلى الفاعل، متعلقة الوجود به، ولولا دوامه لم تدم، ولولا وجوده لم توجد، ولولا قدمه لم تكن قديمة، وهو في ذاته غني عنها وبريء منها! وكيف لا يكون كذلك وقد تبرهن أن قدرته غير متناهية، وأن جميع الأجسام وما يتصل بها أو يتعلق بها، ولو بعض التعلق، هو متناه منقطع. فإذن العالم كله بما في السماوات والأرض والكواكب، وما بينها، وما فوقها، وما تحتها، فعله وخلقه؛ ومتأخر عليه بالذات، وان كانت غير ماخرة عليها بالزمان. كما انك إذا أخذت في قبضتك جسماً من الأجسام، ثم حركت يدك، فان ذلك الجسم لا محالة يتحرك تابعاً لحركة يدك، حركة متأخرة عن حركة يدك، تأخراً بالذات؛ وان كانت لم تتأخر بالزمان عنها، بل كان ابتداؤهما معاً، فكذلك العالم كله، معلول ومخلوق لهذا الفاعل بغير زمان "بسم الله الرحمن الرحيم" إنما أمره إذا أراد شيئاً أن يقول له كن فيكون صدق الله العظيم. فلما راى إن جميع الموجودات فعله، تصفحها من بعد ذا تصفحاً على طريق الاعتبار في قدرة فاعلها؛ والتعجب من غريب صنعته، ولطيف حكمته، ودقيق علمه فتبين له في اقل الأشياء الموجودة، فضلاً عن أكثرها من أثار الحكمة، وبدائع الصنعة، ما قضى منه كل العجب، وتحقق عنده إن ذلك لا يصدر إلا عن فاعل مختار في غاية الكمال وفوق الكمال "بسم الله الرحمن الرحيم" لا يغرب عنه مثقال ذرة في السموات ولا في الأرض ولا اصغر من ذلك ولا أكبر صدق الله العظيم. + +ثمتأمل في جميع أصناف الحيوان، كيف "بسم الله الرحمن الرحيم" أعطى كل شيء خلقه، ثم هداه صدق الله العظيم لاستعماله، فلولا أنه هداه لاستعمال تلك الأعضاء التي خلقت له في وجوه المنافع المقصود بها، لما انتفع بها الحيوان، وكانت كلاً عليه، فعلم بذلك أنه أكرم الكرماء، وارحم الرحماء. من فيض ذلك الفاعل المختار - جل جلاله - ومن وجوده، ومن فعله، فعلم أن الذي هو في ذاته أعظم منها، وأكمل، واتمم وأحسن، وأبهى وأجمل وأدوم، وأنه لا نسبة لهذه إلى تلك. فما زال يتتبع صفات الكمال كلها، فيراها له وصادرة عنه، ويرى أنه أحق بها من كل ما يوصف بها دونه. وتتبع صفات النقص كلها فرآه بريئاً منها، ومنزهاً عنها؛ وكيف لا يكون بريئاً منها وليس معنى النقص إلا العدم المحض، أو ما يتعلق بالعدم؟ وكيف يكون العدم تعلق أو تلبس، بمن هو الموجود المحض، الواجب الوجود بذاته، المعطي لكل ذي وجود وجوده، فلا وجود إلا هو: فهو الوجود، وهو الكمال، وهو التمام، وهو الحسن، وهو البهاء، وهو القدرة، وهو العلم، وهو هو، و "بسم الله الرحمن الرحيم" كل شيء هالك إلا وجهه صدق الله العظيم. فانتهت به المعرفة إلى هذا الحد، على رأس خمسة أسابيع من منشئه، وذلك خمسة وثلاثون عاماً، وقد رسخ في قلبه من هذا الفاعل، ما شغله عن الفكرة في كل شيء إلا فيه، وذهل عما كان فيه تصفح الموجودات والبحث عنها، حتى صار بحيث لا يقع بصره على شيء من الأشياء، إلا ويرى فيه أثر الصنعة، ومن حينه، فينتقل بفكره على الفور إلى الصانع ويترك المصنوع، حتى اشتد شوقه إليه، وانزعج قلبه بالكلية عن العالم الأدنى المحسوس، وتعلق بالعالم الأرفع المعقول. فلما حصل له العلم بهذا الموجود الرفيع الثابت الوجود الذي لا سبب لوجود جميع الأشياء، أراد أن يعلم بأي شيء حصل له هذا العالم، وبأي قوة أدرك هذا الموجود: فتصفح حواسه كلها وهي: السمع، والبصر، والشم، والذوق، واللمس، فرأى أنها لا تدرك شيئاً إلا جسماً، أو ما هو في الجسم، وذلك أن السمع لا يدرك المسموعات، وهي ما يحدث من تموج الهواء عند تصادم الأجسام، والبصر إنما يدرك الألوان، والشم يدرك الروائح، والذوق يدرك الطعوم، واللمس يدرك الأمزجة والصلابة واللين، والخشونة والملاسة، وكذلك القوة الخيالية لا تدرك شيئاً إلا أن يكون له طول وعرض وعمق؛ وهذه المدركات كلها من صفات الأجسام، وليس لهذه الحواس أدراك شيء سواها، وذلك لأنها قوى شائعة في الأجسام، ومنقسمة بانقسامها، فهي لذلك لا تدرك إلا جسماً منقسماً، لان هذه القوة إذا كانت شائعة في شيء منقسم، فلا محالة أنها إذا أدركت شيئاً من الأشياء، فانه ينقسم بانقسامها؛ فإذن كل قوة في جسم، فانها لا محالة لا تدرك إلا جسماً أو ما هو جسم. + +وقد تبين إن هذا الموجود الواجب الوجود، بريء من صفات الأجسام من جميع الاتجاهات، فإذن لا سبيل إلى إدراكه إلا بشيء ليس بجسم، ولا هو قوة في جسم، ولا تعلق له وجه من الوجوه بالأجسام، ولا هو داخل فيها ولا خارج عنها، ولا متصل بها ولا منفصل عنها. وقد كان تبين له أن أدركه بذاته، ورسخت المعرفة به عنده، فتبين له بذلك أن ذاته التي أدركه بها أمر غير جسماني، ولا يجوز عليه شيء من صفات الأجسام، وان كل ما يدركه من ظاهر ذاته من الجسمانية فانها ليست حقيقة ذاته، وانما حقيقة ذاته ذلك الشيء الذي أدرك به الموجود المطلق الواجب الوجود. فلما علم أن ذاته ليست هذه المتجسمة التي يدركها بحواسه، ويحيط بها أديمه، هان عنده بالجملة جسمه، وجعل يتفكر في تلك الذات الشريفة، التي أدرك بها ذلك الموجود الشريف الواجب الوجود، ونظر في ذاته تلك الشريفة، هل يمكن أن تبيد أو تفسد وتضمحل، أو هي دائمة البقاء؟ فرأى إن الفساد والاضمحلال إنما هو من صفات الأجسام بأن تخلع صورة وتلبس صورة أخرى، مثل الماء إذا صار هواء، والهواء إذا صار ماء، والنبات إذا صار تراباً، والتراب إذا صار نباتاً، هذا هو معنى الفساد. + +وأما الشيء الذي ليس بجسم، ولا يحتاج في قوامه إلى جسم، وهو منزه بالجملة عن الجسمانية، فلا يتصور فساده البتة. فلما ثبت له أن ذاته الحقيقة لا يمكن فسادها، أراد إن يعلم كيف يكون حالها إذا اطرح البدن وتخلت عنه، وقد كان تبين له أنها لا تطرحه إلا إذا لم يصلح آلة لها، فتصفح جميع القوى المدركة، فرأى أن كل واحدة منها تارةً تكون مدركة بالقوة، وتارةً تكون مدرة بالفعل: مثل العين في حال تغميضها أو أعراضها عن البصر، فانها تكون مدركة بالقوة - ومعنى مدركه بالقوة أنها لا تدرك الآن وتدرك في المستقبل - وفي حال فتحها واستقبالها للمبصر، تكون مدركه بالفعل - ومعنى مدركة بالفعل أنها الآن تدرك - وكذلك كل واحدة من هذه القوى تكون مدركة بالقوة وتكون مدركة بالفعل، وكل واحدة من هذه القوى إن كانت لم تدرك قط بالفعل، فهي ما دامت بالقوة لا تتشوق إلى إدراك الشيء المخصوص بها لأنها لم تتعرف به بعد، مثل من خلق مكفوف البصر؛ وان كانت قد أدركت بالفعل تارةً، ثم صارت بالقوة، فانها ما دامت بالقوة تشتاق إلى الإدراك بالفعل لأنها قد تعرفت إلى المدرك، وتعلقت به، وحنت إليه، مثل من كان يصيراً ثم عمي فانه لا يزال يشتاق إلى المبصرات. وبحسب ما يكون الشيء المدرك أتم وأبهى وأحسن، يكون الشوق أكثر؛ والتألم لفقده اعظم، ولذلك كان تألم من يفقد بصره بعد الرؤية أعظم من تألم من يفقد شمه، إذ الأشياء التي يدركها البصر أتم وأحسن من التي يدركها الشم، فان كان في الأشياء شيء لا نهاية لكماله، ولا غاية لحسنه وجماله وبهائه، وهو فوق الكمال والبهاء والجمال، وليس في الوجود كمال، ولا حسن، ولا بهاء، ولا جمال إلا صادر من جهته، وفائض من قبله، فمن فقد إدراك ذلك الشيء بعد إن تعرف به، فلا محالة أنهما ما دام فاقد له، يكون في ألام لا نهاية لها، كما أن من كان مدركاً له على الدوام، فانه يكون في لذة لا انفصام لها، وغبطة لا غاية لها ورائها، وبهجة وسرور لا نهاية لهما. وقد تبين له أن الموجود الواجب الوجود. + +متصف بأوصاف الكمال كلها، ومنزه عن الصفات النقص وبريء منها. وتبين له أن الشيء الذي به يتوصل إلى أدركه أمر لا يشبه الأجسام، ولا يفسد لفسادها؛ فظهر له بذلك أن من كانت له مثل هذه الذات، المعدة لمثل هذا الإدراك؛ فانه إذا أطرح البدن بالموت؛ فإما أن يكون قبل ذلك - في مدة تصريفه للبدن - لم يتعرف قط بهذا الموجود الواجب الوجود؛ ولا اتصل به؛ ولا سمع عنه؛ فهذا إذا فارق البدن لا يشتاق إلى ذلك الموجود ولا يتألم لفقده. واما جميع القوى الجسمانية، فانها تبطل ببطلان الجسم؛ فلا تشتاق أيضاً إلى مقتضيات تلك القوى، ولا تحن إليها، ولا تتألم لفقدها. وهذه حال البهائم غير الناطقة كلها: سواء كانت من صورة الإنسان أو لم تكن. واما إن يكون قبل ذلك - في مدة تصريفه للبدن - قد تعرف بهذا الموجود، وعلم ما هو عليه من الكمال والعظمة والسلطان والحسن إلا انه أعرض عنه واتبع هواه، حتى وافته منيته وهو على تلك الحال، فيحرم المشاهدة، وعنده الشوق إليها فيبقى في عذاب طويل، وألام لا نهاية لها. فأما من يتخلص من تلك الآلام بعد جهد طويل، ويشاهد ما تشوق إليه قبل ذلك، واما أن يبقى في آلامه بقاءً سرمدياً، بحسب استعداده لكل واحد من الوجهين لحياته الجسمانية. + +واما من تعرف بهذا الموجود الواجب الوجود، قبل أن يفارق البدن، واقبل بكليته عليه والتزم الفكرة في جلاله وحسن بهائه، ولم يعرض عنه حتى وافته منيته، وهذا على حال من الإقبال والمشاهدة بالفعل. فهذا إذا فارق البدن بقي في لذة لا نهاية لها، وغبطة وسرور وفرح دائم، لاتصال مشاهدته لذلك الموجود الواجب الوجود، وسلامة تلك المشاهدة من الكدر والشوائب؛ ويزول عنه ما تقتضيه هذه القوى الجسمانية من الأمور الحسية التي هي - بالإضافة إلى تلك الحال - ألام وشرور وعوائق. فلما تبين له أن كمال ذاته ولذتها إنما هو بمشاهدة ذلك الموجود الواجب الوجود على الدوام، مشاهدة بالفعل أبداً، حتى لا يعرض عنه طرفة عين لكي توافيه منيته، وهو في حال المشاهدة بالفعل، فتتصل لذته دون أن يتخللها ألم. ثم جعل يتفكر كيف يتأتى له دوام هذه المشاهدة بالفعل، حتى لا يقع منه أعراض فكان يلازم الفكرة في ذلك الموجود كل ساعة، فما هو إلا يسنح لبصره محسوس ما من المحسوسات، أو يخرق سمعه صوت بعض الحيوان، أو يتعرضه خيال من الخيالات، أو يناله ألم في أحد اعضائه، أو يصيبه الجوع أو العطش أو البرد أو الحر، أو يحتاج القيام لدفع فضوله؛ فتختل فكرته، ويزول عما كان فيه، ويتعذر عليه الرجوع إلى ما كان عليه من حال المشاهدة، إلا بعد جهد. وكان يخاف أن تفاجأه منيته وهو في حال الأعراض، فيفضي إلى الشقاء الدائم، وألم الحجاب. + +فساءه حاله ذلك، وأعياء الدواء. فجعل يتصفح أنواع الحيوانات كلها، وينظر أفعالها وما تسعى فيه، لعله يتفطن في بعضها أنها شعرت بهذا الموجود، وجعلت تسعى نحوه، فيتعلم منها ما يكون في سبب نجاته. فرآها كلها إنما تسعى في تحصيل غذائها، ومقتضى شهواتها من المطعوم والمشروب والمنكوح، والاستظلال والاستدفاء، وتجد في ذلك ليلها ونهارها إلى حين مماتها وانقضاء مدتها. ولم ير شيئاً منها ينحرف عن هذا الرأي، ولا يسعى لغيره في وقت من الأوقات، فبان له بذلك أنها لم تشعر بذلك الموجود ولا اشتاقت إليه، ولا تعرفت إليه بوجه من الوجوه، وأنها كلها صائرة إلى العدم، أو إلى حال شبيه بالعدم. فلما حكم على ذلك بالحيوان، علم أن الحكم على النبات أولى، إذ ليس للنبات من الادراكات إلا بعض ما للحيوان. وإذا كان الأكمل إدراكاً لم يصل إلى هذه المعرفة، فالأنقص إدراكاً أحرى أن لا يصل، مع انه رأى أيضاً أن أفعال النبات كلها لا تتعدى الغذاء والتوليد. ثم انه بعد ذلك نظر إلى الكواكب والأفلاك فرآها كلها منتظمة الحركات، جارية على نسق؛ ورآها شفافة ومضيئة بعيدة عن قبول التغيير والفساد، فحدس حدساً قوياً أن لها ذوات سوى أجسامها، تعرف ذلك الموجود الواجب الوجود، وأن تلك الذوات العارفة ليست بأجسام، ولا منطبعة في أجسام مثل ذاته، هو، العارفة، وكيف لا يكون لها مثل تلك الذوات البريئة عن الجسمانية، ويكون لمثله على ما به من الضعف وشدة الاحتياج إلى الأمور المحسوسة، وأنه من جملة الأجسام الفاسدة؟ ومع ما به من النقص، فلم يعقه ذلك عن أن تكون ذاته بريئة عن الأجسام لا تفسد، فتبين له بذلك أن الأجسام السماوية أولى بذلك، وعلم أنها تعرف ذلك الموجود الواجب الوجود وتشاهد على الدوام بالفعل، لأن العوائق التي قطعت به هو عن الدوام المشاهدة من العوارض المحسوسة، لا يوجد مثلها للأجسام السماوية. + +ثم انه تفكر: لم اختص هو من بين سائر أنواع الحيوانات بهذه الذات التي أشبه بها الأجسام السماوية. وقد كان تبين له أولاً من آمر العناصر واستحالة بعضها إلى بعض، وأن جميع ما على وجه الأرض لا يبقى على صورته؛ بل الكون والفساد متعاقبان عليه أبداً، وأن أكثر هذه الأجسام مختلطة مركبة من أشياء متضادة، ولذلك تؤول إلى الفساد، وانه لا يوجد منه شيء صرفاً، وما كان منها قريباً من أن يكون صرفاً خالصاً لا شائبة فيه، فهو بعيد عن الفساد جداً مثل الذهب والياقوت، وأن الأجسام البسيطة صرفة، ولذلك هي بعيدة عن الفساد، والصور لا تتعاقب عليها. وتبين له هنالك أن جميع الأجسام التي في عالم الكون والفساد، منها ما تتقوم حقيقتها بصورة واحدة زائدة على معنى الجسمية - وهذه هي الاسطقسات الأربع - ومنها ما تتقوم حقيقتها أكثر من ذلك كالحيوان والنبات. فما كان قوام حقيقته بصور أقل، كانت أفعاله أقل، وبعده عن الحياة أكثر، فان عدم الصورة جملة لم يكن فيه إلى الحياة طريق، وصار في حال شبيه بالعدم، وما كان قوام حقيقته بصور أكثر، كانت أفعاله أكثر، ودخوله في حال الحياة أبلغ؛ وان كانت تلك الصورة بحيث لا سبيل إلى مفارقتها لمادتها التي اختصت بها كانت الحياة حينئذ كامل الظهور والكمال والقوة. فالشيء العديم للصورة جملة هو الهيولى والمادة، ولا شيء من الحياة فيها وهي شبيهة بالعدم، والشيء المتقوم بصورة واحدة هي الاسطقسات الأربع وهي في أول مراتب الوجود في عالم الكون والفساد ومنها تتركب الأشياء ذوات الصور الكثيرة. وهذه الاسطقسات ضعيفة الحياة جداً، إذ ليست تتحرك إلا حركة واحدة، وانما كانت ضعيفة الحياة لان لكل واحد منها ضداً ظاهر العناد يخالفه في مقتضى طبيعته، ويطلب أن يغير صورته. + +فوجوده لذلك غير متمكن، وحياته ضعيف، والبات أقوى حياة منه والحيوان أظهر حياة منه. وذلك أن ما كان من هذه المركبات تغلب عليه طبيعة أسطقس واحد، فلقوته فيه يغلب طبائع الاسطقسات الباقية، ويبطل قواها، ويصير ذلك المركب في حكم الاسطقس الغالب، فلا يستأهل لاجل ذلك من الحياة آل شيئا يسيراً، كما إن ذلك الاسطقس لا يستأهل من الحياة إلا يسيراً ضعيفاً وما كان من هذه المركبات لا تغلب عليه طبيعة أسطقس واحد منها، فان الاسطقسات تكون فيه متعادلة متكافئة، فإذن لا يبطل لأحدهما الآخر قوة الآخر بأكثر مما يبطل ذلك الآخر قوته، بل يفعل بعضها في بعض فعلاً متساوياً، فلا يكون فعل أحد الاسطقسات أظهر فيه، ولا يستولي عليه أحدها، فيكون بعيد الشبه من كل واحد من الاسطقسات، فكأنه لا مضادة لصورته، فيستأهل الحياة بذلك. ومتى زاد هذا الاعتدال وكان أتم وأبعد من الانحراف، كان بعده عن أن يوجد له ضد أكثر، وكانت حياته أكمل. ولما كان الروح الحيواني الذي مسكنه القلب، شديد الاعتدال، لانه ألطف من الأرض والماء وأغلظ من النار والهواء، صار في حكم الوسط ولم يضاده شيء من الاسطقسات مضادة بينه. + +فاستعد بذلك الصورة الحيوانية، فرأى أن الواجب إلى ذلك أن يكون أعدل ما في هذه الأرواح الحيوانية مستعداً لاتمم ما يكون من الحياة في عالم الكون والفساد، وأن يكون ذلك الروح قريباً من أن يقال أنه لا ضد لصورته، فيشبه لذلك هذه الأجسام السماوية التي لا ضد لصورها؛ ويكون روح ذلك الحيوان، وكأنه وسط بالحقيقة بين الاسطقسات التي لا تتحرك إلى جهة العلو على الإطلاق، ولا إلى جهة السفل، بل لو أمكن أن يجعل في وسط المسافة بين المراكز وأعلى ما تنتهي إليه النار في جهة العلو ولم يطرأ عليه الفساد، لثبت هناك ولم يطلب الصعود ولا نزول. ولو تحرك في المكان، لتحرك حول الوسط كما تتحرك الأجسام السماوية، ولو تحرك في الوضع، لتحرك على نفسه، وكان كروي الشكل إذ لا يمكن غير ذلك، فإذن هو شديد الشبه بالأجسام السماوية. ولما كان قد اعتقد أن أحوال الحيوان، ولم ير فيها ما يظن به انه شعر بالموجود الواجب الوجود، وقد كان علم من ذاتها قد شعرت به، قطع ذلك على أنه هو الحيوان المعتدل الروح، الشيبة بالأجسام السماوية وتبين لو انه نوع مباين لسائر الحيوان، وانه إنما خلق لغاية أخرى، وأعد لامر عظيم، لم يعد له شيء من أنواع الحيوان، وكفى به شرفاً أن يكون أحس جزأيه - وهو الجسماني - أشبه الأشياء بالجواهر السماوية الخارجة عن عالم الكون والفساد، المنزهة عن الحوادث النقص والاستحالة والتغيير. وأما أشرف جزأيه، فهو الشيء الذي به عرف الموجود الواجب الوجود، وهذا الشيء العارف، أمر رباني الهي يستحيل ولا يلحقه الفساد، ولا يوصف بشيء مما توصف به الأجسام، ولا يدرك بشيء من الحواس، ولا يتخيل، ولا يتوصل إلى معرفته بآلة سواه، بل يتوصل إليه به؛ فهو العارف والمعروف، والمعرفة؛ وهو العالم، والمعلوم، والعلم؛ لا يتباين في شيء من ذلك، إذ التباين والانفصال من صفات الأجسام ولواحقها، ولا جسم هنالك ولا صفة جسم ولا لاحق بجسم! فلما تبين له الوجه الذي اختص به من بين سائر أصناف الحيوان بمشابهة الأجسام السماوية، رأى إن الواجب عليه أن يتقبلها ويحاكي أفعالها ويتشبه بها جهده. وكذلك رأى أنه بجزئه الاشرف الذي به عرف الموجود الواجب الوجود، فيه شبه ما منه من حيث هو منزه عن صفات الأجسام، وكما أن الواجب الوجود منزه عنها، فرأى ايضاً انه يجب عليه أن يسعى في تحصيل صفاته لنفسه من أي وجه أمكن، وان يتخلق بأخلاقه ويقتدي بأفعاله، ويجد في تنفيذ إرادته، ويسلم الآمر له، ويرضى بجميع حكمه، رضى من قلبه ظاهراً وباطناً، بحيث يسر به وان كان مؤلماً لجسمه وضاراً به ومتلفتاً لبدنه بالجملة. وكذلك رأى فيه شبهاً من سائر أنواع الحيوان بجزئه الخسيس الذي هو من عالم الكون والفساد، وهو البدن المظلم والكثيف، الذي يطالبه بأنواع المحسوسات من المطعوم والمشروب والمنكوح، ورأى أيضاً أن ذلك البدن لم يخلق له عبثاً ولا قرن به لامر باطل، ويجب عليه أن يتفقده ويصلح من شأنه. هذا التفقد لا يكون منه إلا بفعل يشبه أفعال سائر الحيوان. فاتجهت عنده الأعمال التي يجب عليه أن يفعلها نحو ثلاثة أغراض: أما عمل يتشبه بالحيوان الغير الناطق. + +واما عمل يتشبه به بالأجسام السماوية. واما عمل يتشبه به بالموجود الواجب الوجود. فالتشبه الأول: يجب عليه من حيث البدن المظلم ذو الأعضاء المنقسمة، والقوى المختلفة، والمنازع المتفننة. والتشبه الثاني: يجب عليه من حيث له الروح الحيواني الذي مسكنه القلب، وهو مبدأ لسائر البدن، ولما فيه من القوى. والتشبه الثالث: يجب عليه من حيث هو، أي: من حيث هو الذات التي بها عرف ذلك الموجود الواجب الوجود. وكان أولاً قد وقف على أن سعادته وفوزه من الشقاء، إنما هي في دوام المشاهدة لهذا الموجود الواجب الوجود، حتى يكون بحيث لا يعرض بطرفة عين. ثم أنه نظر بالوجه الذي يتأتى له به هذا الدوام، فأخر له النظر أنه يجب عليه الاعتمال في هذه الأقسام الثلاثة من التشبيهات: آما التشبه الأول، فلا يحصل له به شيء من هذه المشاهدة، بل هو صارف عنها وعائق دونها، إذ هو تصرف في الأمور المحسوسة، والأمور المحسوسة كلها حجب معترضة دون تلك المشاهدة؛ وانما احتيج إلى هذا التشبه لاستدامة هذا الروح الحيواني الذي يحصل به التشبه الثاني بالأجسام السماوية. + +فالضرورة تدعو إليه من هذا الطريق،ولو كان لا يخلو من تلك المضرة. واما التشبه الثاني، فيحصل له به حظ عظيم من المشاهدة على الدوام، لكنها مشاهدة يخالطها شوب؛ اذ من يشاهد ذلك النحو من المشاهدة على الدوام فهو مع تلك المشاهدة يعقل ذاته ويلتفت إليه حسبما يتبين بعد هذا. واما التشبه الثالث، فتحصل به المشاهدة الصرفة، والاستغراق المحض الذي لا التفات فيه بوجه من الوجوه الا إلى الموجود الواجب الوجود، والذي يشاهد هذه المشاهدة قد غابت عنه ذات نفسه وفنيت وتلاشت. وكذلك سائر الذوات، كثيرة كانت أو قليلة، إلا ذات الواحد الحق الواجب الوجود - جل وتعالى وعز. فلما تبين له أن مطلوبه الأقصى هو هذا التشبه الثالث، وأنه لا يحصل له إلا بعد التمرن والاعتمال مدة طويلة في التشبه الثاني، وان هذه المدة لا تدوم له بالتشبه الأول، وعلم أن التشبه الأول - وان كان ضرورياً، فانه عائق بذاته وان كان معيناً بالعرض لا بالذات لكنه ضروري- فألزم نفسه أن لا يجعل لها حظاً من هذا التشبه الأول، إلا بقدر الضرورة، وهي الكفاية التي لا بقاء للروح الحيواني بأقل منها. ووجد ما تدعو إليه الضرورة في بقاء هذا الروح أمرين: أحدهما: ما يمده من الداخل، ويخلف عليه بدل ما يتخلل منه وهو الغذاء. والأخر: ما يقيه من الخارج، ويدفع عنه وجوه الأذى: من البرد والحر والمطر ولفح الشمس والحيوانات المؤذية ونحو ذلك. ورأى أنه إن تناول ضرورية من هذه جزافاً كيفما اتفق، ربما وقع في السرف واخذ فوق الكفاية. فكان سعيه على نفسه من حيث لا يشعر، فرأى أن الحزم له أن يفرض لنفسه فيها حدوداً لا يتعداها، ومقادير لا يتجاوزها، وبأن له الفرض يجب أن يكون في جنس ما يتغذى به. وأي شيء يكون وفي مقداره وفي المدة التي تكون بين العبادات إليه. فنظر أولاً إلى أجناس ما به يتغذى، فرآها ثلاثة أضرب: أولاً: أما نبات لم يكمل بعد نضجه ولم ينته إلى غاية تمامه، وهي أصناف البقول الرطبة التي يمكن الاغتذاء بها. + +ثانياً: واما ثمرات النبات الذي تم وانتهى وأخرج بذرة ليتكون منه أخر من نوعه حفظاً له، وهي أصناف الفواكه رطبها ويابسها. ثالثاً: واما حيوان من الحيوانات التي يتغذى بها: أما البرية واما البحرية. وكان قد صح عنده أن هذه الأجناس كلها، من فعل ذلك الموجود الواجب الوجود الذي تبين له أن سعادته في القرب منه، وطلب التشبه به، ولا محالة أن الاغتذاء بها مما يقطعها عن كمالها ويحول بينها وبين الغاية القصوى المقصودة بها. فكان ذلك اعتراض على فعل الفاعل. وهذا الاعتراض مضاد لما يطلبه من القرب منه والتشبه به. فرأى أن الصواب كان له لو أمكن أن يمتنع عن الغذاء جملة واحدة، لكنه لما لم يمكنه ذلك، لانه أن امتنع عنه أل ذلك إلى فساد جسمه، فيكون ذلك اعتراضاً على فاعله أشد من الأول، إذ هو أشرف من تلك الأشياء الآخر التي يكون فسادها سبباً لبقائه. + +فاستهل أيسر الضررين، وتسامح في اخف الاعتراضين، ورأى إن يأخذ من هذه الأجناس إذا عدمت آيها تيسر له، بالقدر الذي يتبين له بعد هذا. فأما إن كانت كلها موجودة فينبغي له حينئذ إن يتثبت ويتخير منها ما لم يكن في أخذه كبير اعتراض على فعل فاعل، وذلك مثل لحوم الفواكه التي قد تناهت في الطيب، وصلح ما فيها لتوليد البزر على الشرط التحفظ على ذلك البزر، بان لا يأكله ولا يفسده ولا يلقيه في موضع لا يصلح للنبات، مثل الصفاة والسبخة ونحوهما. فان تعذر عليه وجود مثل هذه الثمرات ذات الطعم الغاذي، كالتفاح والكمثرى والأجاص ونحوها، كان له عند ذلك إن يأكل آما الثمرات التي لا يغذو منها إلا نفس البزر، كالجوز والقسطل، واما من البقول التي لم تصل بعد حد كمالها. والشرط عليه في هذين لأن يقصد أكثرها وجوداً وأقواها توليداً، وان لا يستأصل أصولها ولا يفني بزرها. فان عدم هذه، فله أن يأخذ من الحيوان آو من بيضه، والشرط عليه من الحيوان إن يأخذ من أكثره وجوداً، ويستأصل منه نوعاً بأسره. هذا ما رأى في جنس ما يتغذى به. واما المقدر فرأى أن يكون بحسب ما يسد خلة الجوع ولا يزيد عليها. واما الزمان الذي بين كل عودتين، فرأى انه إذا اخذ حاجته من الغذاء، أن يقيم عليه ولا يتعرض لسواه، حتى يلحقه ضعف يقطع به بعض الأعمال التي تجب عليه في التشبه الثاني، وهي التي يأتي ذكرها بعد هذا. فأما ما تدعو إليه الضرورة في بقاء الروح الحيواني مما يقيه من خارج، فكان الخطب فيه يسيراً: إذ كان مكتسياً بالجلود، وقد كان له مسكن يقيه مما يرد عليه من خارج، فاكتفى بذلك ولم يرى الاشتغال به، والتزم في غذائه القوانين التي رسمها لنفسه، وهي التي تقدم شرحها. ثم اخذ في العمل الثاني، وهو التشبه بالأجسام السماوية والاقتداء بها، والتقبل أوصافها، فانحصرت عنده في ثلاثة أضرب: الضرب الأول: أوصاف لها بالإضافة إلى ما تحتها من عالم الكون والفساد، وهي ما تعطيه إياه من التسخين بالذات، آو التبريد بالعرض، والإضاءة والتلطيف والتكثيف، إلى سائر ما تفعل فيه من الأمور التي بها يستعد لفيضان الصور الروحانية عليه من عند الفاعل الواجب الوجود. والضرب الثاني: أوصاف لها في ذاتها، مثل كونها شفافة وناصعة وطاهرة منزهة عن الكدر وضروب الرجس، ومتحركة بالاستدارة بعضها على مركز نفسها، وبعضها على مركز غيرها. + +والضرب الثالث: أوصاف لها بالإضافة إلى الموجود الواجب الوجود، مثل كونها تشاهد مشاهدة دائمة، وتعرض عنه، وتتشوق إليه، وتتصرف بحكمه، وتتسخر في تتميم إرادته، ولا تتحرك إلا بمشيئته وفي قبضته. فجعل يتشبه بها جهده في كل من هذه الاضرب الثلاثة. آما الضرب الأول: فكان تشبه بها فيه: إن ألزم نفسه إن لا يرى ذا حاجة آو عاهة آو مضرة، أو ذا عائق من الحيوان أو النبات، وهو يقدر على أزالتها عنه إلا ويزيلها. فمتى وقع بصره على نبات قد حجبه عن الشمس حاجب آو تعلق به نبات آخر يؤذيه، أو عطش عطشاً يكاد يفسده، أزال عنه ذلك الحاجب إن كان ما يزال، وفصل بينه وبين ذلك المؤذي بفاصل لا يضر المؤذي، وتهده بالسقي ما أمكنه. ومتى وقع بصره على حيوان قد أرهقه سبع آو نشب به ناشب، آو تعلق به شوك، آو سقط على عينيه آو آذنيه شيء يؤذيه، آو مسه ظمأ آو جوع، تكفل بإزالة ذلك كله عنه جهده واطعمه وسقاه. ومتى وقع بصره على ماء يسيل إلى سقي نبات أو حيوان وقد عاقه عن ممره ذلك عائق، من حجر سقط فيه، آو جرف انهار عليه، ازال ذلك كله عنه. وما زال يمعن في هذا النوع من ضروب التشبه حتى بلغ فيه الغاية. واما الضرب الثاني: فكان تشبهه بها فيه إن الزم نفسه دوام الطهارة وإزالة الدنس والرجس عن جسمه والاغتسال بالماء في أكثر الأوقات، وتنظيف ما كان من أظافره واسنانه ومغابن بدنه، وتطيبها بما أمكن من طيبات النبات وصنوف الدهون العطرة، وتعهد لباسه بالتنظيف والتطييب حتى كان يتلألأ حسناً وجمالاً ونظافة وطيباً. والتزم مع ذلك ضروب الحركة على الاستدارة: فتارةً كان يطوف بالجزيرة، ويدور على ساحلها ويسيح باكنافها، وتارةً كان يطوف ببيته، او ببعض الكدى أدوارا معدوده: آما مشياً، آما هرولة؛ وتارة يدور على نفسه حتى يغشه عليه. + +وأما الضرب الثالث: فكان تشبهه بها فيه، إن كان يلازم الفكرة في تلك الموجود الواجب الوجود، ثم يقطع علائق المحسوسات. ويغمض عينيه، ويسد أذنيه، ويضرب جهده عن تتبع الخيال، ويروم بمبلغ طاقته إن لا يفكر في شيء سواه، ولا يشترك به احداً ويستعين على ذلك بالاستدارة على نفسه والاستحثاث فيها. + +فكان اذا اشتد في الاستدارة، غابت عنه جميع المحسوسات، وضعف الخيال وسائر القوى التي إلى الألأت الجسمانية، وقوي فعل ذاته - التي هي بريئة من الجسم - فكانت في بعض الأوقات فكرته قد تخلص عن الشوب ويشاهد بها الموجود الواجب الوجود، ثم تكر عليه القوى الجسمانية فتفسد عليه حاله، وترده إلى اسفل السافلين. ويعود من ذي قبل، فان لحقه ضعف يقطع به عن غرضه تناول بعض الأغذية عن الشرائط المذكورة. ثم انتقل إلى شأنه من التشبه بالأجسام السماوية بالأضرب الثلاثة المذكورة. ودأب على ذلك مدة وهو يجاهد قواه الجسمانية وتجاهده، وينازعها وتنازعه في الأوقات التي يكون له عليها الظهور، وتتخلص فكرته عن الشوب، يلوح له شيء من أحوال أهل التشبه الثالث. + +ثم جعل يطلب التشبه الثالث، ويسعى في تحصيله، فينظر في صفات الموجود الواجب الوجود. وقد كان تبين له أثناء نظره العلمي قبل الشروع في العمل، إنها على ضربين: آما صفة ثبوت: كالعلم والقدرة والحكمة. + +وأما صففة سلب: كتنزه عن الجسمانية وعن صفات الأجسام ولواحقها، وما يتعلق بها، ولو على بعد. + +وأن صفات الثبوت يشترط فيها هذا التنزيه حتى لا يكون فيها شيء من صفات الأجسام التي من جملتها الكثرة، فلا تتكثر ذاته بهذه الصفات الثبوتية، ثم ترجع كلها إلى معنى واحد هي حقيقة ذاته. فجعل يطلب كيف يتشبه به في كل واحد من هذين الضربين. آما صفات الاجاب، فلما علم انها كلها راجعة إلى حقيقة ذاته، وانه لا كثرة فيها بوجه من الوجوه، إذ الكثرة من صفات الأجسام؛ وعلم إن علمه بذاته؛ ليس معنى زائداً على ذاته، بل ذاته هي علمه لذاته؛ وعلمه بذاته هو ذاته، تبين له انه إن أمكنه هو إن يعلم ذاته، فليس ذلك العلم الذي علم به ذاته معنى زائداً على ذاته، بل هو هو! فرأى إن التشبه به من صفات الاجاب، هو ان يعلمه فقط دون إن يشرك به شيئاً من صفات الأجسام؛ فاخذ نفسه بذلك. واما صقات السلب، فانها كلها راجعة إلى التنزه عن الجسمية. فجعل يطرح اوصاف الجسمية عن ذاته. وكان قد طرح منها كثيراً في رياضته المتقدمة التي كان ينحو بها بالتشبه بالأجسام السماوية. إلا انه أبقى منها بقايا كثيرة: كحركة الاستدارة - والحركة من أخص صفات الأجسام - وكل الاعتناء بأمر الحيوان والنبات والرحمة لها، والاهتمام بإزالة عوائقها. فان هذه أيضاً من صفات الأجسام، إذ لا يراها أولاً إلا بقوة جسمانية، ثم يكدح بأمرها بقوة جسمانية أيضاً. فاخذ في طرح ذلك كله عن نفسه، إذ هي بجملتها مما لا يليق بهذه الحالة التي يطلبها الآن. + +وما زال يقتصر على السكون في قصر مغارته مطرقاً، غاضاً بصره، معرضاً عن جميع المحسوسات والقوى الجسمانية، مجتمع الهم والفكرة في الموجود الواجب الوجود وحده دون شركه؛ فمتى سنح بخياله سانح سواه، طرده عن خياله جهده، ودافعه وراض نفسه على ذلك، ودأب فيه مدة طويلة، بحيث تمر عليه عدة أيام لا يتغذى فيها ولا يتحرك. وفي خلال شدة مجاهدته هذه ربما كانت تغيب عن ذكره وفكره جميع الأشياء إلا ذاته، فانها كانت لا تغيب عنه في وقت استغراقه بمشاهدة الموجود الأول الحق الواجب الوجود. + +فكان يسوءه ذلك، ويعلم انه شوب في المشاهدة المحضة، وشركه في الملاحظة. ومازال يطلب الفناء عن نفسه والإخلاص في مشاهدة الحق حتى تأتى له ذلك، وغابت عن ذكره وفكره السموات والأرض وما بينهما، وجميع الصور الروحانية والقوى الجسمانية، وجميع القوى المفارقة للمواد، والتي هي الذوات العارفه بالموجود الحق؛ وغابت ذاته في جملة تلك الذوات، وتلاشى الكل واضمحل، وصار هباءً منثوراً، ولم يبقى إلا الواحد الحق الموجود الثابت الوجود. + +وهو يقول بقوله الذي ليس معنى زائداً على ذاته: "بسم الله الرحمن الرحيم" لمن الملك اليوم لله الواحد القهار صدق الله العظيم ففهم كلامه وسمع ندائه ولم يمنعه عن فهمه كونه لا يعرف الكلام، ولا يتكلم. + +واستغرق في حالته هذه وشاهد ما لا عين رأت ولا إذن سمعت! ولا خطر على قلب بشر. فلا تعلق قلبك بوصف آمر لم يخطر على قلب بشر، فان كثيراً من الأمور التي تخطر على قلوب البشر قد يتعذر وصفه، فكيف بأمر لا سبيل إلى خطورة على القلب، ولا هو من عالمه ولا من طوره!؟ ولست أعني بالقلب جسم القلب، ولا الروح التي في تجويفه بل أعني صورة تلك الروح الفائضة بقواها على بدن الإنسان، فان كل واحد من هذه الثلاثة قد يقال له قلب ولكن لا سبيل لخطور ذلك الآمر على واحد من هذه الثلاثة، ولا يتأتى التعبير إلا عما الخطر علها. + +ومن رام التعبير عن تلك الحال، فقد رام مستحيلاً وهو بمنزلة من يريد أن يذوق الألوان من حيث هي الألوان، ويطلب أن يكون السواد مثلاً حلواً أو حامضاً. + +لكنا، مع ذلك، لا نخيلك عن إشارات نومئ بها إلى ما شاهده من عجائب ذلك المقام، على سبيل ضرب المثل، لا على سبيل قرع باب الحقيقية. إذ لا سبيل إلى التحقق بما في ذلك المقام إلا بالوصول إليه. + +فأصغ الآن بسمع قلبك، وحدق ييصر إلى ما أشير به اليك لعلك أن تجد منه هدياً يلقيك على جادة الطريق! وشرطي عليك أن لا تطلب مني في هذا الوقت مزيد بيان بالمشافهة على ما أودعه هذه الاوراق فان المجال ضيق، والتحكم بالألفاظ على آمر ليس من شأنه أن يلفظ به خطر. + +فأقول: انه لما فني عن ذاتهوعن جميع وعن جميع الذوات ولم ير في الوجود إلا الواحد القيوم، وشاهد ما شاهد، ثم عاد إلى ملاحظة الاغيار عندما آفاق من حالة تلك التي شبيه بالسكر، خطر بباله انه لا ذات له يغاير بها ذات الحق تعالى، وان حقيقة ذاته هي ذات الحق، وان الشيء الذي كان يظن أولاً انه ذات المغايرة لذات الحق، ليس شيئاً في الحقيقة، بل ليس ثم شيء إلا ذات الحق، وان ذلك بمنزلة نور الشمس الذي يقع على الأجسام الكثيفة فتراه يظهر فيها. + +فإنه وإن نسب إلى الجسم الذي يظهر فيه، فليس هو في الحقيقية شيئاً سوى نور الشمس. وان زال ذلك الجسم زال نوره، وبقي نور الشمس بحاله لم ينقص عند حضور ذلك الجسم ولم يزد عند مغيبه. + +ومتى حدث جسم يصلح لقبول ذلك النور، قبله، فإذا عدم الجسم عدم ذلك القبول، ولك يكن له معنى، عنده هذا الظن بما قد بان له من إن ذات الحق، عز وجل، لا تتكثر بوجهه من الوجوه، وأن علمه بذاته، وهو ذاته بعينها. + +فلزم عنده من هذا أن حصل عنده العلم بذاته، فقد حصلت عنده ذاته، وقد كان حصل عنده العلم فحصلت عنده الذات. + +وهذه الذات لا تحصل إلا عند ذاتها، ونفس حصولها هو الذات؛ فإذن هو الذات بعينها. وكذلك جميع الذوات المفارقة للمادة العارفة بتلك الذات الحقه التي كان يراها أولاً كثيرة، وصارت عنده بهذا الظن شيئاً واحداً. وكادت هذه الشبه ترسخ في نفسه لولا أن تداركه الله برحمته وتلافاه بهدايته، فعلم إن الشبهة انما ثارت عنده من بقايا ظلمة الأجسام، وكدورة المحسوسات. فان الكثير والقليل والواحد والوحدة، والجمع والاجتماع، والافتراق، هي كلها من صفات الأجسام، وتلك الذوات المفارقة العارفة بذات الحق، عز وجل، لبرائتها عن المادة، لا يجب إن يقال انها كثيرة، ولا واحدة، لان الكثرة انما هي مغايرة الذوات بعضها لبعض، والوحدة أيضاً لا تكون إلا بالاتصال. ولا يفهم شيء من ذلك إلا في المعاني المركبة المتلبسة بالمادة. غير إن العبارة في هذا الموضع قد تضيق جداً لانك إن عبرت عن تلك الذوات المفارقة بصيغة الجمع حسب لفظنا هذا، أوهم ذلك معنى الكثرة فيها، وهي بريئة عن الكثرة. وان أنت عبرت بصيغة الإفراد، اوهم ذلك معنى الاتحاد، وهو مستحيل عليها. وكأني بمن يقف على هذا الموضع من الخفافيش الذين تظلم الشمس في أعينهم يتحرك في سلسلة جنونه، ويقول: لقد افرطت في تدقيقك حتى انك قد انخلعت عن غريزة العقلاء، واطرحت حكم معقول، فان من أحكام العقل إن الشيء آما واحد واما كثير، فليتئد في غلوائه، وليكف من غرب لسانه وليتهم نفسه، وليعتبر بالعالم المحسوس الخسيس الذي هو أطباقه بنحو ما اعتبر به حي بن يقظان حيث كان بنظر فيه بنظر فيراه كثيراً كثرة لا تنحصر ولا تدخل تحت حد، ثم ينظر فيه بنظر آخر، فيراه واحداً. وبقي في ذلك متردداً ولم يكنه إن يقطع بأحد الوصفين دون الآخر. هذا فالعالم المحسوس منشأ الجمع والإفراد، وفيه الانفصال والاتصال، والتحيز والمغايرة، والاتفاق والاختلاف، فما ظنه بالعالم الإلهي الذي لا يقال فيه كل ولا بعض، ولا ينطق في أمره بلفظ من الألفاظ المسموعة، إلا وتوهم فيه شيء على خلاف الحقيقة، فلا يعرفه إلا من شاهده؛ ولا تثبت حقيقته إلا عند من حصل فيه. واما قوله: حتى انخلعت عن غريزة العقلاء، واطرحت حكم المعقول. فنحن نسلم له ذلك، ونتركه مع عقله وعقلائه، فان العقل الذي يعنيه هو أمثاله، انما هو القوة الناطقة التي تتصفح أشخاص الموجودات المحسوسة، وتقتنص منها المعنى الكلي. والعقلاء الذين يعنيهم، هم ينظرون من هذا النظر والنمط الذي كلامنا فيه فوق هذا كله، فليسد عنه سمعه من لا يعرف سوى المحسوسات وكلياتها، وليرجع إلى فريقه الذين "بسم الله الرحمن الرحيم" يعملون ظاهراً من الحياة الدنيا. وهم عن الآخرة هم غافلون. صدق الله العظيم. فان كنت ممن يقتنع بهذا النوع من التلويح والإشارة إلى ما في العالم الإلهي، ولا تحمل ألفاظاً من المعاني على ما جرت العادة بها في تحميلها إياه، فنحن نزيدك شيئاً مما شاهده حي بن يقظان في مقام أولي الصدق الذي تقدم ذكره، فتقول: انه بعض الاستغراق المحض، والفناء التام، وحقيقة الوصول، وشاهد للفلك الأعلى، الذي لا جسم له، ورأى ذاتاً بريئة عن المادة، ليست هي ذات الواحد الحق، ولا هي نفس الفلك، ولا هي غيرها؛ وكأنها صورة الشمس التي تظهر في مرآة من المرائي الصقيلة، فانها ليست هي الشمس ولا المرأة ولا غيرهما. وراى لذات ذلك الفلك المفارقة من الكمال والبهاء والحسن، ما يعظم عن إن يوصف بلسان، ويدق إن يكسى بحرف آو صوت، وراه في غاية من اللذة والسرور، والغبطة والفرح، بمشاهدة ذات الحق جل جلاله. وشاهد ايضاً للفلك الذي يليه، وهو فلك الكواكب الثابتة، ذاتاً بريئة عن المادة أيضاً، ليست هي ذات الواحد الحق، ولا ذات الفلك الأعلى المفارقة، ولا نفسه، ولا هي غيرها. وكأنها صورة الشمس التي تظهر في المرآة قد انعكست إليها من مرآة أخرى مقابلة للشمس، ورأى لهذه الذات ايضاً من البهاء والحسن واللذة مثل ما راى لتلك التي للفلك الأعلى. وشاهد ايضاً للفلك الذي يلي هذا، وهو فلك زحل ذاتاً مفارقة للمادة ليست هي شيئاً من الدواب التي شاهدها قبله ولا هي غيرها؛ وكأنها صورة الشمس التي تظهر في مرآة قد انعكست إليها الصورة من مرآة مقابلة للشمس؛ وراى لهذه الذات ايضاً مثل ما راى آمل قبلها من البهاء واللذة. ومازال يشاهد لكل فلك ذاتاً مفارقة بريئة عن المادة ليست هي شيئاً من الذوات التي قبلها ولا هي غيرها وكأنها صورة الشمس التي تنعكس من مرآة على مرآة، على رتب مرتبة بحسب ترتيب الأفلاك. وشاهد لكل ذات من هذه الذوات من الحسن والبهاء، واللذة والفرح، ما لا عين رأت، ولا أذن سمعت، ولا خطر على قلب بشر. إلى أن انتهى إلى عالم الكون والفساد، وهو جميعه حشو فلك القمر. فرأى له ذاتاً بريئة عن المادة ليست شيئاً من الذوات التي شاهدها قبلها، ولا هي سواها. ولهذه سبعون ألف وجه، في كل وجه سبعون ألف فم، في كل فم سبعون ألف لسان، يسبح بها ذات الواحد الحق، ويقدسها ويمجدها، لا يفتر؛ ورأى لهذه الذات، التي توهم فيها الكثرة وليست كثيرة، من الكمال واللذة، مثل الذي رآه لما قبلها. وكأن هذه الذات صورة الشمس التي تظهر في ماء مترجرج، وقد انعكست إليها الصورة من آخر المرايا التي انتهى إليها الانعكاس على الترتيب المتقدم من المرآة الأولى التي قابلت الشمس بعينها. ثم شاهد لنفسه ذاتاً مفارقة، لو جاز إن تتبعض ذات السبعين ألف وجه، لقلنا انها بعضها. ولولا إن هذه الذات حدثت بعد إن لم تكن، لقلنا إنها هي! ولولا اختصاصها ببدنه عند حدوثه، لقلنا إنها لم تحدث! وشاهد في هذه الرتبة ذواتاً، مثل ذاته، لاجسام كانت ثم اضمحلت، ولاجسام لم تزل معه في الوجود، وهي من الكثرة في حد بحيث لا تتناهى إن جاز أن يقال لها كثيرة، أو هي كلها متحدة إن جاز إن يقال لها واحدة. وراى لذاته ولتلك الذوات التي في رتبته من الحسن والبهاء واللذة غير المتناهية، ما لا عين رأت ولا أذن سمعت، ولا خطر على قلب بشر، ولا يصفه الواصفون، ولا يعقله إلا الواصلون العارفون. وشاهد ذواتاً كثيرة مفارقة للمادة كأنها مرايا صدئة، قد ران عليها الخبث، وهي مع ذلك مستدبرة للمرايا الصقيلة التي ارتسمت فيها صورة الشمس، ومولية عنها بوجوهها، وراى لهذه الذوات من القبح والنقص ما لم يقم بباله قط؛ وراها في ألام لا تنقضي، وحسرات لا تنمحي؛ قد أحاط بها سرادق العذاب، وأحرقتها نار الحجاب، ونشرت بمناشير بين الانزعاج والانجذاب. وشاهد هنا ذواتاً سوى هذه المعذبة تلوح ثم تضمحل، وتنعقد ثم تنحل، فتثبت فيها وأنعم النظر إليها، فرأى هولاً عظيماً وخطباً جسيماً، وخلقاً حثيثاً، وأحكاماً بليغة، وتسوية ونفخاً وإنشاء ونسخاً. فما هو إلا إن تثبت قليلاً، فعادت إليه حواسه، وتنبه من حاله تلك التي كانت شبيهة بالغشي، وزلت قدمه عن ذلك المقام، ولاح له العالم المحسوس، وغاب عنه العالم الإلهي: إذ لم يكن اجتماعهما في حال واحدة، إذ الأخرى والدنيا كضرتين، إن أرضيت احدهما أسخطت الأخرى، فان قلت يظهر مما حكيته من هذه المشاهدة، إن الذوات المفارقة إن كانت لجسم دائم الوجود لا يفسد، كالأفلاك، كانت هي دائمة الوجود؛ وان كانت لجسم يؤول إلى الفساد كالحيوان الناطق، فسدت هي واضمحلت وتلاشت، حسبما مثلث به في المرايا الانعكاس، فان الصورة لا ثبات لها إلا ثبات بثبات المرآة، فإذا فسدت المرآة صح فساد الصورة واضمحلت هي؛ فأقول لك: ما لأسرع ما نسيت العهد، وحلت عن الربط، ألم نقدم إليك إن مجال العبارة هنا ضيق، وان الألفاظ على كل حال توهم غير الحقيقة وذلك الذي توهمته إنما أوقعك فيه، إن جعلت المثال والممثل به على حكم واحد من جميع الوجوه. ولا ينبغي أن يفعل ذلك في أصناف المخاطبات المعتادة، فكيف ها هنا والشمس ونورها، وصورتها وتشكلها والمرايا والصور الحاصلة فيها، كلها أمور غير مفارقة للأجسام، ولا قوام لها إلا بها وفيها؟ فلذلك افتقرت في وجودها إليها وبطلت ببطلانها. واما الذوات الإلهية، والأرواح الربانية، فانها كلها بريئة عن الأجسام ولواحقها ومنزهة غاية التنزيه عنها، فلا ارتباط ولا تعلق لها بها، وسواء بالإضافة إليها بطلان الأجسام أو ثبوتها، ووجودها أو عدمها؛ وانما ارتباطها وتعلقها بذات الواحد الحق الموجود الواجب الوجود، الذي هو أولها ومبدؤها وسببها وموجدها، وهو يعطيها الدوام ويمدها بالبقاء والتسرمد؛ ولا حاجة بها إلى الأجسام بل الأجسام المحتاجة إليها. ولو جاز عدمها لعدمت الأجسام فانها هي مبديها، كما انه لو جاز إن تعدم ذات الواحد الحق - تعالى وتقدس عن ذلك؛ لا اله إلا هو! - لعدمت هذه الذوات كلها، ولعدمت الأجسام، ولعدم العالم الحسي بآسره، ولم يبق موجود، إذ الكل مرتبط بعضه ببعض. والعالم المحسوس وان كان تابعاً للعالم الإلهي، شبيه الظل له؛ والعالم الإلهي مستغن عنه وبريء منه فانه مع ذلك قد يستحيل فرض عدمه، إذ هو لا محالة تابع للعالم الإلهي، وانما فساده إن يبدل، لا إن يعدم بالجملة، وبذلك نطق الكتاب العزيز حيثما وقع هذا المعنى منه في تسيير الجبال وتسييرها كالعهن والناس كالفراش. وتكوير الشمس والقمر، وتفجيرالبحار يوم تبدل الارض غير الأرض والسموات. فهذا القدر هو الذي امكنني الآن أن أشير إليك به فيما شاهده حي بن يقظان في ذلك المقام الكريم فلا تلتمس الزيادة عليه من جهة الألفاظ فان ذلك كالمعتذر. واما تمام خبره - فسأتلوه عليك إن شاء الله تعالى: وهو انه لما عاد إلى العالم المحسوس، وذلك بعد جولا نه حيث جال، سئم تكاليف الحياة الدنيا، واشتد شوقه إلى الحياة الدنيا، واشتد شوقه إلى الحياة القصوى، فجعل يطلب العود إلى ذلك المقام بالنحو الذي طلبه أولاً حتى وصل إليه بأيسر من السعي الذي وصل به أولاً ودام فيه ثانياً مدة أطول من الأولى. ثم عاد إلى عالم الحس. ثم تكلف الوصول إلى مقامه بعد ذلك فكان ايسر عليه من الأولى والثانية وكان دوامه أطول. وما زال الوصول إلى ذلك المقام الكريم يزيد عليه سهولة، والدوام يزيد فيه طولاً مدة بعد مدة، حتى صار يصل إليه متى شاء، ولا ينفصل عنه إلا متى شاء؛ فكان يلازم مقامه ذلك ولا ينثني عنه إلا لضرورة بدنه التي كان قد قللها، حتى كان لا يوجد اقل منها. وهو في كل ذلك كله يريد إن يريحه الله عز وجل من كل بدنه الذي يدعوه إلى مفارقة مقامه ذلك، فيتخلص إلى لذته تخلصاً دائماً، ويبرأ عما يجده من الألم عند الأعراض عن مقامه ذلك إلى ضرورة البدن. وبقي على حالته تلك حتى أناف على سبعة أسابيع من منشئه وذلك خمسون عاماً. وحينئذ اتفقت له صحبة أسال وكان من قصته معه ما يأتي ذكره بعد هذا إن شاء الله تعالى. ذكروا: إن جزيرة قريبة من الجزيرة التي ولد بها حي بن يقظان على أحد القولين المختلفين على صفة مبدئه، انتقلت إليه ملة من الملل الصحيحة الماخوذه على بعض الأنبياء المتقدمين، صلوات الله عليهم. وكانت ملة محاكية لجميع الموجودات الحقيقية بالأمثال المضروبة التي خيالات تلك الأشياء، وتثبت رسومها في النفوس، حسبما جرت به العادة في مخاطبة الجمهور؛ فما زالت تلك الملة تنتشر بتلك الجزيرة وتقوى وتظهر، حتى قام بها ملكها وحمل الناس على التزامها. وكان قد نشأ بها فتيان من أهل الفضل والخير، يسمى أحدهما أسال والآخر سلامان فتلقيا هذه الملة وقبلاها احسن قبول، واخذ على أنفسهما على بالتزام جميع شرائعها والموظبة على جميع أعمالها، واصطحبا على ذلك. وكانا يتفقهان في بعض الأوقات فيما ورد من ألفاظ تلك الشريعة في صفة الله عز وجل وملائكته، وصفات الميعاد والثواب والعقاب. فأما أسال فكان أشد غوصاً على الباطن، وأكثر عثوراً على المعاني الروحانية واطمع في التأويل. واما سلامان صاحبه فكان أكثر احتفاظاً بالظاهر، وأشد بعداً عن التأويل، وأوقف عن التصرف والتأمل؛ وكلاهما مجد في الأعمال الظاهرة، ومحاسبة النفس، ومجاهدة الهوى. وكان في تلك الشريعة أقوال تحمل عن العزلة والانفراد، وتدل على إن الفوز والنجاة فيهما؛ واقوال أخر تحمل على المعاشرة وملازمة الجماعة. فتعلق أسال بطلب العزلة، ورجح القول فيها لما كان في طباعه من دوام الفكرة، وملازمة العبرة، والغوص على المعاني، وأكثر ما كان يتأتى له أمله من ذلك بالانفراد. وتعلق سلامان بملازمة الجماعة، ورجح القول فيها لما كان في طباعه من الجبن عن الفكرة والتصرف. فكانت ملازمته الجماعة عنده مما يدرأ الوسواس، ويزيل الظنون المعترضة ويعيد من همزات الشياطين. وكان اختلافهما في هذا الرأي سبب افتراقهما. وكان أسال قد سمع عن الجزيرة التي ذكر أن حي بن يقظان تكون بها وعرف ما بها من الخصب والمرافق والهواء المعتدل، وان الانفراد بها يتأتى لملتمسه، فأجمع إن يرتحل إليها ويعتزل الناس بها بقية عمره. فجمع ما كان له من المال، واشترى ببعضه مركباً تحمله إلى تلك الجزيرة، وفرق باقيه على المساكين، وودع صاحبه سلامان وركب متن البحر؛ فحمله الملاحون إلى تلك الجزيرة؛ ووضعوه بساحلها؛ وانفصلوا عنها. فبقي أسال بتلك الجزيرة يعبد الله عز وجل؛ ويعظمه ويقدسه؛ ويفكر في اسمائه الحسنى وصفاته العليا؛ فلا ينقطع خاطره؛ ولا تتكدر فكرته. واذا احتاج إلى غذاء تناول من ثمرات تلك الجزيرة وصيدها ما يسد بها جوعته. وأقام على تلك الحال مدة وهو في أتم غبطة وأعظم أنس بمناجاة ربه. وكان كل يوم يشاهد من ألطافه ومزايا تحفة وتيسره عليه في مطلبه وغذائه ما يثبت يقينه ويقر عينه. وكان في تلك المدة حي بن يقظان شديد الاستغراق في مقاماته الكريمة؛ فكان لا يبرح عن مغارته إلا مرة في الاسبوع لتناول ما سنح من الغذاء، فلذلك لم يعثر عليه أسال لأول وهلة، بل كان يتطوف بأكناف تلك الجزيرة ويسبح في أرجائها، فلا يرى أنسياً ولا يشاهد أثراً فيزيد بذلك أنسه وتنبسط نفسه لما كان قد عزم عليه من التناهي في طلب العزلة والانفراد. إلى إن اتفق في بعض تلك الأوقات إن خرج حي بن يقظان لالتماس غذائه وأسال قد ألم بتلك الجهة، فوقع بصر كل منهما على الآخر. فإما أسال فلم يشك أنه من العباد المنقطعين، وصل تلك الجزيرة لطلب العزلة عن الناس كما وصل هو إليها. فخشي إن هو تعرض له وتعرف به إن يكون سبباً في فساد حاله وعائقاً بينه وبين أمله. واما حي بن يقظان فلم يدر ما هو، لانه لم يره على صورة شيء من الحيوانات التي كان قد عاينها قبل ذلك. وكان عليه مدرعة سوداء من الشعر والصوف، فظن إنها لباس طبيعي. فوقف يتعجب منه ملياً. وولى أسال هارباً منه خيفة أن يشغله عن حاله، فاقتفى حي بن يقظان أثره لما كان في طباعه من البحث عن الحقائق. فلما رآه يشتد في الهرب. خنس عنه وتوارى له، حتى ظن أسال انه قد انصرف عنه وتباعد من تلك الجهة. فشرع أسال في الصلاة والقراءة، والدعاء والبكاء، والتضرع والتواجد، حتى شغله ذلك عن كل شيء. فجعل حي بن يقظان يتقرب منه قليلاً قليلاً، وأسال لا يشعر به حتى دنا منه بحيث يسمع قراءته وتسبيحه، ويشاهد خضوعه وبكائه. فسمع صوتاً حسناً وحروف منظمة، لم يعهد مثلها من شيء من أصناف الحيوان. ونظر إلى أشكاله وتخطيطه فرآه على صورته، وتبين له أن المدرعة التي عليه ليست جلداً طبيعياً، وانما هي لباس متخذ مثل لباسه هو، ولما رأى حسن خشوعه وتضرعه وبكائه لم يشك في انه من الذوات العارفة بالحق؛ فتشوق إليه واراد إن يرى ما عنده، وما الذي أوجب بكاءه وتضرعه؛ فزاد في الدنو منه حتى أحس به أسال؛ فاشتد في العدو، واشتد حي بن يقظان في أثره حتى التحق به - لما كان أعطاه الله من القوة والبسطة في العلم والجسم - فالتزمه وقبض عليه؛ ولم يمكنه من البراح. فلما نظر إليه أسال وهو مكتس بجلود الحيوان ذوات الاوبار؛ وشعره قد طال حتى جلل كثيراً منه، ورأى ما عنده من سرعة العدو وقوة البطش، فرق منه فرقاً شديداً، وجعل يستعطفه ويرغب إليه بكلام لا يفهمه حي بن يقظان ولا يدري ما هو، غير أنه يميز فيه شمائل الجزع. فكان يؤنسه بأصوات كان قد تعلمها من الحيوانات، ويجر يده على رأسه، ويمسح أعطافه. ويتملق إليه، ويظهر البشر والفرح به. حتى سكن جأش أسال وعلم أنه لا يريد به سوءاً. كان أسال قديماً لمحبته في علم التأويل. قد تعلم أكثر الألسن، ومهر فيها. فجعل يكلم حي بن يقظان ويسائله عن شأنه بكل لسان يعلمه ويعالج أفهامه فلا يستطيع، وحي بن يقظان في ذلك كله يتعجب مما يسمع ولا يدري ما هو. غير أنه يظهر له البشر والقبول. فاستغرب كل واحد منهما أمر صاحبه. وكان عند أسال من زاد كان قد اصطحبه من الجزيرة المعمورة، فقربه إلى حي بن يقظان فلم يدر ما هو، لانه لم يكن شاهده قبل ذلك. فأكل منه أسال وأشار إليه ليأكل ففكر حي بن يقظان فيما كان ألزم نفسه من الشروط لتناول الغذاء، ولم يدر اصل ذلك الشيء الذي قدم له ما هو، وهل يجوز له تناوله أم لا! فامتنع عن الآكل. ولم يزل أسال يرغب إليه ويستعطفه. وقد كان اولع به حي بن يقظان فخشي إن دام على امتناعه إن يوحشه، فاقدم على ذلك الزاد وأكل منه. فلما ذاقه واستطابه بدا له سوء ما صنع من نقض عهوده في شرط غذاء، وندم على فعله، وأراد الانفصال عن أسال والإقبال على شأنه من طلب الرجوع إلى مقامه الكريم، فلما تتأت له المشاهدة بسرعة. فرأى أن يقيم مع أسال في عالم الحس حتى يقف على حقيقة شأنه، ولا يبقي في نفسه هو نزوع إليه، وينصرف بعد ذلك إلى مقامه دون إن يشغله شاغل. فالتزم صحبة أسال ولما رأى أسال أيضاً انه لا يتكلم، آمن من غلوائه على دينه، ورجا أن يعلمه الكلام والعلم والدين، فيكون له بذلك أعظم أجر وزلفى عند الله. فشرع أسال في تعليمه الكلام أولاً بأن كان يشير له إلى أعيان الموجودات وينطق بأسمائها ويكرر ذلك عليه ويحمله على النطق، فينطق بها مقترناً بالاشارة، حتى علمه الأسماء كلها، ودرجه قليلاً قليلاً حتى تكلم في أقرب مدة. فجعل أسال يسأله عن شأنه ومن أين صار إلى تلك الجزيرة، فأعلمه حي بن يقظان انه لا يدري لنفسه ابتداء ولا أباً ولا أماً أكثر من الظبية التي ربته، ووصف له شأنه كله وكيف ترقى بالمعرفة، حتى انتهى إلى درجة الوصول. + +فلما سمع أسال منه وصف تلك الحقائق والذوات المفارقة لعالم الحس العارفة بذات الحق عز وجل، ووصفه ذلك الحق تعالى وجل بأوصافه الحسنى، ووصف له ما أمكنه وصفه مما شاهده عند الوصول من لذات الواصلين وألام المحجوبين، لم يشك أسال في أن جميع الأشياء التي وردت في شريعته من أمر الله عز وجل، وملائكته، وكتبه، ورسله، واليوم الآخر، وجنته وناره، هي أمثلة هذه التي شاهدها حي بن يقظان؛ فانفتح بصر قلبه وانقدحت نار خطره وتطابق عنده المعقول والمنقول، وقربت عليه طرق التأويل، ولم يبق عليه مشكل في الشرع إلا تبين له، ولا مغلق إلا انفتح، ولا غامض إلا اتضح، وصار من أولى الألباب. وعند ذلك نظر إلى حي بن يقظان بعين التعظيم والتوقير، وتحقق عنده أنه من أولياء الله الذين لا خوف عليهم ولا هم يحزنون. فالتزم خدمته والاقتداء به بإشارته فيما تعارض عنده من الأعمال الشرعية التي قد تعلمها في ملته. وجعل حي بن يقظان يستفصحه عن أمره وشأنه، فجعل أسال يصف له شأن جزيرته وما فيها من العالم، وكيف كانت سيرهم قبل وصول الملة اليهم. + +وكيف هي الآن بعد وصولها إليهم، وصف له جميع ما ورد في الشريعة من وصف العالم الإلهي، والجنة والنار، والبعث والنشور، والحشر والحساب، والميزان والصراط. ففهم حي بن يقظان ذلك كله ولم ير فيه شيء على خلاف ما شاهده في مقامه الكريم. فعلم أن الذي وصف ذلك وجاء به محق في وصفه، صادق في قوله، ورسول من عند ربه؛ فأمن به وصدقه وشهد برسالته. + +ثم جاء يسأله عما جاء به من الفرائض، ووضعه من العبادات؛ فوصف له الصلاة والزكاة، والصيام والحج، وما أشبهها من الأعمال الظاهرة؛ فتلقى ذلك والتزمه، وأخذ نفسه بأدائه امتثالاً للآمر الذي صح عنده صدق قوله. + +إلا انه بقي في نفسه أمران كان يتعجب منهما ولا يدري وجه الحكمة فيهما: أحدهما - لما ضرب هذا الرسول الأمثال للناس في أكثر ما وصفه من أمر العالم الإلهي، وأضرب عن المكاشفة حتى وقع الناس في أمر عظيم من التجسيم، واعتقاد أشياء في ذات الحق هو منزه عنها وبريء منها؟ وكذلك في أمر الثواب والعقاب! والآمر الآخر - لم اقتصر على هذه الفرائض ووظائف العبادات وأباح الاقتناء للأموال والتوسع في المأكل، حتى بفرغ الناس بالاشتغال بالباطل، والأعراض عن الحق؟ وكان رأيه هو لا يتناول أحد شيئاً إلا ما يقيم به من الرمق؛ واما الأموال فلم تكن لها عنده معنى. + +وكان يرى ما في الشرع من الأحكام في أمر الأموال: كالزكاة وتشعبها، والبيوع والربا والحدود والعقوبات، فكان يستغرب هذا كله ويراه تطويلاً، ويقول: إن الناس لو فهموا الآمر على حقيقته لاعرضوا عن هذه البواطل، وأقبلو على الحق، واستغنوا عن هذا كله، ولم يكن لاحد اختصاص بمال يسأل عن زكاته، أو تقطع الأيدي على سرقته، أو تذهب النفوس على أخذه مجاهرة. + +وكان الذي أوقعه في ذلك ظنه، أن الناس كلهم ذوو فطر فائقة، وأذهان ثاقبة، ونفوس عازمة، ولم يكن يدري ما هم عليه من البلادة والنقص، وسوء الرأي وضعف العزم، وأنهم كالأنعام بل هم أضل سبيلاً. + +فلما اشتد إشفاقه على الناس، وطمع أن تكون نجاتهم على يديه، حدثت له النية في الوصول إليهم، وإيضاح الحق لديهم، وتبييه لهم ففاوض في ذلك صاحبه أسال وسأله: هل تمكنه حيلة في الوصول اليهم؟ فأعلمه بما هم فيه من نقص الفطرة والأعراض عن آمر الله فلم يتأت له فهم ذلك، وبقي في نفسه تعلق بما كان قد أمله. + +وطمع أسال أيضاً أن يهدي الله على يديه طائفة من معارفه المريدين الذين كانوا أقرب من التخلص من سواهم، فساعده على رأيه، ورأيا أن يلتزما ساحل البحر ولا يفارقاه ليلاً ولا نهاراً، لعل الله إن السني لهما عبور البحر فالتزما ذلك وابتهلا الله تعالى أن يهيء لهما من أمرهما رشدأً. + +فكان من أمر الله عز وجل أن سفينة ضلت مسلكها، ودفعها الرياح وتلاطم الأمواج إلى ساحلها. فلما قربت من البر رأى أهلها الرجلين على الشاطئ. + +فدنوا منها فكلمهم أسال وسألهم أن يحملوهما معهم، فأجابوهما إلى ذلك، وأدخلوهما السفينة، فأرسل الله إليهم ريحاً رخاء حملت السفينة في أقرب مدة إلى الجزيرة التي أملاها فنزلا بها، ودخلا مدينتها، واجتمع أصحاب أسال به، فعرفهم شأن حي بن يقظان، فاشتملوا عليه شديداً وأكبروا آمره، واجتمعوا إليه واعظموه وبجلوه، وأعلمه أسال أن تلك الطائفة هم أن تلك الطائفة هم أقرب إلى الفهم والذكاء من جميع الناس، وانه إن عجز عن تعليمهم فهو عن تعليم الجمهور أعجز. + +وكان رأس تلك الجزيرة سلامان وهو صاحب أسال الذي كان يراه ملازمة الجماعة، ويقول بتحريم العزلة، فشرع حي بن يقظان في تعليمهم وبث أسرار الحكمة إليهم. + +فما هو إلا أن ترقى عن الظاهر قليلاً وأخذ في وصف ما سبق إلى فهمهم خلافه، فجعلوا ينقبضون منه وتشمئز نفوسهم مما يأتي به، ويتسخطونه بقلوبهم، وان اظهروا له الرضا في وجهه اكراماً لغربته فيهم، ومراعاة لحق صاحبهم أسال! وما زال حي بن يقظان يستلطفهم ليلاً ونهاراً، ويبن لهم الحق سراً وجهاراً، فلا يزيدهم ذلك إلا نبوأً ونفاراً، مع أنهم كانوا محبين للخير، راغبين في الحق، إلا انهم لنقص فطرتهم كانوا لا يطلبون الحق من طريقة ولا يأخذونه لجهة تحقيقه، ولا يلتمسونه من بابه، بل كانوا لا يريدون معرفته من طريق أربابه. فيأس من أصلاحهم، وانقطع رجائه من صلاحهم لقلة قبولهم. + +وتصفح طبقات الناس بعد ذلك، فرأى كل حزب بما لديهم فرحون، قد اتخذوا ألههم هواهم، ومعبودهم شهواتهم، وتهالكوا في جميع حطام الدنيا، ألهاهم التكاثر حتى زاروا المقابر، لا تنجح فيهم الموعظة ولا تعمل فيهم الكلمة الحسنة، ولا يزدادون بالجدل إلا إصرارا. + +واما الحكمة فلا سبيل لهم إليها، ولا حظ لهم منه، قد غمرتهم الجهالة وران على قلوبهم ما يكسبون ختم الله على قلوبهم وعلى سمعهم وعلى أبصارهم غشاوةً ولهم عذاب عظيم. + +فلما رأى سرادق العذاب قد أحاط بهم، الظالمات الحجب قد تغشتهم، والكل منهم - إلا اليسير - لا يتمسكون من ملتهم إلا بالدنيا، وقد نبذوا أعمالهم على خفتها وسهولتها وراء ظهورهم، واشتروا بها ثمناً قليلاً، وألهاهم عن ذكر الله تعالى التجارة والبيع، ولم يخافوا يوماً تنقلب فيه القلوب والابصار، لأن له وتحقق على القطع، أن مخاطبتهم بطريق المكاشفة لا تمكن وأن تكليفهم من العمل فوق هذا القدر لا يتفق، وأن حظ أكثر الجمهور من الانتفاع بالشريعة إنما هو في حياتهم الدنيا لا يستقيم له معاشه، ولا يتعدى عليه سواه فيما اختص هو به، وانه لا يفوز منه بالسعادة الأخروية إلا الشاذ النادر، وهو من أراد حرث الآخرة وسعى لها سعياً وهو مؤمن. + +وأما من طغى وأثر الحياة الدنيا فان الجحيم هي المأوى، وأي تعب أعظم وشقاوةً أطم ممن إذا تصفحت أعماله من وقت انتباهه من نومه إلى حين رجوعه إلى الكره لا تجد منها شيئاً إلا وهو يلتمس به تحصيل غايةً من هذه الأمور المحسوسة الخسيسة آما مال يجمعه أو لذة ينالها أو شهوة يقضيها أو غيطاً يتشفه به أو جاه يحرزه أو عمل من أعمال الشرع يتزين به أو يدافع عن رقبته، وهي كلها ظلمات بعضها فوق بعض في بحر لجي وان منكم إلا واردها كان على ربك حتماً مقضياً. + +فلما فهم أحوال الناس وان أكثرهم بمنزلة الحيوان غير الناطق علم أن الحكمة كلها والهداية والتوفيق فيما نطقت به الرسل ووردت به الشريعة لا يمكن غير ذلك ولا يحتمل المزيد عليه ولكل عمل رجال وكل ميسر لما خلق له "بسم الله الرحمن الرحيم" سنة الله التي قد خلت من قبل ولن تجد لسنة الله تبديلاً صدق الله العظيم. + +فانصرف إلى سلامان وأصحابه، فاعتذر عما تكلم به معه وتبرأ إليهم منه وأعلمهم أنه قد رآه مثل رأيهم واهتدى بمثل هديهم، وأوصاهم بملازمة ما هم عليه من التزام حدود الشرع والأعمال الظاهرة مقلة الخوض فيما لا يعنيهم، والإيمان بالمتشابهات والتسليم لها، والأعراض عن البدع والأهواء والاقتداء بالسلف الصالح والترك لمحدثات الأمور، وأمرهم بمجانبة ما عليه جمهور العوام من إهمال الشريعة والإقبال على الدنيا، وحذرهم عنه غاية التحذير، وعلم هو وصاحبه أسال أن هذه الطائفة المريدة القاصرة لا نجاة لها إلا بهذا الطريق، وأنها إن رفعت عنه إلى يفاع الاستبصار اختل ما هي عليه ولم يمكنها أن تلحق بدرجة السعداء وتذبذبت وانتكست وساءت عاقبتها. وان هي دامت على ما هي عليه حتى يوافيها اليقين فازت بالآمن وكانت من أصحاب اليمين، والسابقون السابقون أولئك المقربون. فو دعاهم وانفصلا عنهم وتلطفا في العود إلى جزيرتهما حتى يسر الله عز وجل عليهما العبور إليها. وطلب حي بن يقظان مقامه الكريم بالنحو الذي طلبه أولاً حتى عاد إليه، واقتدى به أسال حتى قرب من أو كاد وعبدا الله في تلك الجزيرة حتى أتاهما اليقين. هذا - أيدنا الله وأياك بروح منه - ما كان من نبأ حي بن يقظان وأسال وسلامان وقد أشتمل على حظ من الكلام لا يوجد في كتاب ولا يسمع في معتاد خطاب، وهو من العلم المكنون الذي لا يقبله إلا أهل المعرفة بالله، ولا يجهله إلا أهل الغرة بالله. وقد خالفنا فيه طريق السلف الصالح في الضنانا به والشح عليه. إلا أن الذي سهل علينا إفشاء هذا السر وهتك الحجاب، ما ظهر في زماننا من أراء فاسده نبغت بها متفلسفة العصر وصرحت بها، حتى انتشرت في البلدان وعما ضررها وخشينا على الضعفاء الذين اطرحوا تقليد الأنبياء صلوات الله عليهم، وأرادوا تقليد السفهاء والأغبياء أن يظنوا أن تلك الآراء هي الأسرار المضنون بها على غير أهلها، فيزيد بذلك حبهم فيها وولعهم فيها. فرأينا أن نلمح إليهم بطرف من سر الأسرار لنجتذبهم إلى جانب التحقيق، ثم نصدهم عن ذلك الطريق. ولم نخل مع ذلك ما أودعناه هذه الأوراق اليسيره من الأسرار عن حجاب رقيق وستر لطيف ينتهك سريعاً لمن هو أهله، ويتكاثف لمن لا يستحق تجاوزه حتى لا يتعداه. وأنا أسئل إخواني الواقفين على هذا الكلام، أن يقبلو عذري فيما تسائلت في تبينه وتسامحت في تثبيته، فلم أفعل ذلك إلا لأني تسمنت شواهق يزل الطرف عن مرآها. وأردت تقريب الكلام فيها على وجه الترغيب والتشويق في دخول الطريق. وأسأل الله التجاوز والعفو، وأن يوردنا من المعرفة به الصفو، إنه منعم كريم. والسلام عليك أيها الأخ المفترض إسعافه ورحمت الله وبركاته. +EOT; +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/at_AT/Payment.php b/vendor/fzaninotto/faker/src/Faker/Provider/at_AT/Payment.php new file mode 100644 index 0000000..799e864 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/at_AT/Payment.php @@ -0,0 +1,31 @@ +generator->parse(static::randomElement(static::$lastNameFormat)); + } + + public static function lastNameMale() + { + return static::randomElement(static::$lastNameMale); + } + + public static function lastNameFemale() + { + return static::randomElement(static::$lastNameFemale); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/bg_BG/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/bg_BG/PhoneNumber.php new file mode 100644 index 0000000..e5ec042 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/bg_BG/PhoneNumber.php @@ -0,0 +1,20 @@ +generator->parse($format)); + } + + /** + * Generates valid czech IČO + * + * @see http://phpfashion.com/jak-overit-platne-ic-a-rodne-cislo + * @return string + */ + public function ico() + { + $ico = static::numerify('#######'); + $split = str_split($ico); + $prod = 0; + foreach (array(8, 7, 6, 5, 4, 3, 2) as $i => $p) { + $prod += $p * $split[$i]; + } + $mod = $prod % 11; + if ($mod === 0 || $mod === 10) { + return "{$ico}1"; + } elseif ($mod === 1) { + return "{$ico}0"; + } + + return $ico . (11 - $mod); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/DateTime.php b/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/DateTime.php new file mode 100644 index 0000000..4bd1508 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/DateTime.php @@ -0,0 +1,61 @@ +format('w')]; + } + + /** + * @param \DateTime|int|string $max maximum timestamp used as random end limit, default to "now" + * @return string + * @example '2' + */ + public static function dayOfMonth($max = 'now') + { + return static::dateTime($max)->format('j'); + } + + /** + * Full date with inflected month + * @return string + * @example '16. listopadu 2003' + */ + public function formattedDate() + { + $format = static::randomElement(static::$formattedDateFormat); + + return $this->generator->parse($format); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Internet.php new file mode 100644 index 0000000..d0d993d --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/Internet.php @@ -0,0 +1,9 @@ +generator->parse(static::randomElement(static::$lastNameFormat)); + } + + public static function lastNameMale() + { + return static::randomElement(static::$lastNameMale); + } + + public static function lastNameFemale() + { + return static::randomElement(static::$lastNameFemale); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/PhoneNumber.php new file mode 100644 index 0000000..90495df --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/cs_CZ/PhoneNumber.php @@ -0,0 +1,14 @@ + + */ +class Address extends \Faker\Provider\Address +{ + /** + * @var array Danish city suffixes. + */ + protected static $citySuffix = array( + 'sted', 'bjerg', 'borg', 'rød', 'lund', 'by', + ); + + /** + * @var array Danish street suffixes. + */ + protected static $streetSuffix = array( + 'vej', 'gade', 'skov', 'shaven', + ); + + /** + * @var array Danish street word suffixes. + */ + protected static $streetSuffixWord = array( + 'Vej', 'Gade', 'Allé', 'Boulevard', 'Plads', 'Have', + ); + + /** + * @var array Danish building numbers. + */ + protected static $buildingNumber = array( + '%##', '%#', '%#', '%', '%', '%', '%?', '% ?', + ); + + /** + * @var array Danish building level. + */ + protected static $buildingLevel = array( + 'st.', '%.', '%. sal.', + ); + + /** + * @var array Danish building sides. + */ + protected static $buildingSide = array( + 'tv.', 'th.', + ); + + /** + * @var array Danish zip code. + */ + protected static $postcode = array( + '%###' + ); + + /** + * @var array Danish cities. + */ + protected static $cityNames = array( + 'Aabenraa', 'Aabybro', 'Aakirkeby', 'Aalborg', 'Aalestrup', 'Aars', 'Aarup', 'Agedrup', 'Agerbæk', 'Agerskov', + 'Albertslund', 'Allerød', 'Allinge', 'Allingåbro', 'Almind', 'Anholt', 'Ansager', 'Arden', 'Asaa', 'Askeby', + 'Asnæs', 'Asperup', 'Assens', 'Augustenborg', 'Aulum', 'Auning', 'Bagenkop', 'Bagsværd', 'Balle', 'Ballerup', + 'Bandholm', 'Barrit', 'Beder', 'Bedsted', 'Bevtoft', 'Billum', 'Billund', 'Bindslev', 'Birkerød', 'Bjerringbro', + 'Bjert', 'Bjæverskov', 'Blokhus', 'Blommenslyst', 'Blåvand', 'Boeslunde', 'Bogense', 'Bogø', 'Bolderslev', 'Bording', + 'Borre', 'Borup', 'Brøndby', 'Brabrand', 'Bramming', 'Brande', 'Branderup', 'Bredebro', 'Bredsten', 'Brenderup', + 'Broager', 'Broby', 'Brovst', 'Bryrup', 'Brædstrup', 'Strand', 'Brønderslev', 'Brønshøj', 'Brørup', 'Bække', + 'Bækmarksbro', 'Bælum', 'Børkop', 'Bøvlingbjerg', 'Charlottenlund', 'Christiansfeld', 'Dalby', 'Dalmose', + 'Dannemare', 'Daugård', 'Dianalund', 'Dragør', 'Dronninglund', 'Dronningmølle', 'Dybvad', 'Dyssegård', 'Ebberup', + 'Ebeltoft', 'Egernsund', 'Egtved', 'Egå', 'Ejby', 'Ejstrupholm', 'Engesvang', 'Errindlev', 'Erslev', 'Esbjerg', + 'Eskebjerg', 'Eskilstrup', 'Espergærde', 'Faaborg', 'Fanø', 'Farsø', 'Farum', 'Faxe', 'Ladeplads', 'Fejø', + 'Ferritslev', 'Fjenneslev', 'Fjerritslev', 'Flemming', 'Fredensborg', 'Fredericia', 'Frederiksberg', + 'Frederikshavn', 'Frederikssund', 'Frederiksværk', 'Frørup', 'Frøstrup', 'Fuglebjerg', 'Føllenslev', 'Føvling', + 'Fårevejle', 'Fårup', 'Fårvang', 'Gadbjerg', 'Gadstrup', 'Galten', 'Gandrup', 'Gedser', 'Gedsted', 'Gedved', 'Gelsted', + 'Gentofte', 'Gesten', 'Gilleleje', 'Gislev', 'Gislinge', 'Gistrup', 'Give', 'Gjerlev', 'Gjern', 'Glamsbjerg', + 'Glejbjerg', 'Glesborg', 'Glostrup', 'Glumsø', 'Gram', 'Gredstedbro', 'Grenaa', 'Greve', 'Grevinge', 'Grindsted', + 'Græsted', 'Gråsten', 'Gudbjerg', 'Sydfyn', 'Gudhjem', 'Gudme', 'Guldborg', 'Gørding', 'Gørlev', 'Gørløse', + 'Haderslev', 'Haderup', 'Hadsten', 'Hadsund', 'Hals', 'Hammel', 'Hampen', 'Hanstholm', 'Harboøre', 'Harlev', 'Harndrup', + 'Harpelunde', 'Hasle', 'Haslev', 'Hasselager', 'Havdrup', 'Havndal', 'Hedehusene', 'Hedensted', 'Hejls', 'Hejnsvig', + 'Hellebæk', 'Hellerup', 'Helsinge', 'Helsingør', 'Hemmet', 'Henne', 'Herfølge', 'Herlev', 'Herlufmagle', 'Herning', + 'Hesselager', 'Hillerød', 'Hinnerup', 'Hirtshals', 'Hjallerup', 'Hjerm', 'Hjortshøj', 'Hjørring', 'Hobro', 'Holbæk', + 'Holeby', 'Holmegaard', 'Holstebro', 'Holsted', 'Holte', 'Horbelev', 'Hornbæk', 'Hornslet', 'Hornsyld', 'Horsens', + 'Horslunde', 'Hovborg', 'Hovedgård', 'Humble', 'Humlebæk', 'Hundested', 'Hundslund', 'Hurup', 'Hvalsø', 'Hvide', + 'Sande', 'Hvidovre', 'Højbjerg', 'Højby', 'Højer', 'Højslev', 'Høng', 'Hørning', 'Hørsholm', 'Hørve', 'Hårlev', + 'Idestrup', 'Ikast', 'Ishøj', 'Janderup', 'Vestj', 'Jelling', 'Jerslev', 'Sjælland', 'Jerup', 'Jordrup', 'Juelsminde', + 'Jyderup', 'Jyllinge', 'Jystrup', 'Midtsj', 'Jægerspris', 'Kalundborg', 'Kalvehave', 'Karby', 'Karise', 'Karlslunde', + 'Karrebæksminde', 'Karup', 'Kastrup', 'Kerteminde', 'Kettinge', 'Kibæk', 'Kirke', 'Hyllinge', 'Såby', 'Kjellerup', + 'Klampenborg', 'Klarup', 'Klemensker', 'Klippinge', 'Klovborg', 'Knebel', 'Kokkedal', 'Kolding', 'Kolind', 'Kongens', + 'Lyngby', 'Kongerslev', 'Korsør', 'Kruså', 'Kvistgård', 'Kværndrup', 'København', 'Køge', 'Langebæk', 'Langeskov', + 'Langå', 'Lejre', 'Lemming', 'Lemvig', 'Lille', 'Skensved', 'Lintrup', 'Liseleje', 'Lundby', 'Lunderskov', 'Lynge', + 'Lystrup', 'Læsø', 'Løgstrup', 'Løgstør', 'Løgumkloster', 'Løkken', 'Løsning', 'Låsby', 'Malling', 'Mariager', + 'Maribo', 'Marslev', 'Marstal', 'Martofte', 'Melby', 'Mern', 'Mesinge', 'Middelfart', 'Millinge', 'Morud', 'Munke', + 'Bjergby', 'Munkebo', 'Møldrup', 'Mørke', 'Mørkøv', 'Måløv', 'Mårslet', 'Nakskov', 'Nexø', 'Nibe', 'Nimtofte', + 'Nordborg', 'Nyborg', 'Nykøbing', 'Nyrup', 'Nysted', 'Nærum', 'Næstved', 'Nørager', 'Nørre', 'Aaby', 'Alslev', + 'Asmindrup', 'Nebel', 'Snede', 'Nørreballe', 'Nørresundby', 'Odder', 'Odense', 'Oksbøl', 'Otterup', 'Oure', 'Outrup', + 'Padborg', 'Pandrup', 'Præstø', 'Randbøl', 'Randers', 'Ranum', 'Rask', 'Mølle', 'Redsted', 'Regstrup', 'Ribe', 'Ringe', + 'Ringkøbing', 'Ringsted', 'Risskov', 'Roskilde', 'Roslev', 'Rude', 'Rudkøbing', 'Ruds', 'Vedby', 'Rungsted', 'Kyst', + 'Rynkeby', 'Ryomgård', 'Ryslinge', 'Rødby', 'Rødding', 'Rødekro', 'Rødkærsbro', 'Rødovre', 'Rødvig', 'Stevns', + 'Rønde', 'Rønne', 'Rønnede', 'Rørvig', 'Sabro', 'Sakskøbing', 'Saltum', 'Samsø', 'Sandved', 'Sejerø', 'Silkeborg', + 'Sindal', 'Sjællands', 'Odde', 'Sjølund', 'Skagen', 'Skals', 'Skamby', 'Skanderborg', 'Skibby', 'Skive', 'Skjern', + 'Skodsborg', 'Skovlunde', 'Skælskør', 'Skærbæk', 'Skævinge', 'Skødstrup', 'Skørping', 'Skårup', 'Slagelse', + 'Slangerup', 'Smørum', 'Snedsted', 'Snekkersten', 'Snertinge', 'Solbjerg', 'Solrød', 'Sommersted', 'Sorring', 'Sorø', + 'Spentrup', 'Spjald', 'Sporup', 'Spøttrup', 'Stakroge', 'Stege', 'Stenderup', 'Stenlille', 'Stenløse', 'Stenstrup', + 'Stensved', 'Stoholm', 'Jyll', 'Stokkemarke', 'Store', 'Fuglede', 'Heddinge', 'Merløse', 'Storvorde', 'Stouby', + 'Strandby', 'Struer', 'Strøby', 'Stubbekøbing', 'Støvring', 'Suldrup', 'Sulsted', 'Sunds', 'Svaneke', 'Svebølle', + 'Svendborg', 'Svenstrup', 'Svinninge', 'Sydals', 'Sæby', 'Søborg', 'Søby', 'Ærø', 'Søllested', 'Sønder', 'Felding', + 'Sønderborg', 'Søndersø', 'Sørvad', 'Taastrup', 'Tappernøje', 'Tarm', 'Terndrup', 'Them', 'Thisted', 'Thorsø', + 'Thyborøn', 'Thyholm', 'Tikøb', 'Tilst', 'Tinglev', 'Tistrup', 'Tisvildeleje', 'Tjele', 'Tjæreborg', 'Toftlund', + 'Tommerup', 'Toreby', 'Torrig', 'Tranbjerg', 'Tranekær', 'Trige', 'Trustrup', 'Tune', 'Tureby', 'Tylstrup', 'Tølløse', + 'Tønder', 'Tørring', 'Tårs', 'Ugerløse', 'Uldum', 'Ulfborg', 'Ullerslev', 'Ulstrup', 'Vadum', 'Valby', 'Vallensbæk', + 'Vamdrup', 'Vandel', 'Vanløse', 'Varde', 'Vedbæk', 'Veflinge', 'Vejby', 'Vejen', 'Vejers', 'Vejle', 'Vejstrup', + 'Veksø', 'Vemb', 'Vemmelev', 'Vesløs', 'Vestbjerg', 'Vester', 'Skerninge', 'Vesterborg', 'Vestervig', 'Viborg', 'Viby', + 'Videbæk', 'Vildbjerg', 'Vils', 'Vinderup', 'Vipperød', 'Virum', 'Vissenbjerg', 'Viuf', 'Vodskov', 'Vojens', 'Vonge', + 'Vorbasse', 'Vordingborg', 'Væggerløse', 'Værløse', 'Ærøskøbing', 'Ølgod', 'Ølsted', 'Ølstykke', 'Ørbæk', + 'Ørnhøj', 'Ørsted', 'Djurs', 'Østbirk', 'Øster', 'Assels', 'Ulslev', 'Østermarie', 'Østervrå', 'Åbyhøj', + 'Ålbæk', 'Ålsgårde', 'Århus', 'Årre', 'Årslev', 'Haarby', 'Nivå', 'Rømø', 'Omme', 'Vrå', 'Ørum', + ); + + /** + * @var array Danish municipalities, called 'kommuner' in danish. + */ + protected static $kommuneNames = array( + 'København', 'Frederiksberg', 'Ballerup', 'Brøndby', 'Dragør', 'Gentofte', 'Gladsaxe', 'Glostrup', 'Herlev', + 'Albertslund', 'Hvidovre', 'Høje Taastrup', 'Lyngby-Taarbæk', 'Rødovre', 'Ishøj', 'Tårnby', 'Vallensbæk', + 'Allerød', 'Fredensborg', 'Helsingør', 'Hillerød', 'Hørsholm', 'Rudersdal', 'Egedal', 'Frederikssund', 'Greve', + 'Halsnæs', 'Roskilde', 'Solrød', 'Gribskov', 'Odsherred', 'Holbæk', 'Faxe', 'Kalundborg', 'Ringsted', 'Slagelse', + 'Stevns', 'Sorø', 'Lejre', 'Lolland', 'Næstved', 'Guldborgsund', 'Vordingborg', 'Bornholm', 'Middelfart', + 'Christiansø', 'Assens', 'Faaborg-Midtfyn', 'Kerteminde', 'Nyborg', 'Odense', 'Svendborg', 'Nordfyns', 'Langeland', + 'Ærø', 'Haderslev', 'Billund', 'Sønderborg', 'Tønder', 'Esbjerg', 'Fanø', 'Varde', 'Vejen', 'Aabenraa', + 'Fredericia', 'Horsens', 'Kolding', 'Vejle', 'Herning', 'Holstebro', 'Lemvig', 'Struer', 'Syddjurs', 'Furesø', + 'Norddjurs', 'Favrskov', 'Odder', 'Randers', 'Silkeborg', 'Samsø', 'Skanderborg', 'Aarhus', 'Ikast-Brande', + 'Ringkøbing-Skjern', 'Hedensted', 'Morsø', 'Skive', 'Thisted', 'Viborg', 'Brønderslev', 'Frederikshavn', + 'Vesthimmerlands', 'Læsø', 'Rebild', 'Mariagerfjord', 'Jammerbugt', 'Aalborg', 'Hjørring', 'Køge', + ); + + /** + * @var array Danish regions. + */ + protected static $regionNames = array( + 'Region Nordjylland', 'Region Midtjylland', 'Region Syddanmark', 'Region Hovedstaden', 'Region Sjælland', + ); + + /** + * @link https://github.com/umpirsky/country-list/blob/master/country/cldr/da_DK/country.php + * + * @var array Some countries in danish. + */ + protected static $country = array( + 'Andorra', 'Forenede Arabiske Emirater', 'Afghanistan', 'Antigua og Barbuda', 'Anguilla', 'Albanien', 'Armenien', + 'Hollandske Antiller', 'Angola', 'Antarktis', 'Argentina', 'Amerikansk Samoa', 'Østrig', 'Australien', 'Aruba', + 'Åland', 'Aserbajdsjan', 'Bosnien-Hercegovina', 'Barbados', 'Bangladesh', 'Belgien', 'Burkina Faso', 'Bulgarien', + 'Bahrain', 'Burundi', 'Benin', 'Saint Barthélemy', 'Bermuda', 'Brunei Darussalam', 'Bolivia', 'Brasilien', 'Bahamas', + 'Bhutan', 'Bouvetø', 'Botswana', 'Hviderusland', 'Belize', 'Canada', 'Cocosøerne', 'Congo-Kinshasa', + 'Centralafrikanske Republik', 'Congo', 'Schweiz', 'Elfenbenskysten', 'Cook-øerne', 'Chile', 'Cameroun', 'Kina', + 'Colombia', 'Costa Rica', 'Serbien og Montenegro', 'Cuba', 'Kap Verde', 'Juleøen', 'Cypern', 'Tjekkiet', 'Tyskland', + 'Djibouti', 'Danmark', 'Dominica', 'Den Dominikanske Republik', 'Algeriet', 'Ecuador', 'Estland', 'Egypten', + 'Vestsahara', 'Eritrea', 'Spanien', 'Etiopien', 'Finland', 'Fiji-øerne', 'Falklandsøerne', + 'Mikronesiens Forenede Stater', 'Færøerne', 'Frankrig', 'Gabon', 'Storbritannien', 'Grenada', 'Georgien', + 'Fransk Guyana', 'Guernsey', 'Ghana', 'Gibraltar', 'Grønland', 'Gambia', 'Guinea', 'Guadeloupe', 'Ækvatorialguinea', + 'Grækenland', 'South Georgia og De Sydlige Sandwichøer', 'Guatemala', 'Guam', 'Guinea-Bissau', 'Guyana', + 'SAR Hongkong', 'Heard- og McDonald-øerne', 'Honduras', 'Kroatien', 'Haiti', 'Ungarn', 'Indonesien', 'Irland', + 'Israel', 'Isle of Man', 'Indien', 'Det Britiske Territorium i Det Indiske Ocean', 'Irak', 'Iran', 'Island', + 'Italien', 'Jersey', 'Jamaica', 'Jordan', 'Japan', 'Kenya', 'Kirgisistan', 'Cambodja', 'Kiribati', 'Comorerne', + 'Saint Kitts og Nevis', 'Nordkorea', 'Sydkorea', 'Kuwait', 'Caymanøerne', 'Kasakhstan', 'Laos', 'Libanon', + 'Saint Lucia', 'Liechtenstein', 'Sri Lanka', 'Liberia', 'Lesotho', 'Litauen', 'Luxembourg', 'Letland', 'Libyen', + 'Marokko', 'Monaco', 'Republikken Moldova', 'Montenegro', 'Saint Martin', 'Madagaskar', 'Marshalløerne', + 'Republikken Makedonien', 'Mali', 'Myanmar', 'Mongoliet', 'SAR Macao', 'Nordmarianerne', 'Martinique', + 'Mauretanien', 'Montserrat', 'Malta', 'Mauritius', 'Maldiverne', 'Malawi', 'Mexico', 'Malaysia', 'Mozambique', + 'Namibia', 'Ny Caledonien', 'Niger', 'Norfolk Island', 'Nigeria', 'Nicaragua', 'Holland', 'Norge', 'Nepal', 'Nauru', + 'Niue', 'New Zealand', 'Oman', 'Panama', 'Peru', 'Fransk Polynesien', 'Papua Ny Guinea', 'Filippinerne', 'Pakistan', + 'Polen', 'Saint Pierre og Miquelon', 'Pitcairn', 'Puerto Rico', 'De palæstinensiske områder', 'Portugal', 'Palau', + 'Paraguay', 'Qatar', 'Reunion', 'Rumænien', 'Serbien', 'Rusland', 'Rwanda', 'Saudi-Arabien', 'Salomonøerne', + 'Seychellerne', 'Sudan', 'Sverige', 'Singapore', 'St. Helena', 'Slovenien', 'Svalbard og Jan Mayen', 'Slovakiet', + 'Sierra Leone', 'San Marino', 'Senegal', 'Somalia', 'Surinam', 'Sao Tome og Principe', 'El Salvador', 'Syrien', + 'Swaziland', 'Turks- og Caicosøerne', 'Tchad', 'Franske Besiddelser i Det Sydlige Indiske Ocean', 'Togo', + 'Thailand', 'Tadsjikistan', 'Tokelau', 'Timor-Leste', 'Turkmenistan', 'Tunesien', 'Tonga', 'Tyrkiet', + 'Trinidad og Tobago', 'Tuvalu', 'Taiwan', 'Tanzania', 'Ukraine', 'Uganda', 'De Mindre Amerikanske Oversøiske Øer', + 'USA', 'Uruguay', 'Usbekistan', 'Vatikanstaten', 'St. Vincent og Grenadinerne', 'Venezuela', + 'De britiske jomfruøer', 'De amerikanske jomfruøer', 'Vietnam', 'Vanuatu', 'Wallis og Futunaøerne', 'Samoa', + 'Yemen', 'Mayotte', 'Sydafrika', 'Zambia', 'Zimbabwe', + ); + + /** + * @var array Danish city format. + */ + protected static $cityFormats = array( + '{{cityName}}', + ); + + /** + * @var array Danish street's name formats. + */ + protected static $streetNameFormats = array( + '{{lastName}}{{streetSuffix}}', + '{{middleName}}{{streetSuffix}}', + '{{lastName}} {{streetSuffixWord}}', + '{{middleName}} {{streetSuffixWord}}', + ); + + /** + * @var array Danish street's address formats. + */ + protected static $streetAddressFormats = array( + '{{streetName}} {{buildingNumber}}', + '{{streetName}} {{buildingNumber}}, {{buildingLevel}}', + '{{streetName}} {{buildingNumber}}, {{buildingLevel}} {{buildingSide}}', + ); + + /** + * @var array Danish address format. + */ + protected static $addressFormats = array( + "{{streetAddress}}\n{{postcode}} {{city}}", + ); + + /** + * Randomly return a real city name. + * + * @return string + */ + public static function cityName() + { + return static::randomElement(static::$cityNames); + } + + /** + * Randomly return a suffix word. + * + * @return string + */ + public static function streetSuffixWord() + { + return static::randomElement(static::$streetSuffixWord); + } + + /** + * Randomly return a building number. + * + * @return string + */ + public static function buildingNumber() + { + return static::toUpper(static::bothify(static::randomElement(static::$buildingNumber))); + } + + /** + * Randomly return a building level. + * + * @return string + */ + public static function buildingLevel() + { + return static::numerify(static::randomElement(static::$buildingLevel)); + } + + /** + * Randomly return a side of the building. + * + * @return string + */ + public static function buildingSide() + { + return static::randomElement(static::$buildingSide); + } + + /** + * Randomly return a real municipality name, called 'kommune' in danish. + * + * @return string + */ + public static function kommune() + { + return static::randomElement(static::$kommuneNames); + } + + /** + * Randomly return a real region name. + * + * @return string + */ + public static function region() + { + return static::randomElement(static::$regionNames); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Company.php b/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Company.php new file mode 100644 index 0000000..b9f289c --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Company.php @@ -0,0 +1,70 @@ + + */ +class Company extends \Faker\Provider\Company +{ + /** + * @var array Danish company name formats. + */ + protected static $formats = array( + '{{lastName}} {{companySuffix}}', + '{{lastName}} {{companySuffix}}', + '{{lastName}} {{companySuffix}}', + '{{firstname}} {{lastName}} {{companySuffix}}', + '{{middleName}} {{companySuffix}}', + '{{middleName}} {{companySuffix}}', + '{{middleName}} {{companySuffix}}', + '{{firstname}} {{middleName}} {{companySuffix}}', + '{{lastName}} & {{lastName}} {{companySuffix}}', + '{{lastName}} og {{lastName}} {{companySuffix}}', + '{{lastName}} & {{lastName}} {{companySuffix}}', + '{{lastName}} og {{lastName}} {{companySuffix}}', + '{{middleName}} & {{middleName}} {{companySuffix}}', + '{{middleName}} og {{middleName}} {{companySuffix}}', + '{{middleName}} & {{lastName}}', + '{{middleName}} og {{lastName}}', + ); + + /** + * @var array Company suffixes. + */ + protected static $companySuffix = array('ApS', 'A/S', 'I/S', 'K/S'); + + /** + * @link http://cvr.dk/Site/Forms/CMS/DisplayPage.aspx?pageid=60 + * + * @var string CVR number format. + */ + protected static $cvrFormat = '%#######'; + + /** + * @link http://cvr.dk/Site/Forms/CMS/DisplayPage.aspx?pageid=60 + * + * @var string P number (production number) format. + */ + protected static $pFormat = '%#########'; + + /** + * Generates a CVR number (8 digits). + * + * @return string + */ + public static function cvr() + { + return static::numerify(static::$cvrFormat); + } + + /** + * Generates a P entity number (10 digits). + * + * @return string + */ + public static function p() + { + return static::numerify(static::$pFormat); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Internet.php new file mode 100644 index 0000000..1f778de --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Internet.php @@ -0,0 +1,30 @@ + + */ +class Internet extends \Faker\Provider\Internet +{ + /** + * @var array Some safe email TLD. + */ + protected static $safeEmailTld = array( + 'org', 'com', 'net', 'dk', 'dk', 'dk', + ); + + /** + * @var array Some email domains in Denmark. + */ + protected static $freeEmailDomain = array( + 'gmail.com', 'yahoo.com', 'yahoo.dk', 'hotmail.com', 'hotmail.dk', 'mail.dk', 'live.dk' + ); + + /** + * @var array Some TLD. + */ + protected static $tld = array( + 'com', 'com', 'com', 'biz', 'info', 'net', 'org', 'dk', 'dk', 'dk', + ); +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Payment.php b/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Payment.php new file mode 100644 index 0000000..6a5b6a8 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/Payment.php @@ -0,0 +1,19 @@ + + */ +class Person extends \Faker\Provider\Person +{ + /** + * @var array Danish person name formats. + */ + protected static $maleNameFormats = array( + '{{firstNameMale}} {{lastName}}', + '{{firstNameMale}} {{lastName}}', + '{{firstNameMale}} {{lastName}}', + '{{firstNameMale}} {{middleName}} {{lastName}}', + '{{firstNameMale}} {{middleName}} {{lastName}}', + '{{firstNameMale}} {{middleName}}-{{middleName}} {{lastName}}', + '{{firstNameMale}} {{middleName}} {{middleName}}-{{lastName}}', + ); + + protected static $femaleNameFormats = array( + '{{firstNameFemale}} {{lastName}}', + '{{firstNameFemale}} {{lastName}}', + '{{firstNameFemale}} {{lastName}}', + '{{firstNameFemale}} {{middleName}} {{lastName}}', + '{{firstNameFemale}} {{middleName}} {{lastName}}', + '{{firstNameFemale}} {{middleName}}-{{middleName}} {{lastName}}', + '{{firstNameFemale}} {{middleName}} {{middleName}}-{{lastName}}', + ); + + /** + * @var array Danish first names. + */ + protected static $firstNameMale = array( + 'Aage', 'Adam', 'Adolf', 'Ahmad', 'Ahmed', 'Aksel', 'Albert', 'Alex', 'Alexander', 'Alf', 'Alfred', 'Ali', 'Allan', + 'Anders', 'Andreas', 'Anker', 'Anton', 'Arne', 'Arnold', 'Arthur', 'Asbjørn', 'Asger', 'August', 'Axel', 'Benjamin', + 'Benny', 'Bent', 'Bernhard', 'Birger', 'Bjarne', 'Bjørn', 'Bo', 'Brian', 'Bruno', 'Børge', 'Carl', 'Carlo', + 'Carsten', 'Casper', 'Charles', 'Chris', 'Christian', 'Christoffer', 'Christopher', 'Claus', 'Dan', 'Daniel', 'David', 'Dennis', + 'Ebbe', 'Edmund', 'Edvard', 'Egon', 'Einar', 'Ejvind', 'Elias', 'Emanuel', 'Emil', 'Erik', 'Erland', 'Erling', + 'Ernst', 'Esben', 'Ferdinand', 'Finn', 'Flemming', 'Frank', 'Freddy', 'Frederik', 'Frits', 'Fritz', 'Frode', 'Georg', + 'Gerhard', 'Gert', 'Gunnar', 'Gustav', 'Hans', 'Harald', 'Harry', 'Hassan', 'Heine', 'Heinrich', 'Helge', 'Helmer', + 'Helmuth', 'Henning', 'Henrik', 'Henry', 'Herman', 'Hermann', 'Holger', 'Hugo', 'Ib', 'Ibrahim', 'Ivan', 'Jack', + 'Jacob', 'Jakob', 'Jan', 'Janne', 'Jens', 'Jeppe', 'Jesper', 'Jimmi', 'Jimmy', 'Joachim', 'Johan', 'Johannes', + 'John', 'Johnny', 'Jon', 'Jonas', 'Jonathan', 'Josef', 'Jul', 'Julius', 'Jørgen', 'Jørn', 'Kai', 'Kaj', + 'Karl', 'Karlo', 'Karsten', 'Kasper', 'Kenneth', 'Kent', 'Kevin', 'Kjeld', 'Klaus', 'Knud', 'Kristian', 'Kristoffer', + 'Kurt', 'Lars', 'Lasse', 'Leif', 'Lennart', 'Leo', 'Leon', 'Louis', 'Lucas', 'Lukas', 'Mads', 'Magnus', + 'Malthe', 'Marc', 'Marcus', 'Marinus', 'Marius', 'Mark', 'Markus', 'Martin', 'Martinus', 'Mathias', 'Max', 'Michael', + 'Mikael', 'Mike', 'Mikkel', 'Mogens', 'Mohamad', 'Mohamed', 'Mohammad', 'Morten', 'Nick', 'Nicklas', 'Nicolai', 'Nicolaj', + 'Niels', 'Niklas', 'Nikolaj', 'Nils', 'Olaf', 'Olav', 'Ole', 'Oliver', 'Oscar', 'Oskar', 'Otto', 'Ove', + 'Palle', 'Patrick', 'Paul', 'Peder', 'Per', 'Peter', 'Philip', 'Poul', 'Preben', 'Rasmus', 'Rene', 'René', + 'Richard', 'Robert', 'Rolf', 'Rudolf', 'Rune', 'Sebastian', 'Sigurd', 'Simon', 'Simone', 'Steen', 'Stefan', 'Steffen', + 'Sten', 'Stig', 'Sune', 'Sven', 'Svend', 'Søren', 'Tage', 'Theodor', 'Thomas', 'Thor', 'Thorvald', 'Tim', + 'Tobias', 'Tom', 'Tommy', 'Tonny', 'Torben', 'Troels', 'Uffe', 'Ulrik', 'Vagn', 'Vagner', 'Valdemar', 'Vang', + 'Verner', 'Victor', 'Viktor', 'Villy', 'Walther', 'Werner', 'Wilhelm', 'William', 'Willy', 'Åge', 'Bendt', 'Bjarke', + 'Chr', 'Eigil', 'Ejgil', 'Ejler', 'Ejnar', 'Ejner', 'Evald', 'Folmer', 'Gunner', 'Gurli', 'Hartvig', 'Herluf', 'Hjalmar', + 'Ingemann', 'Ingolf', 'Ingvard', 'Keld', 'Kresten', 'Laurids', 'Laurits', 'Lauritz', 'Ludvig', 'Lynge', 'Oluf', 'Osvald', + 'Povl', 'Richardt', 'Sigfred', 'Sofus', 'Thorkild', 'Viggo', 'Vilhelm', 'Villiam', + ); + + protected static $firstNameFemale = array( + 'Aase', 'Agathe', 'Agnes', 'Alberte', 'Alexandra', 'Alice', 'Alma', 'Amalie', 'Amanda', 'Andrea', 'Ane', 'Anette', 'Anita', + 'Anja', 'Ann', 'Anna', 'Annalise', 'Anne', 'Anne-Lise', 'Anne-Marie', 'Anne-Mette', 'Annelise', 'Annette', 'Anni', 'Annie', + 'Annika', 'Anny', 'Asta', 'Astrid', 'Augusta', 'Benedikte', 'Bente', 'Berit', 'Bertha', 'Betina', 'Bettina', 'Betty', + 'Birgit', 'Birgitte', 'Birte', 'Birthe', 'Bitten', 'Bodil', 'Britt', 'Britta', 'Camilla', 'Carina', 'Carla', 'Caroline', + 'Cathrine', 'Cecilie', 'Charlotte', 'Christa', 'Christen', 'Christiane', 'Christina', 'Christine', 'Clara', 'Conni', 'Connie', 'Conny', + 'Dagmar', 'Dagny', 'Diana', 'Ditte', 'Dora', 'Doris', 'Dorte', 'Dorthe', 'Ebba', 'Edel', 'Edith', 'Eleonora', + 'Eli', 'Elin', 'Eline', 'Elinor', 'Elisa', 'Elisabeth', 'Elise', 'Ella', 'Ellen', 'Ellinor', 'Elly', 'Elna', + 'Elsa', 'Else', 'Elsebeth', 'Elvira', 'Emilie', 'Emma', 'Emmy', 'Erna', 'Ester', 'Esther', 'Eva', 'Evelyn', + 'Frede', 'Frederikke', 'Freja', 'Frida', 'Gerda', 'Gertrud', 'Gitte', 'Grete', 'Grethe', 'Gudrun', 'Hanna', 'Hanne', + 'Hardy', 'Harriet', 'Hedvig', 'Heidi', 'Helen', 'Helena', 'Helene', 'Helga', 'Helle', 'Henny', 'Henriette', 'Herdis', + 'Hilda', 'Iben', 'Ida', 'Ilse', 'Ina', 'Inga', 'Inge', 'Ingeborg', 'Ingelise', 'Inger', 'Ingrid', 'Irene', + 'Iris', 'Irma', 'Isabella', 'Jane', 'Janni', 'Jannie', 'Jeanette', 'Jeanne', 'Jenny', 'Jes', 'Jette', 'Joan', + 'Johanna', 'Johanne', 'Jonna', 'Josefine', 'Josephine', 'Juliane', 'Julie', 'Jytte', 'Kaja', 'Kamilla', 'Karen', 'Karin', + 'Karina', 'Karla', 'Karoline', 'Kate', 'Kathrine', 'Katja', 'Katrine', 'Ketty', 'Kim', 'Kirsten', 'Kirstine', 'Klara', + 'Krista', 'Kristen', 'Kristina', 'Kristine', 'Laila', 'Laura', 'Laurine', 'Lea', 'Lena', 'Lene', 'Lilian', 'Lilli', + 'Lillian', 'Lilly', 'Linda', 'Line', 'Lis', 'Lisa', 'Lisbet', 'Lisbeth', 'Lise', 'Liselotte', 'Lissi', 'Lissy', + 'Liv', 'Lizzie', 'Lone', 'Lotte', 'Louise', 'Lydia', 'Lykke', 'Lærke', 'Magda', 'Magdalene', 'Mai', 'Maiken', + 'Maj', 'Maja', 'Majbritt', 'Malene', 'Maren', 'Margit', 'Margrethe', 'Maria', 'Mariane', 'Marianne', 'Marie', 'Marlene', + 'Martha', 'Martine', 'Mary', 'Mathilde', 'Matilde', 'Merete', 'Merethe', 'Meta', 'Mette', 'Mia', 'Michelle', 'Mie', + 'Mille', 'Minna', 'Mona', 'Monica', 'Nadia', 'Nancy', 'Nanna', 'Nicoline', 'Nikoline', 'Nina', 'Ninna', 'Oda', + 'Olga', 'Olivia', 'Orla', 'Paula', 'Pauline', 'Pernille', 'Petra', 'Pia', 'Poula', 'Ragnhild', 'Randi', 'Rasmine', + 'Rebecca', 'Rebekka', 'Rigmor', 'Rikke', 'Rita', 'Rosa', 'Rose', 'Ruth', 'Sabrina', 'Sandra', 'Sanne', 'Sara', + 'Sarah', 'Selma', 'Severin', 'Sidsel', 'Signe', 'Sigrid', 'Sine', 'Sofia', 'Sofie', 'Solveig', 'Solvejg', 'Sonja', + 'Sophie', 'Stephanie', 'Stine', 'Susan', 'Susanne', 'Tanja', 'Thea', 'Theodora', 'Therese', 'Thi', 'Thyra', 'Tina', + 'Tine', 'Tove', 'Trine', 'Ulla', 'Vera', 'Vibeke', 'Victoria', 'Viktoria', 'Viola', 'Vita', 'Vivi', 'Vivian', + 'Winnie', 'Yrsa', 'Yvonne', 'Agnete', 'Agnethe', 'Alfrida', 'Alvilda', 'Anine', 'Bolette', 'Dorthea', 'Gunhild', + 'Hansine', 'Inge-Lise', 'Jensine', 'Juel', 'Jørgine', 'Kamma', 'Kristiane', 'Maj-Britt', 'Margrete', 'Metha', 'Nielsine', + 'Oline', 'Petrea', 'Petrine', 'Pouline', 'Ragna', 'Sørine', 'Thora', 'Valborg', 'Vilhelmine', + ); + + /** + * @var array Danish middle names. + */ + protected static $middleName = array( + 'Møller', 'Lund', 'Holm', 'Jensen', 'Juul', 'Nielsen', 'Kjær', 'Hansen', 'Skov', 'Østergaard', 'Vestergaard', + 'Nørgaard', 'Dahl', 'Bach', 'Friis', 'Søndergaard', 'Andersen', 'Bech', 'Pedersen', 'Bruun', 'Nygaard', 'Winther', + 'Bang', 'Krogh', 'Schmidt', 'Christensen', 'Hedegaard', 'Toft', 'Damgaard', 'Holst', 'Sørensen', 'Juhl', 'Munk', + 'Skovgaard', 'Søgaard', 'Aagaard', 'Berg', 'Dam', 'Petersen', 'Lind', 'Overgaard', 'Brandt', 'Larsen', 'Bak', 'Schou', + 'Vinther', 'Bjerregaard', 'Riis', 'Bundgaard', 'Kruse', 'Mølgaard', 'Hjorth', 'Ravn', 'Madsen', 'Rasmussen', + 'Jørgensen', 'Kristensen', 'Bonde', 'Bay', 'Hougaard', 'Dalsgaard', 'Kjærgaard', 'Haugaard', 'Munch', 'Bjerre', 'Due', + 'Sloth', 'Leth', 'Kofoed', 'Thomsen', 'Kragh', 'Højgaard', 'Dalgaard', 'Hjort', 'Kirkegaard', 'Bøgh', 'Beck', 'Nissen', + 'Rask', 'Høj', 'Brix', 'Storm', 'Buch', 'Bisgaard', 'Birch', 'Gade', 'Kjærsgaard', 'Hald', 'Lindberg', 'Høgh', 'Falk', + 'Koch', 'Thorup', 'Borup', 'Knudsen', 'Vedel', 'Poulsen', 'Bøgelund', 'Juel', 'Frost', 'Hvid', 'Bjerg', 'Bæk', 'Elkjær', + 'Hartmann', 'Kirk', 'Sand', 'Sommer', 'Skou', 'Nedergaard', 'Meldgaard', 'Brink', 'Lindegaard', 'Fischer', 'Rye', + 'Hoffmann', 'Daugaard', 'Gram', 'Johansen', 'Meyer', 'Schultz', 'Fogh', 'Bloch', 'Lundgaard', 'Brøndum', 'Jessen', + 'Busk', 'Holmgaard', 'Lindholm', 'Krog', 'Egelund', 'Engelbrecht', 'Buus', 'Korsgaard', 'Ellegaard', 'Tang', 'Steen', + 'Kvist', 'Olsen', 'Nørregaard', 'Fuglsang', 'Wulff', 'Damsgaard', 'Hauge', 'Sonne', 'Skytte', 'Brun', 'Kronborg', + 'Abildgaard', 'Fabricius', 'Bille', 'Skaarup', 'Rahbek', 'Borg', 'Torp', 'Klitgaard', 'Nørskov', 'Greve', 'Hviid', + 'Mørch', 'Buhl', 'Rohde', 'Mørk', 'Vendelbo', 'Bjørn', 'Laursen', 'Egede', 'Rytter', 'Lehmann', 'Guldberg', 'Rosendahl', + 'Krarup', 'Krogsgaard', 'Westergaard', 'Rosendal', 'Fisker', 'Højer', 'Rosenberg', 'Svane', 'Storgaard', 'Pihl', + 'Mohamed', 'Bülow', 'Birk', 'Hammer', 'Bro', 'Kaas', 'Clausen', 'Nymann', 'Egholm', 'Ingemann', 'Haahr', 'Olesen', + 'Nøhr', 'Brinch', 'Bjerring', 'Christiansen', 'Schrøder', 'Guldager', 'Skjødt', 'Højlund', 'Ørum', 'Weber', + 'Bødker', 'Bruhn', 'Stampe', 'Astrup', 'Schack', 'Mikkelsen', 'Høyer', 'Husted', 'Skriver', 'Lindgaard', 'Yde', + 'Sylvest', 'Lykkegaard', 'Ploug', 'Gammelgaard', 'Pilgaard', 'Brogaard', 'Degn', 'Kaae', 'Kofod', 'Grønbæk', + 'Lundsgaard', 'Bagge', 'Lyng', 'Rømer', 'Kjeldgaard', 'Hovgaard', 'Groth', 'Hyldgaard', 'Ladefoged', 'Jacobsen', + 'Linde', 'Lange', 'Stokholm', 'Bredahl', 'Hein', 'Mose', 'Bækgaard', 'Sandberg', 'Klarskov', 'Kamp', 'Green', + 'Iversen', 'Riber', 'Smedegaard', 'Nyholm', 'Vad', 'Balle', 'Kjeldsen', 'Strøm', 'Borch', 'Lerche', 'Grønlund', + 'Vestergård', 'Østergård', 'Nyborg', 'Qvist', 'Damkjær', 'Kold', 'Sønderskov', 'Bank', + ); + + /** + * @var array Danish last names. + */ + protected static $lastName = array( + 'Jensen', 'Nielsen', 'Hansen', 'Pedersen', 'Andersen', 'Christensen', 'Larsen', 'Sørensen', 'Rasmussen', 'Petersen', + 'Jørgensen', 'Madsen', 'Kristensen', 'Olsen', 'Christiansen', 'Thomsen', 'Poulsen', 'Johansen', 'Knudsen', 'Mortensen', + 'Møller', 'Jacobsen', 'Jakobsen', 'Olesen', 'Frederiksen', 'Mikkelsen', 'Henriksen', 'Laursen', 'Lund', 'Schmidt', + 'Eriksen', 'Holm', 'Kristiansen', 'Clausen', 'Simonsen', 'Svendsen', 'Andreasen', 'Iversen', 'Jeppesen', 'Mogensen', + 'Jespersen', 'Nissen', 'Lauridsen', 'Frandsen', 'Østergaard', 'Jepsen', 'Kjær', 'Carlsen', 'Vestergaard', 'Jessen', + 'Nørgaard', 'Dahl', 'Christoffersen', 'Skov', 'Søndergaard', 'Bertelsen', 'Bruun', 'Lassen', 'Bach', 'Gregersen', + 'Friis', 'Johnsen', 'Steffensen', 'Kjeldsen', 'Bech', 'Krogh', 'Lauritsen', 'Danielsen', 'Mathiesen', 'Andresen', + 'Brandt', 'Winther', 'Toft', 'Ravn', 'Mathiasen', 'Dam', 'Holst', 'Nilsson', 'Lind', 'Berg', 'Schou', 'Overgaard', + 'Kristoffersen', 'Schultz', 'Klausen', 'Karlsen', 'Paulsen', 'Hermansen', 'Thorsen', 'Koch', 'Thygesen', 'Bak', 'Kruse', + 'Bang', 'Juhl', 'Davidsen', 'Berthelsen', 'Nygaard', 'Lorentzen', 'Villadsen', 'Lorenzen', 'Damgaard', 'Bjerregaard', + 'Lange', 'Hedegaard', 'Bendtsen', 'Lauritzen', 'Svensson', 'Justesen', 'Juul', 'Hald', 'Beck', 'Kofoed', 'Søgaard', + 'Meyer', 'Kjærgaard', 'Riis', 'Johannsen', 'Carstensen', 'Bonde', 'Ibsen', 'Fischer', 'Andersson', 'Bundgaard', + 'Johannesen', 'Eskildsen', 'Hemmingsen', 'Andreassen', 'Thomassen', 'Schrøder', 'Persson', 'Hjorth', 'Enevoldsen', + 'Nguyen', 'Henningsen', 'Jønsson', 'Olsson', 'Asmussen', 'Michelsen', 'Vinther', 'Markussen', 'Kragh', 'Thøgersen', + 'Johansson', 'Dalsgaard', 'Gade', 'Bjerre', 'Ali', 'Laustsen', 'Buch', 'Ludvigsen', 'Hougaard', 'Kirkegaard', 'Marcussen', + 'Mølgaard', 'Ipsen', 'Sommer', 'Ottosen', 'Müller', 'Krog', 'Hoffmann', 'Clemmensen', 'Nikolajsen', 'Brodersen', + 'Therkildsen', 'Leth', 'Michaelsen', 'Graversen', 'Frost', 'Dalgaard', 'Albertsen', 'Laugesen', 'Due', 'Ebbesen', + 'Munch', 'Svenningsen', 'Ottesen', 'Fisker', 'Albrechtsen', 'Axelsen', 'Erichsen', 'Sloth', 'Bentsen', 'Westergaard', + 'Bisgaard', 'Nicolaisen', 'Magnussen', 'Thuesen', 'Povlsen', 'Thorup', 'Høj', 'Bentzen', 'Johannessen', 'Vilhelmsen', + 'Isaksen', 'Bendixen', 'Ovesen', 'Villumsen', 'Lindberg', 'Thomasen', 'Kjærsgaard', 'Buhl', 'Kofod', 'Ahmed', 'Smith', + 'Storm', 'Christophersen', 'Bruhn', 'Matthiesen', 'Wagner', 'Bjerg', 'Gram', 'Nedergaard', 'Dinesen', 'Mouritsen', + 'Boesen', 'Borup', 'Abrahamsen', 'Wulff', 'Gravesen', 'Rask', 'Pallesen', 'Greve', 'Korsgaard', 'Haugaard', 'Josefsen', + 'Bæk', 'Espersen', 'Thrane', 'Mørch', 'Frank', 'Lynge', 'Rohde', 'Larsson', 'Hammer', 'Torp', 'Sonne', 'Boysen', 'Bay', + 'Pihl', 'Fabricius', 'Høyer', 'Birch', 'Skou', 'Kirk', 'Antonsen', 'Høgh', 'Damsgaard', 'Dall', 'Truelsen', 'Daugaard', + 'Fuglsang', 'Martinsen', 'Therkelsen', 'Jansen', 'Karlsson', 'Caspersen', 'Steen', 'Callesen', 'Balle', 'Bloch', 'Smidt', + 'Rahbek', 'Hjort', 'Bjørn', 'Skaarup', 'Sand', 'Storgaard', 'Willumsen', 'Busk', 'Hartmann', 'Ladefoged', 'Skovgaard', + 'Philipsen', 'Damm', 'Haagensen', 'Hviid', 'Duus', 'Kvist', 'Adamsen', 'Mathiassen', 'Degn', 'Borg', 'Brix', 'Troelsen', + 'Ditlevsen', 'Brøndum', 'Svane', 'Mohamed', 'Birk', 'Brink', 'Hassan', 'Vester', 'Elkjær', 'Lykke', 'Nørregaard', + 'Meldgaard', 'Mørk', 'Hvid', 'Abildgaard', 'Nicolajsen', 'Bengtsson', 'Stokholm', 'Ahmad', 'Wind', 'Rømer', 'Gundersen', + 'Carlsson', 'Grøn', 'Khan', 'Skytte', 'Bagger', 'Hendriksen', 'Rosenberg', 'Jonassen', 'Severinsen', 'Jürgensen', + 'Boisen', 'Groth', 'Bager', 'Fogh', 'Hussain', 'Samuelsen', 'Pilgaard', 'Bødker', 'Dideriksen', 'Brogaard', 'Lundberg', + 'Hansson', 'Schwartz', 'Tran', 'Skriver', 'Klitgaard', 'Hauge', 'Højgaard', 'Qvist', 'Voss', 'Strøm', 'Wolff', 'Krarup', + 'Green', 'Odgaard', 'Tønnesen', 'Blom', 'Gammelgaard', 'Jæger', 'Kramer', 'Astrup', 'Würtz', 'Lehmann', 'Koefoed', + 'Skøtt', 'Lundsgaard', 'Bøgh', 'Vang', 'Martinussen', 'Sandberg', 'Weber', 'Holmgaard', 'Bidstrup', 'Meier', 'Drejer', + 'Schneider', 'Joensen', 'Dupont', 'Lorentsen', 'Bro', 'Bagge', 'Terkelsen', 'Kaspersen', 'Keller', 'Eliasen', 'Lyberth', + 'Husted', 'Mouritzen', 'Krag', 'Kragelund', 'Nørskov', 'Vad', 'Jochumsen', 'Hein', 'Krogsgaard', 'Kaas', 'Tolstrup', + 'Ernst', 'Hermann', 'Børgesen', 'Skjødt', 'Holt', 'Buus', 'Gotfredsen', 'Kjeldgaard', 'Broberg', 'Roed', 'Sivertsen', + 'Bergmann', 'Bjerrum', 'Petersson', 'Smed', 'Jeremiassen', 'Nyborg', 'Borch', 'Foged', 'Terp', 'Mark', 'Busch', + 'Lundgaard', 'Boye', 'Yde', 'Hinrichsen', 'Matzen', 'Esbensen', 'Hertz', 'Westh', 'Holmberg', 'Geertsen', 'Raun', + 'Aagaard', 'Kock', 'Falk', 'Munk', + ); + + /** + * Randomly return a danish name. + * + * @return string + */ + public static function middleName() + { + return static::randomElement(static::$middleName); + } + + /** + * Randomly return a danish CPR number (Personnal identification number) format. + * + * @link http://cpr.dk/cpr/site.aspx?p=16 + * @link http://en.wikipedia.org/wiki/Personal_identification_number_%28Denmark%29 + * + * @return string + */ + public static function cpr() + { + $birthdate = new \DateTime('@' . mt_rand(0, time())); + + return sprintf('%s-%s', $birthdate->format('dmy'), static::numerify('%###')); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/PhoneNumber.php new file mode 100644 index 0000000..af96d3f --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/da_DK/PhoneNumber.php @@ -0,0 +1,21 @@ + + */ +class PhoneNumber extends \Faker\Provider\PhoneNumber +{ + /** + * @var array Danish phonenumber formats. + */ + protected static $formats = array( + '+45 ## ## ## ##', + '+45 #### ####', + '+45########', + '## ## ## ##', + '#### ####', + '########', + ); +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/de_AT/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/de_AT/Address.php new file mode 100644 index 0000000..22bcf12 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/de_AT/Address.php @@ -0,0 +1,99 @@ +generator->parse(static::randomElement(static::$lastNameFormat)); + } + + /** + * @example 'Θεωδωρόπουλος' + */ + public static function lastNameMale() + { + return static::randomElement(static::$lastNameMale); + } + + /** + * @example 'Κοκκίνου' + */ + public static function lastNameFemale() + { + return static::randomElement(static::$lastNameFemale); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/el_GR/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/el_GR/PhoneNumber.php new file mode 100644 index 0000000..107253d --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/el_GR/PhoneNumber.php @@ -0,0 +1,19 @@ +numberBetween($min = 10000, $max = 100000000); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/es_VE/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/es_VE/PhoneNumber.php new file mode 100644 index 0000000..74caecc --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/es_VE/PhoneNumber.php @@ -0,0 +1,29 @@ +generator->parse($format)); + } + + /** + * @example 'ahmad.ir' + */ + public function domainName() + { + return static::randomElement(static::$lastNameAscii) . '.' . $this->tld(); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/fa_IR/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/fa_IR/Person.php new file mode 100644 index 0000000..055b863 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/fa_IR/Person.php @@ -0,0 +1,137 @@ + 5) { + throw new \InvalidArgumentException('indexSize must be at most 5'); + } + + $words = $this->getConsecutiveWords($indexSize); + $result = array(); + $resultLength = 0; + // take a random starting point + $next = static::randomKey($words); + while ($resultLength < $maxNbChars && isset($words[$next])) { + // fetch a random word to append + $word = static::randomElement($words[$next]); + + // calculate next index + $currentWords = explode(' ', $next); + + $currentWords[] = $word; + array_shift($currentWords); + $next = implode(' ', $currentWords); + + if ($resultLength == 0 && !preg_match('/^[\x{0600}-\x{06FF}]/u', $word)) { + continue; + } + // append the element + $result[] = $word; + $resultLength += strlen($word) + 1; + } + + // remove the element that caused the text to overflow + array_pop($result); + + // build result + $result = implode(' ', $result); + + return $result.'.'; + } + + /** + * License: Creative Commons Attribution-ShareAlike License + * + * Title: مدیر مدرسه + * Author: جلال آل‌احمد + * Language: Persian + * + * @see http://fa.wikisource.org/wiki/%D9%85%D8%AF%DB%8C%D8%B1_%D9%85%D8%AF%D8%B1%D8%B3%D9%87 + * @var string + */ + protected static $baseText = <<<'EOT' +از در که وارد شدم سیگارم دستم بود. زورم آمد سلام کنم. همین طوری دنگم گرفته بود قد باشم. رئیس فرهنگ که اجازه‌ی نشستن داد، نگاهش لحظه‌ای روی دستم مکث کرد و بعد چیزی را که می‌نوشت، تمام کرد و می‌خواست متوجه من بشود که رونویس حکم را روی میزش گذاشته بودم. حرفی نزدیم. رونویس را با کاغذهای ضمیمه‌اش زیر و رو کرد و بعد غبغب انداخت و آرام و مثلاً خالی از عصبانیت گفت: + +- جا نداریم آقا. این که نمی‌شه! هر روز یه حکم می‌دند دست یکی می‌فرستنش سراغ من... دیروز به آقای مدیر کل... + +حوصله‌ی این اباطیل را نداشتم. حرفش را بریدم که: + +- ممکنه خواهش کنم زیر همین ورقه مرقوم بفرمایید؟ + +و سیگارم را توی زیرسیگاری براق روی میزش تکاندم. روی میز، پاک و مرتب بود. درست مثل اتاق همان مهمان‌خانه‌ی تازه‌عروس‌ها. هر چیز به جای خود و نه یک ذره گرد. فقط خاکستر سیگار من زیادی بود. مثل تفی در صورت تازه تراشیده‌ای.... قلم را برداشت و زیر حکم چیزی نوشت و امضا کرد و من از در آمده بودم بیرون. خلاص. تحمل این یکی را نداشتم. با اداهایش. پیدا بود که تازه رئیس شده. زورکی غبغب می‌انداخت و حرفش را آهسته توی چشم آدم می‌زد. انگار برای شنیدنش گوش لازم نیست. صد و پنجاه تومان در کارگزینی کل مایه گذاشته بودم تا این حکم را به امضا رسانده بودم. توصیه هم برده بودم و تازه دو ماه هم دویده بودم. مو، لای درزش نمی‌رفت. می‌دانستم که چه او بپذیرد، چه نپذیرد، کار تمام است. خودش هم می‌دانست. حتماً هم دستگیرش شد که با این نک و نالی که می‌کرد، خودش را کنف کرده. ولی کاری بود و شده بود. در کارگزینی کل، سفارش کرده بودند که برای خالی نبودن عریضه رونویس را به رؤیت رئیس فرهنگ هم برسانم تازه این طور شد. و گر نه بالی حکم کارگزینی کل چه کسی می‌توانست حرفی بزند؟ یک وزارت خانه بود و یک کارگزینی! شوخی که نبود. ته دلم قرص‌تر از این‌ها بود که محتاج به این استدلال‌ها باشم. اما به نظرم همه‌ی این تقصیرها از این سیگار لعنتی بود که به خیال خودم خواسته بودم خرجش را از محل اضافه حقوق شغل جدیدم در بیاورم. البته از معلمی، هم اُقم نشسته بود. ده سال «الف.ب.» درس دادن و قیافه‌های بهت‌زده‌ی بچه‌های مردم برای مزخرف‌ترین چرندی که می‌گویی... و استغناء با غین و استقراء با قاف و خراسانی و هندی و قدیمی‌ترین شعر دری و صنعت ارسال مثل و ردالعجز... و از این مزخرفات! دیدم دارم خر می‌شوم. گفتم مدیر بشوم. مدیر دبستان! دیگر نه درس خواهم داد و نه مجبور خواهم بود برای فرار از اتلاف وقت، در امتحان تجدیدی به هر احمق بی‌شعوری هفت بدهم تا ایام آخر تابستانم را که لذیذترین تکه‌ی تعطیلات است، نجات داده باشم. این بود که راه افتادم. رفتم و از اهلش پرسیدم. از یک کار چاق کن. دستم را توی دست کارگزینی گذاشت و قول و قرار و طرفین خوش و خرم و یک روز هم نشانی مدرسه را دستم دادند که بروم وارسی، که باب میلم هست یا نه. + +و رفتم. مدرسه دو طبقه بود و نوساز بود و در دامنه‌ی کوه تنها افتاده بود و آفتاب‌رو بود. یک فرهنگ‌دوست خرپول، عمارتش را وسط زمین خودش ساخته بود و بیست و پنج سال هم در اختیار فرهنگ گذاشته بود که مدرسه‌اش کنند و رفت و آمد بشود و جاده‌ها کوبیده بشود و این قدر ازین بشودها بشود، تا دل ننه باباها بسوزد و برای این‌که راه بچه‌هاشان را کوتاه بکنند، بیایند همان اطراف مدرسه را بخرند و خانه بسازند و زمین یارو از متری یک عباسی بشود صد تومان. یارو اسمش را هم روی دیوار مدرسه کاشی‌کاری کرده بود. هنوز در و همسایه پیدا نکرده بودند که حرف‌شان بشود و لنگ و پاچه‌ی سعدی و باباطاهر را بکشند میان و یک ورق دیگر از تاریخ‌الشعرا را بکوبند روی نبش دیوار کوچه‌شان. تابلوی مدرسه هم حسابی و بزرگ و خوانا. از صد متری داد می‌زد که توانا بود هر.... هر چه دلتان بخواهد! با شیر و خورشیدش که آن بالا سر، سه پا ایستاده بود و زورکی تعادل خودش را حفظ می‌کرد و خورشید خانم روی کولش با ابروهای پیوسته و قمچیلی که به دست داشت و تا سه تیر پرتاب، اطراف مدرسه بیابان بود. درندشت و بی آب و آبادانی و آن ته رو به شمال، ردیف کاج‌های درهم فرو رفته‌ای که از سر دیوار گلی یک باغ پیدا بود روی آسمان لکه‌ی دراز و تیره‌ای زده بود. حتماً تا بیست و پنج سال دیگر همه‌ی این اطراف پر می‌شد و بوق ماشین و ونگ ونگ بچه‌ها و فریاد لبویی و زنگ روزنامه‌فروشی و عربده‌ی گل به سر دارم خیار! نان یارو توی روغن بود. + +- راستی شاید متری ده دوازده شاهی بیشتر نخریده باشد؟ شاید هم زمین‌ها را همین جوری به ثبت داده باشد؟ هان؟ + +- احمق به توچه؟!... + +بله این فکرها را همان روزی کردم که ناشناس به مدرسه سر زدم و آخر سر هم به این نتیجه رسیدم که مردم حق دارند جایی بخوابند که آب زیرشان نرود. + +- تو اگر مردی، عرضه داشته باش مدیر همین مدرسه هم بشو. + +و رفته بودم و دنبال کار را گرفته بودم تا رسیده بودم به این‌جا. همان روز وارسی فهمیده بودم که مدیر قبلی مدرسه زندانی است. لابد کله‌اش بوی قرمه‌سبزی می‌داده و باز لابد حالا دارد کفاره‌ی گناهانی را می‌دهد که یا خودش نکرده یا آهنگری در بلخ کرده. جزو پر قیچی‌های رئیس فرهنگ هم کسی نبود که با مدیرشان، اضافه حقوقی نصیبش بشود و ناچار سر و دستی برای این کار بشکند. خارج از مرکز هم نداشت. این معلومات را توی کارگزینی به دست آورده بودم. هنوز «گه خوردم نامه‌نویسی» هم مد نشده بود که بگویم یارو به این زودی‌ها از سولدونی در خواهد آمد. فکر نمی‌کردم که دیگری هم برای این وسط بیابان دلش لک زده باشد با زمستان سختش و با رفت و آمد دشوارش. + +این بود که خیالم راحت بود. از همه‌ی این‌ها گذشته کارگزینی کل موافقت کرده بود! دست است که پیش از بلند شدن بوی اسکناس، آن جا هم دو سه تا عیب شرعی و عرفی گرفته بودند و مثلاً گفته بودن لابد کاسه‌ای زیر نیم کاسه است که فلانی یعنی من، با ده سال سابقه‌ی تدریس، می‌خواهد مدیر دبستان بشود! غرض‌شان این بود که لابد خل شدم که از شغل مهم و محترم دبیری دست می‌شویم. ماهی صد و پنجاه تومان حق مقام در آن روزها پولی نبود که بتوانم نادیده بگیرم. و تازه اگر ندیده می‌گرفتم چه؟ باز باید بر می‌گشتم به این کلاس‌ها و این جور حماقت‌ها. این بود که پیش رئیس فرهنگ، صاف برگشتم به کارگزینی کل، سراغ آن که بفهمی نفهمی، دلال کارم بود. و رونویس حکم را گذاشتم و گفتم که چه طور شد و آمدم بیرون. + +دو روز بعد رفتم سراغش. معلوم شد که حدسم درست بوده است و رئیس فرهنگ گفته بوده: «من از این لیسانسه‌های پر افاده نمی‌خواهم که سیگار به دست توی هر اتاقی سر می‌کنند.» + +و یارو برایش گفته بود که اصلاً وابدا..! فلانی همچین و همچون است و مثقالی هفت صنار با دیگران فرق دارد و این هندوانه‌ها و خیال من راحت باشد و پنج‌شنبه یک هفته‌ی دیگر خودم بروم پهلوی او... و این کار را کردم. این بار رئیس فرهنگ جلوی پایم بلند شد که: «ای آقا... چرا اول نفرمودید؟!...» و از کارمندهایش گله کرد و به قول خودش، مرا «در جریان موقعیت محل» گذاشت و بعد با ماشین خودش مرا به مدرسه رساند و گفت زنگ را زودتر از موعد زدند و در حضور معلم‌ها و ناظم، نطق غرایی در خصائل مدیر جدید – که من باشم – کرد و بعد هم مرا گذاشت و رفت با یک مدرسه‌ی شش کلاسه‌ی «نوبنیاد» و یک ناظم و هفت تا معلم و دویست و سی و پنج تا شاگرد. دیگر حسابی مدیر مدرسه شده بودم! + +ناظم، جوان رشیدی بود که بلند حرف می‌زد و به راحتی امر و نهی می‌کرد و بیا و برویی داشت و با شاگردهای درشت، روی هم ریخته بود که خودشان ترتیب کارها را می‌دادند و پیدا بود که به سر خر احتیاجی ندارد و بی‌مدیر هم می‌تواند گلیم مدرسه را از آب بکشد. معلم کلاس چهار خیلی گنده بود. دو تای یک آدم حسابی. توی دفتر، اولین چیزی که به چشم می‌آمد. از آن‌هایی که اگر توی کوچه ببینی، خیال می‌کنی مدیر کل است. لفظ قلم حرف می‌زد و شاید به همین دلیل بود که وقتی رئیس فرهنگ رفت و تشریفات را با خودش برد، از طرف همکارانش تبریک ورود گفت و اشاره کرد به اینکه «ان‌شاءالله زیر سایه‌ی سرکار، سال دیگر کلاس‌های دبیرستان را هم خواهیم داشت.» پیدا بود که این هیکل کم‌کم دارد از سر دبستان زیادی می‌کند! وقتی حرف می‌زد همه‌اش درین فکر بودم که با نان آقا معلمی چه طور می‌شد چنین هیکلی به هم زد و چنین سر و تیپی داشت؟ و راستش تصمیم گرفتم که از فردا صبح به صبح ریشم را بتراشم و یخه‌ام تمیز باشد و اتوی شلوارم تیز. + +معلم کلاس اول باریکه‌ای بود، سیاه سوخته. با ته ریشی و سر ماشین کرده‌ای و یخه‌ی بسته. بی‌کراوات. شبیه میرزابنویس‌های دم پست‌خانه. حتی نوکر باب می‌نمود. و من آن روز نتوانستم بفهمم وقتی حرف می‌زند کجا را نگاه می‌کند. با هر جیغ کوتاهی که می‌زد هرهر می‌خندید. با این قضیه نمی‌شد کاری کرد. معلم کلاس سه، یک جوان ترکه‌ای بود؛ بلند و با صورت استخوانی و ریش از ته تراشیده و یخه‌ی بلند آهاردار. مثل فرفره می‌جنبید. چشم‌هایش برق عجیبی می‌زد که فقط از هوش نبود، چیزی از ناسلامتی در برق چشم‌هایش بود که مرا واداشت از ناظم بپرسم مبادا مسلول باشد. البته مسلول نبود، تنها بود و در دانشگاه درس می‌خواند. کلاس‌های پنجم و ششم را دو نفر با هم اداره می‌کردند. یکی فارسی و شرعیات و تاریخ، جغرافی و کاردستی و این جور سرگرمی‌ها را می‌گفت، که جوانکی بود بریانتین زده، با شلوار پاچه تنگ و پوشت و کراوات زرد و پهنی که نعش یک لنگر بزرگ آن را روی سینه‌اش نگه داشته بود و دائماً دستش حمایل موهای سرش بود و دم به دم توی شیشه‌ها نگاه می‌کرد. و آن دیگری که حساب و مرابحه و چیزهای دیگر می‌گفت، جوانی بود موقر و سنگین مازندرانی به نظر می‌آمد و به خودش اطمینان داشت. غیر از این‌ها، یک معلم ورزش هم داشتیم که دو هفته بعد دیدمش و اصفهانی بود و از آن قاچاق‌ها. + +رئیس فرهنگ که رفت، گرم و نرم از همه‌شان حال و احوال پرسیدم. بعد به همه سیگار تعارف کردم. سراپا همکاری و همدردی بود. از کار و بار هر کدامشان پرسیدم. فقط همان معلم کلاس سه، دانشگاه می‌رفت. آن که لنگر به سینه انداخته بود، شب‌ها انگلیسی می‌خواند که برود آمریکا. چای و بساطی در کار نبود و ربع ساعت‌های تفریح، فقط توی دفتر جمع می‌شدند و دوباره از نو. و این نمی‌شد. باید همه‌ی سنن را رعایت کرد. دست کردم و یک پنج تومانی روی میز گذاشتم و قرار شد قبل و منقلی تهیه کنند و خودشان چای را راه بیندازند. + +بعد از زنگ قرار شد من سر صف نطقی بکنم. ناظم قضیه را در دو سه کلمه برای بچه‌ها گفت که من رسیدم و همه دست زدند. چیزی نداشتم برایشان بگویم. فقط یادم است اشاره‌ای به این کردم که مدیر خیلی دلش می‌خواست یکی از شما را به جای فرزند داشته باشد و حالا نمی‌داند با این همه فرزند چه بکند؟! که بی‌صدا خندیدند و در میان صف‌های عقب یکی پکی زد به خنده. واهمه برم داشت که «نه بابا. کار ساده‌ای هم نیست!» قبلاً فکر کرده بودم که می‌روم و فارغ از دردسر اداره‌ی کلاس، در اتاق را روی خودم می‌بندم و کار خودم را می‌کنم. اما حالا می‌دیدم به این سادگی‌ها هم نیست. اگر فردا یکی‌شان زد سر اون یکی را شکست، اگر یکی زیر ماشین رفت؛ اگر یکی از ایوان افتاد؛ چه خاکی به سرم خواهم ریخت؟ + +حالا من مانده بودم و ناظم که چیزی از لای در آهسته خزید تو. کسی بود؛ فراش مدرسه با قیافه‌ای دهاتی و ریش نتراشیده و قدی کوتاه و گشاد گشاد راه می‌رفت و دست‌هایش را دور از بدن نگه می‌داشت. آمد و همان کنار در ایستاد. صاف توی چشمم نگاه می‌کرد. حال او را هم پرسیدم. هر چه بود او هم می‌توانست یک گوشه‌ی این بار را بگیرد. در یک دقیقه همه‌ی درد دل‌هایش را کرد و التماس دعاهایش که تمام شد، فرستادمش برایم چای درست کند و بیاورد. بعد از آن من به ناظم پرداختم. سال پیش، از دانشسرای مقدماتی در آمده بود. یک سال گرمسار و کرج کار کرده بود و امسال آمده بود این‌جا. پدرش دو تا زن داشته. از اولی دو تا پسر که هر دو تا چاقوکش از آب در آمده‌اند و از دومی فقط او مانده بود که درس‌خوان شده و سرشناس و نان مادرش را می‌دهد که مریض است و از پدر سال‌هاست که خبری نیست و... یک اتاق گرفته‌اند به پنجاه تومان و صد و پنجاه تومان حقوق به جایی نمی‌رسد و تازه زور که بزند سه سال دیگر می‌تواند از حق فنی نظامت مدرسه استفاده کند + +... بعد بلند شدیم که به کلاس‌ها سرکشی کنیم. بعد با ناظم به تک تک کلاس‌ها سر زدیم در این میان من به یاد دوران دبستان خودم افتادم. در کلاس ششم را باز کردیم «... ت بی پدرو مادر» جوانک بریانتین زده خورد توی صورت‌مان. یکی از بچه‌ها صورتش مثل چغندر قرمز بود. لابد بزک فحش هنوز باقی بود. قرائت فارسی داشتند. معلم دستهایش توی جیبش بود و سینه‌اش را پیش داده بود و زبان به شکایت باز کرد: + +- آقای مدیر! اصلاً دوستی سرشون نمی‌شه. تو سَری می‌خوان. ملاحظه کنید بنده با چه صمیمیتی... + +حرفش را در تشدید «ایت» بریدم که: + +- صحیح می‌فرمایید. این بار به من ببخشید. + +و از در آمدیم بیرون. بعد از آن به اطاقی که در آینده مال من بود سر زدیم. بهتر از این نمی‌شد. بی سر و صدا، آفتاب‌رو، دور افتاده. + +وسط حیاط، یک حوض بزرگ بود و کم‌عمق. تنها قسمت ساختمان بود که رعایت حال بچه‌های قد و نیم قد در آن شده بود. دور حیاط دیوار بلندی بود درست مثل دیوار چین. سد مرتفعی در مقابل فرار احتمالی فرهنگ و ته حیاط مستراح و اتاق فراش بغلش و انبار زغال و بعد هم یک کلاس. به مستراح هم سر کشیدیم. همه بی در و سقف و تیغه‌ای میان آن‌ها. نگاهی به ناظم کردم که پا به پایم می‌آمد. گفت: + +- دردسر عجیبی شده آقا. تا حالا صد تا کاغذ به ادارفردا صبح رفتم مدرسه. بچه‌ها با صف‌هاشان به طرف کلاس‌ها می‌رفتند و ناظم چوب به دست توی ایوان ایستاده بود و توی دفتر دو تا از معلم‌ها بودند. معلوم شد کار هر روزه‌شان است. ناظم را هم فرستادم سر یک کلاس دیگر و خودم آمدم دم در مدرسه به قدم زدن؛ فکر کردم از هر طرف که بیایند مرا این ته، دم در مدرسه خواهند دید و تمام طول راه در این خجالت خواهند ماند و دیگر دیر نخواهند آمد. یک سیاهی از ته جاده‌ی جنوبی پیداشد. جوانک بریانتین زده بود. مسلماً او هم مرا می‌دید، ولی آهسته‌تر از آن می‌آمد که یک معلم تأخیر کرده جلوی مدیرش می‌آمد. جلوتر که آمد حتی شنیدم که سوت می‌زد. اما بی‌انصاف چنان سلانه سلانه می‌آمد که دیدم هیچ جای گذشت نیست. اصلاً محل سگ به من نمی‌گذاشت. داشتم از کوره در می‌رفتم که یک مرتبه احساس کردم تغییری در رفتار خود داد و تند کرد. + +به خیر گذشت و گرنه خدا عالم است چه اتفاقی می‌افتاد. سلام که کرد مثل این که می‌خواست چیزی بگوید که پیش دستی کردم: + +- بفرمایید آقا. بفرمایید، بچه‌ها منتظرند. + +واقعاً به خیر گذشت. شاید اتوبوسش دیر کرده. شاید راه‌بندان بوده؛ جاده قرق بوده و باز یک گردن‌کلفتی از اقصای عالم می‌آمده که ازین سفره‌ی مرتضی علی بی‌نصیب نماند. به هر صورت در دل بخشیدمش. چه خوب شد که بد و بی‌راهی نگفتی! که از دور علم افراشته‌ی هیکل معلم کلاس چهارم نمایان شد. از همان ته مرا دیده بود. تقریباً می‌دوید. تحمل این یکی را نداشتم. «بدکاری می‌کنی. اول بسم‌الله و مته به خشخاش!» رفتم و توی دفتر نشستم و خودم را به کاری مشغول کردم که هن هن کنان رسید. چنان عرق از پیشانی‌اش می‌ریخت که راستی خجالت کشیدم. یک لیوان آب از کوه به دستش دادم و مسخ‌شده‌ی خنده‌اش را با آب به خوردش دادم و بلند که شد برود، گفتم: + +- عوضش دو کیلو لاغر شدید. + +برگشت نگاهی کرد و خنده‌ای و رفت. ناگهان ناظم از در وارد شد و از را ه نرسیده گفت: + +- دیدید آقا! این جوری می‌آند مدرسه. اون قرتی که عین خیالش هم نبود آقا! اما این یکی... + +از او پرسیدم: + +- انگار هنوز دو تا از کلاس‌ها ولند؟ + +- بله آقا. کلاس سه ورزش دارند. گفتم بنشینند دیکته بنویسند آقا. معلم حساب پنج و شش هم که نیومده آقا. + +در همین حین یکی از عکس‌های بزرگ دخمه‌های هخامنشی را که به دیوار کوبیده بود پس زد و: + +- نگاه کنید آقا... + +روی گچ دیوار با مداد قرمز و نه چندان درشت، به عجله و ناشیانه علامت داس کشیده بودند. همچنین دنبال کرد: + +- از آثار دوره‌ی اوناست آقا. کارشون همین چیزها بود. روزنومه بفروشند. تبلیغات کنند و داس چکش بکشند آقا. رئیس‌شون رو که گرفتند چه جونی کندم آقا تا حالی‌شون کنم که دست ور دارند آقا. و از روی میز پرید پایین. + +- گفتم مگه باز هم هستند؟ + +- آره آقا، پس چی! یکی همین آقازاده که هنوز نیومده آقا. هر روز نیم ساعت تأخیر داره آقا. یکی هم مثل کلاس سه. + +- خوب چرا تا حالا پاکش نکردی؟ + +- به! آخه آدم درد دلشو واسه‌ی کی بگه؟ آخه آقا در میان تو روی آدم می‌گند جاسوس، مأمور! باهاش حرفم شده آقا. کتک و کتک‌کاری! + +و بعد یک سخنرانی که چه طور مدرسه را خراب کرده‌اند و اعتماد اهل محله را چه طور از بین برده‌اند که نه انجمنی، نه کمکی به بی‌بضاعت‌ها؛ و از این حرف ها. + +بعد از سخنرانی آقای ناظم دستمالم را دادم که آن عکس‌ها را پاک کند و بعد هم راه افتادم که بروم سراغ اتاق خودم. در اتاقم را که باز کردم، داشتم دماغم با بوی خاک نم کشیده‌اش اخت می‌کرد که آخرین معلم هم آمد. آمدم توی ایوان و با صدای بلند، جوری که در تمام مدرسه بشنوند، ناظم را صدا زدم و گفتم با قلم قرمز برای آقا یک ساعت تأخیر بگذارند.ه‌ی ساختمان نوشتیم آقا. می‌گند نمی‌شه پول دولت رو تو ملک دیگرون خرج کرد. + +- گفتم راست می‌گند. + +دیگه کافی بود. آمدیم بیرون. همان توی حیاط تا نفسی تازه کنیم وضع مالی و بودجه و ازین حرف‌های مدرسه را پرسیدم. هر اتاق ماهی پانزده ریال حق نظافت داشت. لوازم‌التحریر و دفترها را هم اداره‌ی فرهنگ می‌داد. ماهی بیست و پنج تومان هم برای آب خوردن داشتند که هنوز وصول نشده بود. برای نصب هر بخاری سالی سه تومان. ماهی سی تومان هم تنخواه‌گردان مدرسه بود که مثل پول آب سوخت شده بود و حالا هم ماه دوم سال بود. اواخر آبان. حالیش کردم که حوصله‌ی این کارها را ندارم و غرضم را از مدیر شدن برایش خلاصه کردم و گفتم حاضرم همه‌ی اختیارات را به او بدهم. «اصلاً انگار که هنوز مدیر نیامده.» مهر مدرسه هم پهلوی خودش باشد. البته او را هنوز نمی‌شناختم. شنیده بودم که مدیرها قبلاً ناظم خودشان را انتخاب می‌کنند، اما من نه کسی را سراغ داشتم و نه حوصله‌اش را. حکم خودم را هم به زور گرفته بودم. سنگ‌هامان را وا کندیم و به دفتر رفتیم و چایی را که فراش از بساط خانه‌اش درست کرده بود، خوردیم تا زنگ را زدند و باز هم زدند و من نگاهی به پرونده‌های شاگردها کردم که هر کدام عبارت بود از دو برگ کاغذ. از همین دو سه برگ کاغذ دانستم که اولیای بچه‌ها اغلب زارع و باغبان و اویارند و قبل از این‌که زنگ آخر را بزنند و مدرسه تعطیل بشود بیرون آمدم. برای روز اول خیلی زیاد بود. + +فردا صبح رفتم مدرسه. بچه‌ها با صف‌هاشان به طرف کلاس‌ها می‌رفتند و ناظم چوب به دست توی ایوان ایستاده بود و توی دفتر دو تا از معلم‌ها بودند. معلوم شد کار هر روزه‌شان است. ناظم را هم فرستادم سر یک کلاس دیگر و خودم آمدم دم در مدرسه به قدم زدن؛ فکر کردم از هر طرف که بیایند مرا این ته، دم در مدرسه خواهند دید و تمام طول راه در این خجالت خواهند ماند و دیگر دیر نخواهند آمد. یک سیاهی از ته جاده‌ی جنوبی پیداشد. جوانک بریانتین زده بود. مسلماً او هم مرا می‌دید، ولی آهسته‌تر از آن می‌آمد که یک معلم تأخیر کرده جلوی مدیرش می‌آمد. جلوتر که آمد حتی شنیدم که سوت می‌زد. اما بی‌انصاف چنان سلانه سلانه می‌آمد که دیدم هیچ جای گذشت نیست. اصلاً محل سگ به من نمی‌گذاشت. داشتم از کوره در می‌رفتم که یک مرتبه احساس کردم تغییری در رفتار خود داد و تند کرد. + +به خیر گذشت و گرنه خدا عالم است چه اتفاقی می‌افتاد. سلام که کرد مثل این که می‌خواست چیزی بگوید که پیش دستی کردم: + +- بفرمایید آقا. بفرمایید، بچه‌ها منتظرند. + +واقعاً به خیر گذشت. شاید اتوبوسش دیر کرده. شاید راه‌بندان بوده؛ جاده قرق بوده و باز یک گردن‌کلفتی از اقصای عالم می‌آمده که ازین سفره‌ی مرتضی علی بی‌نصیب نماند. به هر صورت در دل بخشیدمش. چه خوب شد که بد و بی‌راهی نگفتی! که از دور علم افراشته‌ی هیکل معلم کلاس چهارم نمایان شد. از همان ته مرا دیده بود. تقریباً می‌دوید. تحمل این یکی را نداشتم. «بدکاری می‌کنی. اول بسم‌الله و مته به خشخاش!» رفتم و توی دفتر نشستم و خودم را به کاری مشغول کردم که هن هن کنان رسید. چنان عرق از پیشانی‌اش می‌ریخت که راستی خجالت کشیدم. یک لیوان آب از کوه به دستش دادم و مسخ‌شده‌ی خنده‌اش را با آب به خوردش دادم و بلند که شد برود، گفتم: + +- عوضش دو کیلو لاغر شدید. + +برگشت نگاهی کرد و خنده‌ای و رفت. ناگهان ناظم از در وارد شد و از را ه نرسیده گفت: + +- دیدید آقا! این جوری می‌آند مدرسه. اون قرتی که عین خیالش هم نبود آقا! اما این یکی... + +از او پرسیدم: + +- انگار هنوز دو تا از کلاس‌ها ولند؟ + +- بله آقا. کلاس سه ورزش دارند. گفتم بنشینند دیکته بنویسند آقا. معلم حساب پنج و شش هم که نیومده آقا. + +در همین حین یکی از عکس‌های بزرگ دخمه‌های هخامنشی را که به دیوار کوبیده بود پس زد و: + +- نگاه کنید آقا... + +روی گچ دیوار با مداد قرمز و نه چندان درشت، به عجله و ناشیانه علامت داس کشیده بودند. همچنین دنبال کرد: + +- از آثار دوره‌ی اوناست آقا. کارشون همین چیزها بود. روزنومه بفروشند. تبلیغات کنند و داس چکش بکشند آقا. رئیس‌شون رو که گرفتند چه جونی کندم آقا تا حالی‌شون کنم که دست ور دارند آقا. و از روی میز پرید پایین. + +- گفتم مگه باز هم هستند؟ + +- آره آقا، پس چی! یکی همین آقازاده که هنوز نیومده آقا. هر روز نیم ساعت تأخیر داره آقا. یکی هم مثل کلاس سه. + +- خوب چرا تا حالا پاکش نکردی؟ + +- به! آخه آدم درد دلشو واسه‌ی کی بگه؟ آخه آقا در میان تو روی آدم می‌گند جاسوس، مأمور! باهاش حرفم شده آقا. کتک و کتک‌کاری! + +و بعد یک سخنرانی که چه طور مدرسه را خراب کرده‌اند و اعتماد اهل محله را چه طور از بین برده‌اند که نه انجمنی، نه کمکی به بی‌بضاعت‌ها؛ و از این حرف ها. + +بعد از سخنرانی آقای ناظم دستمالم را دادم که آن عکس‌ها را پاک کند و بعد هم راه افتادم که بروم سراغ اتاق خودم. در اتاقم را که باز کردم، داشتم دماغم با بوی خاک نم کشیده‌اش اخت می‌کرد که آخرین معلم هم آمد. آمدم توی ایوان و با صدای بلند، جوری که در تمام مدرسه بشنوند، ناظم را صدا زدم و گفتم با قلم قرمز برای آقا یک ساعت تأخیر بگذارند. + +روز سوم باز اول وقت مدرسه بودم. هنوز از پشت دیوار نپیچیده بودم که صدای سوز و بریز بچه‌ها به پیشبازم آمد. تند کردم. پنج تا از بچه‌ها توی ایوان به خودشان می‌پیچیدند و ناظم ترکه‌ای به دست داشت و به نوبت به کف دست‌شان می‌زد. بچه‌ها التماس می‌کردند؛ گریه می‌کردند؛ اما دستشان را هم دراز می‌کردند. نزدیک بود داد بزنم یا با لگد بزنم و ناظم را پرت کنم آن طرف. پشتش به من بود و من را نمی‌دید. ناگهان زمزمه‌ای توی صف‌ها افتاد که یک مرتبه مرا به صرافت انداخت که در مقام مدیریت مدرسه، به سختی می‌شود ناظم را کتک زد. این بود که خشمم را فرو خوردم و آرام از پله‌ها رفتم بالا. ناظم، تازه متوجه من شده بود در همین حین دخالتم را کردم و خواهش کردم این بار همه‌شان را به من ببخشند. + +نمی‌دانم چه کار خطایی از آنها سر زده بود که ناظم را تا این حد عصبانی کرده بود. بچه‌ها سکسکه‌کنان رفتند توی صف‌ها و بعد زنگ را زدند و صف‌ها رفتند به کلاس‌ها و دنبالشان هم معلم‌ها که همه سر وقت حاضر بودند. نگاهی به ناظم انداختم که تازه حالش سر جا آمده بود و گفتم در آن حالی که داشت، ممکن بود گردن یک کدامشان را بشکند. که مرتبه براق شد: + +- اگه یک روز جلوشونو نگیرید سوارتون می‌شند آقا. نمی‌دونید چه قاطرهای چموشی شده‌اند آقا. + +مثل بچه مدرسه‌ای‌ها آقا آقا می‌کرد. موضوع را برگرداندم و احوال مادرش را پرسیدم. خنده، صورتش را از هم باز کرد و صدا زد فراش برایش آب بیاورد. یادم هست آن روز نیم ساعتی برای آقای ناظم صحبت کردم. پیرانه. و او جوان بود و زود می‌شد رامش کرد. بعد ازش خواستم که ترکه‌ها را بشکند و آن وقت من رفتم سراغ اتاق خودم. + +در همان هفته‌ی اول به کارها وارد شدم. فردای زمستان و نه تا بخاری زغال سنگی و روزی چهار بار آب آوردن و آب و جاروی اتاق‌ها با یک فراش جور در نمی‌آید. یک فراش دیگر از اداره ی فرهنگ خواستم که هر روز منتظر ورودش بودیم. بعد از ظهرها را نمی‌رفتم. روزهای اول با دست و دل لرزان، ولی سه چهار روزه جرأت پیدا کردم. احساس می‌کردم که مدرسه زیاد هم محض خاطر من نمی‌گردد. کلاس اول هم یکسره بود و به خاطر بچه‌های جغله دلهره‌ای نداشتم. در بیابان‌های اطراف مدرسه هم ماشینی آمد و رفت نداشت و گرچه پست و بلند بود اما به هر صورت از حیاط مدرسه که بزرگ‌تر بود. معلم ها هم، هر بعد از ظهری دو تاشان به نوبت می‌رفتند یک جوری باهم کنار آمده بودند. و ترسی هم از این نبود که بچه‌ها از علم و فرهنگ ثقل سرد بکنند. یک روز هم بازرس آمد و نیم ساعتی پیزر لای پالان هم گذاشتیم و چای و احترامات متقابل! و در دفتر بازرسی تصدیق کرد که مدرسه «با وجود عدم وسایل» بسیار خوب اداره می‌شود. + +بچه‌ها مدام در مدرسه زمین می‌خوردند، بازی می‌کردند، زمین می‌خوردند. مثل اینکه تاتوله خورده بودند. ساده‌ترین شکل بازی‌هایشان در ربع ساعت‌های تفریح، دعوا بود. فکر می‌کردم علت این همه زمین خوردن شاید این باشد که بیش‌ترشان کفش حسابی ندارند. آن‌ها هم که داشتند، بچه‌ننه بودند و بلد نبودند بدوند و حتی راه بروند. این بود که روزی دو سه بار، دست و پایی خراش بر می‌داشت. پرونده‌ی برق و تلفن مدرسه را از بایگانی بسیار محقر مدرسه بیرون کشیده بودم و خوانده بودم. اگر یک خرده می‌دویدی تا دو سه سال دیگر هم برق مدرسه درست می‌شد و هم تلفنش. دوباره سری به اداره ساختمان زدم و موضوع را تازه کردم و به رفقایی که دورادور در اداره‌ی برق و تلفن داشتم، یکی دو بار رو انداختم که اول خیال می‌کردند کار خودم را می‌خواهم به اسم مدرسه راه بیندازم و ناچار رها کردم. این قدر بود که ادای وظیفه‌ای می‌کرد. مدرسه آب نداشت. نه آب خوراکی و نه آب جاری. با هرزاب بهاره، آب انبار زیر حوض را می‌انباشتند که تلمبه‌ای سرش بود و حوض را با همان پر می‌کردند و خود بچه‌ها. اما برای آب خوردن دو تا منبع صد لیتری داشتیم از آهن سفید که مثل امامزاده‌ای یا سقاخانه‌ای دو قلو، روی چهار پایه کنار حیاط بود و روزی دو بار پر و خالی می‌شد. این آب را از همان باغی می‌آوردیم که ردیف کاج‌هایش روی آسمان، لکه‌ی دراز سیاه انداخته بود. البته فراش می‌آورد. با یک سطل بزرگ و یک آب‌پاش که سوراخ بود و تا به مدرسه می‌رسید، نصف شده بود. هر دو را از جیب خودم دادم تعمیر کردند. + +یک روز هم مالک مدرسه آمد. پیرمردی موقر و سنگین که خیال می‌کرد برای سرکشی به خانه‌ی مستأجرنشینش آمده. از در وارد نشده فریادش بلند شد و فحش را کشید به فراش و به فرهنگ که چرا بچه‌ها دیوار مدرسه را با زغال سیاه کرده‌اند واز همین توپ و تشرش شناختمش. کلی با او صحبت کردیم البته او دو برابر سن من را داشت. برایش چای هم آوردیم و با معلم‌ها آشنا شد و قول‌ها داد و رفت. کنه‌ای بود. درست یک پیرمرد. یک ساعت و نیم درست نشست. ماهی یک بار هم این برنامه را داشتند که بایست پیه‌اش را به تن می‌مالیدم. + +اما معلم‌ها. هر کدام یک ابلاغ بیست و چهار ساعته در دست داشتند، ولی در برنامه به هر کدام‌شان بیست ساعت درس بیشتر نرسیده بود. کم کم قرار شد که یک معلم از فرهنگ بخواهیم و به هر کدام‌شان هجده ساعت درس بدهیم، به شرط آن‌که هیچ بعد از ظهری مدرسه تعطیل نباشد. حتی آن که دانشگاه می‌رفت می‌توانست با هفته‌ای هجده ساعت درس بسازد. و دشوارترین کار همین بود که با کدخدامنشی حل شد و من یک معلم دیگر از فرهنگ خواستم. + +اواخر هفته‌ی دوم، فراش جدید آمد. مرد پنجاه ساله‌ای باریک و زبر و زرنگ که شب‌کلاه می‌گذاشت و لباس آبی می‌پوشید و تسبیح می‌گرداند و از هر کاری سر رشته داشت. آب خوردن را نوبتی می‌آوردند. مدرسه تر و تمیز شد و رونقی گرفت. فراش جدید سرش توی حساب بود. هر دو مستخدم با هم تمام بخاری‌ها را راه انداختند و یک کارگر هم برای کمک به آن‌ها آمد. فراش قدیمی را چهار روز پشت سر هم، سر ظهر می‌فرستادیم اداره‌ی فرهنگ و هر آن منتظر زغال بودیم. هنوز یک هفته از آمدن فراش جدید نگذشته بود که صدای همه‌ی معلم‌ها در آمده بود. نه به هیچ کدامشان سلام می‌کرد و نه به دنبال خرده فرمایش‌هایشان می‌رفت. درست است که به من سلام می‌کرد، اما معلم‌ها هم، لابد هر کدام در حدود من صاحب فضایل و عنوان و معلومات بودند که از یک فراش مدرسه توقع سلام داشته باشند. اما انگار نه انگار. + +بدتر از همه این که سر خر معلم‌ها بود. من که از همان اول، خرجم را سوا کرده بودم و آن‌ها را آزاد گذاشته بودم که در مواقع بیکاری در دفتر را روی خودشان ببندند و هر چه می‌خواهند بگویند و هر کاری می‌خواهند بکنند. اما او در فاصله‌ی ساعات درس، همچه که معلم‌ها می‌آمدند، می‌آمد توی دفتر و همین طوری گوشه‌ی اتاق می‌ایستاد و معلم‌ها کلافه می‌شدند. نه می‌توانستند شلکلک‌های معلمی‌شان را در حضور او کنار بگذارند و نه جرأت می‌کردند به او چیزی بگویند. بدزبان بود و از عهده‌ی همه‌شان بر می‌آمد. یکی دوبار دنبال نخود سیاه فرستاده بودندش. اما زرنگ بود و فوری کار را انجام می‌داد و بر می‌گشت. حسابی موی دماغ شده بود. ده سال تجربه این حداقل را به من آموخته بود که اگر معلم‌ها در ربع ساعت‌های تفریح نتوانند بخندند، سر کلاس، بچه‌های مردم را کتک خواهند زد. این بود که دخالت کردم. یک روز فراش جدید را صدا زدم. اول حال و احوالپرسی و بعد چند سال سابقه دارد و چند تا بچه و چه قدر می‌گیرد... که قضیه حل شد. سی صد و خرده‌ای حقوق می‌گرفت. با بیست و پنج سال سابقه. کار از همین جا خراب بود. پیدا بود که معلم‌ها حق دارند او را غریبه بدانند. نه دیپلمی، نه کاغذپاره‌ای، هر چه باشد یک فراش که بیشتر نبود! و تازه قلدر هم بود و حق هم داشت. اول به اشاره و کنایه و بعد با صراحت بهش فهماندم که گر چه معلم جماعت اجر دنیایی ندارد، اما از او که آدم متدین و فهمیده‌ای است بعید است و از این حرف‌ها... که یک مرتبه پرید توی حرفم که: + +- ای آقا! چه می‌فرمایید؟ شما نه خودتون این کاره‌اید و نه اینارو می‌شناسید. امروز می‌خواند سیگار براشون بخرم، فردا می‌فرستنم سراغ عرق. من این‌ها رو می‌شناسم. + +راست می‌گفت. زودتر از همه، او دندان‌های مرا شمرده بود. فهمیده بود که در مدرسه هیچ‌کاره‌ام. می‌خواستم کوتاه بیایم، ولی مدیر مدرسه بودن و در مقابل یک فراش پررو ساکت ماندن!... که خر خر کامیون زغال به دادم رسید. ترمز که کرد و صدا خوابید گفتم: + +- این حرف‌ها قباحت داره. معلم جماعت کجا پولش به عرق می‌رسه؟ حالا بدو زغال آورده‌اند. + +و همین طور که داشت بیرون می‌رفت، افزودم: + +- دو روز دیگه که محتاجت شدند و ازت قرض خواستند با هم رفیق می‌شید. + +و آمدم توی ایوان. در بزرگ آهنی مدرسه را باز کرده بودند و کامیون آمده بود تو و داشتند بارش را جلوی انبار ته حیاط خالی می‌کردند و راننده، کاغذی به دست ناظم داد که نگاهی به آن انداخت و مرا نشان داد که در ایوان بالا ایستاده بودم و فرستادش بالا. کاغذش را با سلام به دستم داد. بیجک زغال بود. رسید رسمی اداره‌ی فرهنگ بود در سه نسخه و روی آن ورقه‌ی ماشین شده‌ی «باسکول» که می‌گفت کامیون و محتویاتش جمعاً دوازده خروار است. اما رسیدهای رسمی اداری فرهنگ ساکت بودند. جای مقدار زغالی که تحویل مدرسه داده شده بود، در هر سه نسخه خالی بود. پیدا بود که تحویل گیرنده باید پرشان کند. همین کار را کردم. اوراق را بردم توی اتاق و با خودنویسم عدد را روی هر سه ورق نوشتم و امضا کردم و به دست راننده دادم که راه افتاد و از همان بالا به ناظم گفتم: + +- اگر مهر هم بایست زد، خودت بزن بابا. + +و رفتم سراغ کارم که ناگهان در باز شد و ناظم آمد تو؛ بیجک زغال دستش بود و: + +- مگه نفهمیدین آقا؟ مخصوصاً جاش رو خالی گذاشته بودند آقا... + +نفهمیده بودم. اما اگر هم فهمیده بودم، فرقی نمی‌کرد و به هر صورت از چنین کودنی نا به هنگام از جا در رفتم و به شدت گفتم: + +- خوب؟ + +- هیچ چی آقا.... رسم‌شون همینه آقا. اگه باهاشون کنار نیایید کارمونو لنگ می‌گذارند آقا... + +که از جا در رفتم. به چنین صراحتی مرا که مدیر مدرسه بودم در معامله شرکت می‌داد. و فریاد زدم: + +- عجب! حالا سرکار برای من تکلیف هم معین می‌کنید؟... خاک بر سر این فرهنگ با مدیرش که من باشم! برو ورقه رو بده دست‌شون، گورشون رو گم کنند. پدر سوخته‌ها... + +چنان فریاد زده بودم که هیچ کس در مدرسه انتظار نداشت. مدیر سر به زیر و پا به راهی بودم که از همه خواهش می‌کردم و حالا ناظم مدرسه، داشت به من یاد می‌داد که به جای نه خروار زغال مثلا هجده خروار تحویل بگیرم و بعد با اداره‌ی فرهنگ کنار بیایم. هی هی!.... تا ظهر هیچ کاری نتوانستم بکنم، جز این‌که چند بار متن استعفانامه‌ام را بنویسم و پاره کنم... قدم اول را این جور جلوی پای آدم می‌گذارند. + +بارندگی که شروع شد دستور دادم بخاری‌ها را از هفت صبح بسوزانند. بچه‌ها همیشه زود می‌آمدند. حتی روزهای بارانی. مثل این‌که اول آفتاب از خانه بیرون‌شان می‌کنند. یا ناهارنخورده. خیلی سعی کردم یک روز زودتر از بچه‌ها مدرسه باشم. اما عاقبت نشد که مدرسه را خالی از نفسِ به علم‌آلوده‌ی بچه‌ها استنشاق کنم. از راه که می‌رسیدند دور بخاری جمع می‌شدند و گیوه‌هاشان را خشک می‌کردند. و خیلی زود فهمیدم که ظهر در مدرسه ماندن هم مسأله کفش بود. هر که داشت نمی‌ماند.این قاعده در مورد معلم‌ها هم صدق می‌کرد اقلاً یک پول واکس جلو بودند. وقتی که باران می‌بارید تمام کوهپایه و بدتر از آن تمام حیاط مدرسه گل می‌شد. بازی و دویدن متوقف شده بود. مدرسه سوت و کور بود. این جا هم مسأله کفش بود. چشم اغلبشان هم قرمز بود. پیدا بود باز آن روز صبح یک فصل گریه کرده‌اند و در خانه‌شان علم صراطی بوده است. + +مدرسه داشت تخته می‌شد. عده‌ی غایب‌های صبح ده برابر شده بود و ساعت اول هیچ معلمی نمی‌توانست درس بدهد. دست‌های ورم‌کرده و سرمازده کار نمی‌کرد. حتی معلم کلاس اولمان هم می‌دانست که فرهنگ و معلومات مدارس ما صرفاً تابع تمرین است. مشق و تمرین. ده بار بیست بار. دست یخ‌کرده بیل و رنده را هم نمی‌تواند به کار بگیرد که خیلی هم زمخت‌اند و دست پر کن. این بود که به فکر افتادیم. فراش جدید واردتر از همه‌ی ما بود. یک روز در اتاق دفتر، شورامانندی داشتیم که البته او هم بود. خودش را کم‌کم تحمیل کرده بود. گفت حاضر است یکی از دُم‌کلفت‌های همسایه‌ی مدرسه را وادارد که شن برایمان بفرستد به شرط آن که ما هم برویم و از انجمن محلی برای بچه‌ها کفش و لباس بخواهیم. قرار شد خودش قضیه را دنبال کند که هفته‌ی آینده جلسه‌شان کجاست و حتی بخواهد که دعوت‌مانندی از ما بکنند. دو روز بعد سه تا کامیون شن آمد. دوتایش را توی حیاط مدرسه، خالی کردیم و سومی را دم در مدرسه، و خود بچه‌ها نیم ساعته پهنش کردند. با پا و بیل و هر چه که به دست می‌رسید. + +عصر همان روز ما را به انجمن دعوت کردند. خود من و ناظم باید می‌رفتیم. معلم کلاس چهارم را هم با خودمان بردیم. خانه‌ای که محل جلسه‌ی آن شب انجمن بود، درست مثل مدرسه، دور افتاده و تنها بود. قالی‌ها و کناره‌ها را به فرهنگ می‌آلودیم و می‌رفتیم. مثل این‌که سه تا سه تا روی هم انداخته بودند. اولی که کثیف شد دومی. به بالا که رسیدیم یک حاجی آقا در حال نماز خواندن بود. و صاحب‌خانه با لهجه‌ی غلیظ یزدی به استقبال‌مان آمد. همراهانم را معرفی کردم و لابد خودش فهمید مدیر کیست. برای ما چای آوردند. سیگارم را چاق کردم و با صاحب‌خانه از قالی‌هایش حرف زدیم. ناظم به بچه‌هایی می‌ماند که در مجلس بزرگترها خوابشان می‌گیرد و دل‌شان هم نمی‌خواست دست به سر شوند. سر اعضای انجمن باز شده بود. حاجی آقا صندوقدار بود. من و ناظم عین دو طفلان مسلم بودیم و معلم کلاس چهارم عین خولی وسطمان نشسته. اغلب اعضای انجمن به زبان محلی صحبت می‌کردند و رفتار ناشی داشتند. حتی یک کدامشان نمی‌دانستند که دست و پاهای خود را چه جور ضبط و ربط کنند. بلند بلند حرف می‌زدند. درست مثل این‌که وزارتخانه‌ی دواب سه تا حیوان تازه برای باغ وحش محله‌شان وارد کرده. جلسه که رسمی شد، صاحبخانه معرفی‌مان کرد و شروع کردند. مدام از خودشان صحبت می‌کردند از این‌که دزد دیشب فلان جا را گرفته و باید درخواست پاسبان شبانه کنیم و... + +همین طور یک ساعت حرف زدند و به مهام امور رسیدگی کردند و من و معلم کلاس چهارم سیگار کشیدیم. انگار نه انگار که ما هم بودیم. نوکرشان که آمد استکان‌ها را جمع کند، چیزی روی جلد اشنو نوشتم و برای صاحبخانه فرستادم که یک مرتبه به صرافت ما افتاد و اجازه خواست و: + +- آقایان عرضی دارند. بهتر است کارهای خودمان را بگذاریم برای بعد. + +مثلاً می‌خواست بفهماند که نباید همه‌ی حرف‌ها را در حضور ما زده باشند. و اجازه دادند معلم کلاس چهار شروع کرد به نطق و او هم شروع کرد که هر چه باشد ما زیر سایه‌ی آقایانیم و خوش‌آیند نیست که بچه‌هایی باشند که نه لباس داشته باشند و نه کفش درست و حسابی و از این حرف‌ها و مدام حرف می‌زد. ناظم هم از چُرت در آمد چیزهایی را که از حفظ کرده بود گفت و التماس دعا و کار را خراب کرد.تشری به ناظم زدم که گدابازی را بگذارد کنار و حالی‌شان کردم که صحبت از تقاضا نیست و گدایی. بلکه مدرسه دور افتاده است و مستراح بی در و پیکر و از این اباطیل... چه خوب شد که عصبانی نشدم. و قرار شد که پنج نفرشان فردا عصر بیایند که مدرسه را وارسی کنند و تشکر و اظهار خوشحالی و در آمدیم. + +در تاریکی بیابان هفت تا سواری پشت در خانه ردیف بودند و راننده‌ها توی یکی از آن‌ها جمع شده بودند و اسرار ارباب‌هاشان را به هم می‌گفتند. در این حین من مدام به خودم می‌گفتم من چرا رفتم؟ به من چه؟ مگر من در بی کفش و کلاهی‌شان مقصر بودم؟ می‌بینی احمق؟ مدیر مدرسه هم که باشی باید شخصیت و غرورت را لای زرورق بپیچی و طاق کلاهت بگذاری که اقلاً نپوسد. حتی اگر بخواهی یک معلم کوفتی باشی، نه چرا دور می‌زنی؟ حتی اگر یک فراش ماهی نود تومانی باشی، باید تا خرخره توی لجن فرو بروی.در همین حین که من در فکر بودم ناظم گفت: + +- دیدید آقا چه طور باهامون رفتار کردند؟ با یکی از قالی‌هاشون آقا تمام مدرسه رو می‌خرید. + +گفتم: + +- تا سر و کارت با الف.ب است به‌پا قیاس نکنی. خودخوری می‌آره. + +و معلم کلاس چهار گفت: + +- اگه فحشمون هم می‌دادند من باز هم راضی بودم، باید واقع‌بین بود. خدا کنه پشیمون نشند. + +بعد هم مدتی درد دل کردیم و تا اتوبوس برسد و سوار بشیم، معلوم شد که معلم کلاس چهار با زنش متارکه کرده و مادر ناظم را سرطانی تشخیص دادند. و بعد هم شب بخیر... + +دو روز تمام مدرسه نرفتم. خجالت می‌کشیدم توی صورت یک کدام‌شان نگاه کنم. و در همین دو روز حاجی آقا با دو نفر آمده بودند، مدرسه را وارسی و صورت‌برداری و ناظم می‌گفت که حتی بچه‌هایی هم که کفش و کلاهی داشتند پاره و پوره آمده بودند. و برای بچه‌ها کفش و لباس خریدند. روزهای بعد احساس کردم زن‌هایی که سر راهم لب جوی آب ظرف می‌شستند، سلام می‌کنند و یک بار هم دعای خیر یکی‌شان را از عقب سر شنیدم.اما چنان از خودم بدم آمده بود که رغبتم نمی‌شد به کفش و لباس‌هاشان نگاه کنم. قربان همان گیوه‌های پاره! بله، نان گدایی فرهنگ را نو نوار کرده بود. + +تازه از دردسرهای اول کار مدرسه فارغ شده بودم که شنیدم که یک روز صبح، یکی از اولیای اطفال آمد. بعد از سلام و احوالپرسی دست کرد توی جیبش و شش تا عکس در آورد، گذاشت روی میزم. شش تا عکس زن لخت. لخت لخت و هر کدام به یک حالت. یعنی چه؟ نگاه تندی به او کردم. آدم مرتبی بود. اداری مانند. کسر شأن خودم می‌دانستم که این گوشه‌ی از زندگی را طبق دستور عکاس‌باشی فلان جنده‌خانه‌ی بندری ببینم. اما حالا یک مرد اتو کشیده‌ی مرتب آمده بود و شش تا از همین عکس‌ها را روی میزم پهن کرده بود و به انتظار آن که وقاحت عکس‌ها چشم‌هایم را پر کند داشت سیگار چاق می‌کرد. + +حسابی غافلگیر شده بودم... حتماً تا هر شش تای عکس‌ها را ببینم، بیش از یک دقیقه طول کشید. همه از یک نفر بود. به این فکر گریختم که الان هزار ها یا میلیون ها نسخه‌ی آن، توی جیب چه جور آدم‌هایی است و در کجاها و چه قدر خوب بود که همه‌ی این آدم‌ها را می‌شناختم یا می‌دیدم. بیش ازین نمی‌شد گریخت. یارو به تمام وزنه وقاحتش، جلوی رویم نشسته بود. سیگاری آتش زدم و چشم به او دوختم. کلافه بود و پیدا بود برای کتک‌کاری هم آماده باشد. سرخ شده بود و داشت در دود سیگارش تکیه‌گاهی برای جسارتی که می‌خواست به خرج بدهد می‌جست. عکس‌ها را با یک ورقه از اباطیلی که همان روز سیاه کرده بودم، پوشاندم و بعد با لحنی که دعوا را با آن شروع می‌کنند؛ پرسیدم: + +- خوب، غرض؟ + +و صدایم توی اتاق پیچید. حرکتی از روی بیچارگی به خودش داد و همه‌ی جسارت‌ها را با دستش توی جیبش کرد و آرام‌تر از آن چیزی که با خودش تو آورده بود، گفت: + +- چه عرض کنم؟... از معلم کلاس پنج تون بپرسید. + +که راحت شدم و او شروع کرد به این که «این چه فرهنگی است؟ خراب بشود. پس بچه‌های مردم با چه اطمینانی به مدرسه بیایند؟ + +و از این حرف‌ها... + +خلاصه این آقا معلم کاردستی کلاس پنجم، این عکس‌ها را داده به پسر آقا تا آن‌ها را روی تخته سه لایی بچسباند و دورش را سمباده بکشد و بیاورد. به هر صورت معلم کلاس پنج بی‌گدار به آب زده. و حالا من چه بکنم؟ به او چه جوابی بدهم؟ بگویم معلم را اخراج می‌کنم؟ که نه می‌توانم و نه لزومی دارد. او چه بکند؟ حتماً در این شهر کسی را ندارد که به این عکس‌ها دلخوش کرده. ولی آخر چرا این جور؟ یعنی این قدر احمق است که حتی شاگردهایش را نمی‌شناسد؟... پاشدم ناظم را صدا بزنم که خودش آمده بود بالا، توی ایوان منتظر ایستاده بود. من آخرین کسی بودم که از هر اتفاقی در مدرسه خبردار می‌شدم. حضور این ولی طفل گیجم کرده بود که چنین عکس‌هایی را از توی جیب پسرش، و لابد به همین وقاحتی که آن‌ها را روی میز من ریخت، در آورده بوده. وقتی فهمید هر دو در مانده‌ایم سوار بر اسب شد که اله می‌کنم و بله می‌کنم، در مدرسه را می‌بندم، و از این جفنگیات.... + +حتماً نمی‌دانست که اگر در هر مدرسه بسته بشود، در یک اداره بسته شده است. اما من تا او بود نمی‌توانستم فکرم را جمع کنم. می‌خواست پسرش را بخواهیم تا شهادت بدهد و چه جانی کندیم تا حالیش کنیم که پسرش هر چه خفت کشیده، بس است و وعده‌ها دادیم که معلمش را دم خورشید کباب کنیم و از نان خوردن بیندازیم. یعنی اول ناظم شروع کرد که از دست او دل پری داشت و من هم دنبالش را گرفتم. برای دک کردن او چاره‌ای جز این نبود. و بعد رفت، ما دو نفری ماندیم با شش تا عکس زن لخت. حواسم که جمع شد به ناظم سپردم صدایش را در نیاورد و یک هفته‌ی تمام مطلب را با عکس‌ها، توی کشوی میزم قفل کردم و بعد پسرک را صدا زدم. نه عزیزدُردانه می‌نمود و نه هیچ جور دیگر. داد می‌زد که از خانواده‌ی عیال‌واری است. کم‌خونی و فقر. دیدم معلمش زیاد هم بد تشخیص نداده. یعنی زیاد بی‌گدار به آب نزده. گفتم: + +- خواهر برادر هم داری؟ + +- آ... آ...آقا داریم آقا. + +- چند تا؟ + +- آ... آقا چهار تا آقا. + +- عکس‌ها رو خودت به بابات نشون دادی؟ + +- نه به خدا آقا... به خدا قسم... + +- پس چه طور شد؟ + +و دیدم از ترس دارد قالب تهی می‌کند. گرچه چوب‌های ناظم شکسته بود، اما ترس او از من که مدیر باشم و از ناظم و از مدرسه و از تنبیه سالم مانده بود. + +- نترس بابا. کاریت نداریم. تقصیر آقا معلمه که عکس‌ها رو داده... تو کار بدی نکردی بابا جان. فهمیدی؟ اما می‌خواهم ببینم چه طور شد که عکس‌ها دست بابات افتاد. + +- آ.. آ... آخه آقا... آخه... + +می‌دانستم که باید کمکش کنم تا به حرف بیاید. + +گفتم: + +- می‌دونی بابا؟ عکس‌هام چیز بدی نبود. تو خودت فهمیدی چی بود؟ + +- آخه آقا...نه آقا.... خواهرم آقا... خواهرم می‌گفت... + +- خواهرت؟ از تو کوچک‌تره؟ + +- نه آقا. بزرگ‌تره. می‌گفتش که آقا... می‌گفتش که آقا... هیچ چی سر عکس‌ها دعوامون شد. + +دیگر تمام بود. عکس‌ها را به خواهرش نشان داده بود که لای دفترچه پر بوده از عکس آرتیست‌ها. به او پز داده بوده. اما حاضر نبوده، حتی یکی از آن‌ها را به خواهرش بدهد. آدم مورد اعتماد معلم باشد و چنین خبطی بکند؟ و تازه جواب معلم را چه بدهد؟ ناچار خواهر او را لو داده بوده. بعد از او معلم را احضار کردم. علت احضار را می‌دانست. و داد می‌زد که چیزی ندارد بگوید. پس از یک هفته مهلت، هنوز از وقاحتی که من پیدا کرده بودم، تا از آدم خلع سلاح‌شده‌ای مثل او، دست بر ندارم، در تعجب بود. به او سیگار تعارف کردم و این قصه را برایش تعریف کردم که در اوایل تأسیس وزارت معارف، یک روز به وزیر خبر می‌دهند که فلان معلم با فلان بچه روابطی دارد. وزیر فوراً او را می‌خواهد و حال و احوال او را می‌پرسد و این‌که چرا تا به حال زن نگرفته و ناچار تقصیر گردن بی‌پولی می‌افتد و دستور که فلان قدر به او کمک کنند تا عروسی راه بیندازد و خود او هم دعوت بشود و قضیه به همین سادگی تمام می‌شود. و بعد گفتم که خیلی جوان‌ها هستند که نمی‌توانند زن بگیرند و وزرای فرهنگ هم این روزها گرفتار مصاحبه‌های روزنامه‌ای و رادیویی هستند. اما در نجیب‌خانه‌ها که باز است و ازین مزخرفات... و هم‌دردی و نگذاشتم یک کلمه حرف بزند. بعد هم عکس را که توی پاکت گذاشته بودم، به دستش دادم و وقاحت را با این جمله به حد اعلا رساندم که: + +- اگر به تخته نچسبونید، ضررشون کم‌تره. + +تا حقوقم به لیست اداره‌ی فرهنگ برسه، سه ماه طول کشید. فرهنگی‌های گداگشنه و خزانه‌ی خالی و دست‌های از پا درازتر! اما خوبیش این بود که در مدرسه‌ی ما فراش جدیدمان پولدار بود و به همه‌شان قرض داد. کم کم بانک مدرسه شده بود. از سیصد و خرده‌ای تومان که می‌گرفت، پنجاه تومان را هم خرج نمی‌کرد. نه سیگار می‌کشید و نه اهل سینما بود و نه برج دیگری داشت. از این گذشته، باغبان یکی از دم‌کلفت‌های همان اطراف بود و باغی و دستگاهی و سور و ساتی و لابد آشپزخانه‌ی مرتبی. خیلی زود معلم‌ها فهمیدند که یک فراش پولدار خیلی بیش‌تر به درد می‌خورد تا یک مدیر بی‌بو و خاصیت. + +این از معلم‌ها. حقوق مرا هم هنوز از مرکز می‌دادند. با حقوق ماه بعد هم اسم مرا هم به لیست اداره منتقل کردند. درین مدت خودم برای خودم ورقه انجام کار می‌نوشتم و امضا می‌کردم و می‌رفتم از مدرسه‌ای که قبلاً در آن درس می‌دادم، حقوقم را می‌گرفتم. سر و صدای حقوق که بلند می‌شد معلم‌ها مرتب می‌شدند و کلاس ماهی سه چهار روز کاملاً دایر بود. تا ورقه‌ی انجام کار به دستشان بدهم. غیر از همان یک بار - در اوایل کار- که برای معلم حساب پنج و شش قرمز توی دفتر گذاشتیم، دیگر با مداد قرمز کاری نداشتیم و خیال همه‌شان راحت بود. وقتی برای گرفتن حقوقم به اداره رفتم، چنان شلوغی بود که به خودم گفتم کاش اصلاً حقوقم را منتقل نکرده بودم. نه می‌توانستم سر صف بایستم و نه می‌توانستم از حقوقم بگذرم. تازه مگر مواجب‌بگیر دولت چیزی جز یک انبان گشاده‌ی پای صندوق است؟..... و اگر هم می‌ماندی با آن شلوغی باید تا دو بعداز ظهر سر پا بایستی. همه‌ی جیره‌خوارهای اداره بو برده بودند که مدیرم. و لابد آن‌قدر ساده لوح بودند که فکر کنند روزی گذارشان به مدرسه‌ی ما بیفتد. دنبال سفته‌ها می‌گشتند، به حسابدار قبلی فحش می‌دادند، التماس می‌کردند که این ماه را ندیده بگیرید و همه‌ی حق و حساب‌دان شده بودند و یکی که زودتر از نوبت پولش را می‌گرفت صدای همه در می‌آمد. در لیست مدرسه، بزرگ‌ترین رقم مال من بود. درست مثل بزرگ‌ترین گناه در نامه‌ی عمل. دو برابر فراش جدیدمان حقوق می‌گرفتم. از دیدن رقم‌های مردنی حقوق دیگران چنان خجالت کشیدم که انگار مال آن‌ها را دزدیده‌ام. و تازه خلوت که شد و ده پانزده تا امضا که کردم، صندوق‌دار چشمش به من افتاد و با یک معذرت، شش صد تومان پول دزدی را گذاشت کف دستم... مرده شور! + +هنوز برف اول نباریده بود که یک روز عصر، معلم کلاس چهار رفت زیر ماشین. زیر یک سواری. مثل همه‌ی عصرها من مدرسه نبودم. دم غروب بود که فراش قدیمی مدرسه دم در خونه‌مون، خبرش را آورد. که دویدم به طرف لباسم و تا حاضر بشوم، می‌شنیدم که دارد قضیه را برای زنم تعریف می‌کند. ماشین برای یکی از آمریکایی‌ها بوده. باقیش را از خانه که در آمدیم برایم تعریف کرد. گویا یارو خودش پشت فرمون بوده و بعد هم هول شده و در رفته. بچه‌ها خبر را به مدرسه برگردانده‌اند و تا فراش و زنش برسند، جمعیت و پاسبان‌ها سوارش کرده بودند و فرستاده بوده‌اند مریض‌خانه. به اتوبوس که رسیدم، دیدم لاک پشت است. فراش را مرخص کردم و پریدم توی تاکسی. اول رفتم سراغ پاسگاه جدید کلانتری. تعاریف تکه و پاره‌ای از پرونده مطلع بود. اما پرونده تصریحی نداشت که راننده که بوده. اما هیچ کس نمی‌دانست عاقبت چه بلایی بر سر معلم کلاس چهار ما آمده است. کشیک پاسگاه همین قدر مطلع بود که درین جور موارد «طبق جریان اداری» اول می‌روند سرکلانتری، بعد دایره‌ی تصادفات و بعد بیمارستان. اگر آشنا در نمی‌آمدیم، کشیک پاسگاه مسلماً نمی‌گذاشت به پرونده نگاه چپ بکنم. احساس کردم میان اهل محل کم‌کم دارم سرشناس می‌شوم. و از این احساس خنده‌ام گرفت. + +ساعت ۸ دم در بیمارستان بودم، اگر سالم هم بود حتماً یه چیزیش شده بود. همان طور که من یه چیزیم می‌شد. روی در بیمارستان نوشته شده بود: «از ساعت ۷ به بعد ورود ممنوع». در زدم. از پشت در کسی همین آیه را صادر کرد. دیدم فایده ندارد و باید از یک چیزی کمک بگیرم. از قدرتی، از مقامی، از هیکلی، از یک چیزی. صدایم را کلفت کردم و گفتم:« من...» می‌خواستم بگویم من مدیر مدرسه‌ام. ولی فوراً پشیمان شدم. یارو لابد می‌گفت مدیر مدرسه کدام سگی است؟ این بود با کمی مکث و طمطراق فراوان جمله‌ام را این طور تمام کردم: + +- ...بازرس وزارت فرهنگم. + +که کلون صدایی کرد و لای در باز شد. یارو با چشم‌هایش سلام کرد. رفتم تو و با همان صدا پرسیدم: + +- این معلمه مدرسه که تصادف کرده... + +تا آخرش را خواند. یکی را صدا زد و دنبالم فرستاد که طبقه‌ی فلان، اتاق فلان. از حیاط به راهرو و باز به حیاط دیگر که نصفش را برف پوشانده بود و من چنان می‌دویدم که یارو از عقب سرم هن هن می‌کرد. طبقه‌ی اول و دوم و چهارم. چهار تا پله یکی. راهرو تاریک بود و پر از بوهای مخصوص بود. هن هن کنان دری را نشان داد که هل دادم و رفتم تو. بو تندتر بود و تاریکی بیشتر. تالاری بود پر از تخت و جیرجیر کفش و خرخر یک نفر. دور یک تخت چهار نفر ایستاده بودند. حتماً خودش بود. پای تخت که رسیدم، احساس کردم همه‌ی آنچه از خشونت و تظاهر و ابهت به کمک خواسته بودم آب شد و بر سر و صورتم راه افتاد. و این معلم کلاس چهارم مدرسه‌ام بود. سنگین و با شکم بر آمده دراز کشیده بود. خیلی کوتاه‌تر از زمانی که سر پا بود به نظرم آمد. صورت و سینه‌اش از روپوش چرک‌مُرد بیرون بود. صورتش را که شسته بودند کبود کبود بود، درست به رنگ جای سیلی روی صورت بچه‌ها. مرا که دید، لبخند و چه لبخندی! شاید می‌خواست بگوید مدرسه‌ای که مدیرش عصرها سر کار نباشد، باید همین جورها هم باشد. خنده توی صورت او همین طور لرزید و لرزید تا یخ زد. + +«آخر چرا تصادف کردی؟...» + +مثل این که سوال را ازو کردم. اما وقتی که دیدم نمی‌تواند حرف بزند و به جای هر جوابی همان خنده‌ی یخ‌بسته را روی صورت دارد، خودم را به عنوان او دم چک گرفتم. «آخه چرا؟ چرا این هیکل مدیر کلی را با خودت این قد این ور و آن ور می‌بری تا بزنندت؟ تا زیرت کنند؟ مگر نمی‌دانستی که معلم حق ندارد این قدر خوش‌هیکل باشد؟ آخر چرا تصادف کردی؟» به چنان عتاب و خطابی این‌ها را می‌گفتم که هیچ مطمئن نیستم بلند بلند به خودش نگفته باشم. و یک مرتبه به کله‌ام زد که «مبادا خودت چشمش زده باشی؟» و بعد: «احمق خاک بر سر! بعد از سی و چند سال عمر، تازه خرافاتی شدی!» و چنان از خودم بیزاریم گرفت که می‌خواستم به یکی فحش بدهم، کسی را بزنم. که چشمم به دکتر کشیک افتاد. + +- مرده شور این مملکتو ببره. ساعت چهار تا حالا از تن این مرد خون می‌ره. حیفتون نیومد؟... + +دستی روی شانه‌ام نشست و فریادم را خواباند. برگشتم پدرش بود. او هم می‌خندید. دو نفر دیگر هم با او بودند. همه دهاتی‌وار؛ همه خوش قد و قواره. حظ کردم! آن دو تا پسرهایش بودند یا برادرزاده‌هایش یا کسان دیگرش. تازه داشت گل از گلم می‌شکفت که شنیدم: + +- آقا کی باشند؟ + +این راهم دکتر کشیک گفت که من باز سوار شدم: + +- مرا می‌گید آقا؟ من هیشکی. یک آقا مدیر کوفتی. این هم معلمم. + +که یک مرتبه عقل هی زد و «پسر خفه شو» و خفه شدم. بغض توی گلویم بود. دلم می‌خواست یک کلمه دیگر بگوید. یک کنایه بزند... نسبت به مهارت هیچ دکتری تا کنون نتوانسته‌ام قسم بخورم. دستش را دراز کرد که به اکراه فشار دادم و بعد شیشه‌ی بزرگی را نشانم داد که وارونه بالای تخت آویزان بود و خرفهمم کرد که این جوری غذا به او می‌رسانند و عکس هم گرفته‌اند و تا فردا صبح اگر زخم‌ها چرک نکند، جا خواهند انداخت و گچ خواهند کرد. که یکی دیگر از راه رسید. گوشی به دست و سفید پوش و معطر. با حرکاتی مثل آرتیست سینما. سلامم کرد. صدایش در ته ذهنم چیزی را مختصر تکانی داد. اما احتیاجی به کنجکاوی نبود. یکی از شاگردهای نمی‌دانم چند سال پیشم بود. خودش خودش را معرفی کرد. آقای دکتر...! عجب روزگاری! هر تکه از وجودت را با مزخرفی از انبان مزخرفاتت، مثل ذره‌ای روزی در خاکی ریخته‌ای که حالا سبز کرده. چشم داری احمق. این تویی که روی تخت دراز کشیده‌ای. ده سال آزگار از پلکان ساعات و دقایق عمرت هر لحظه یکی بالا رفته و تو فقط خستگی این بار را هنوز در تن داری. این جوجه‌فکلی و جوجه‌های دیگر که نمی‌شناسی‌شان، همه از تخمی سر در آورده‌اند که روزی حصار جوانی تو بوده و حالا شکسته و خالی مانده. دستش را گرفتم و کشیدمش کناری و در گوشش هر چه بد و بی‌راه می‌دانستم، به او و همکارش و شغلش دادم. مثلاً می‌خواستم سفارش معلم کلاس چهار مدرسه‌ام را کرده باشم. بعد هم سری برای پدر تکان دادم و گریختم. از در که بیرون آمدم، حیاط بود و هوای بارانی. از در بزرگ که بیرون آمدم به این فکر می‌کردم که «اصلا به تو چه؟ اصلاً چرا آمدی؟ می‌خواستی کنجکاوی‌ات را سیرکنی؟» و دست آخر به این نتیجه رسیدم که «طعمه‌ای برای میزنشین‌های شهربانی و دادگستری به دست آمده و تو نه می‌توانی این طعمه را از دستشان بیرون بیاوری و نه هیچ کار دیگری می‌توانی بکنی...» + +و داشتم سوار تاکسی می‌شدم تا برگردم خانه که یک دفعه به صرافت افتادم که اقلاً چرا نپرسیدی چه بلایی به سرش آمده؟» خواستم عقب‌گرد کنم، اما هیکل کبود معلم کلاس چهارم روی تخت بود و دیدم نمی‌توانم. خجالت می‌کشیدم و یا می‌ترسیدم. آن شب تا ساعت دو بیدار بودم و فردا یک گزارش مفصل به امضای مدیر مدرسه و شهادت همه‌ی معلم‌ها برای اداره‌ی فرهنگ و کلانتری محل و بعد هم دوندگی در اداره‌ی بیمه و قرار بر این که روزی نه تومان بودجه برای خرج بیمارستان او بدهند و عصر پس از مدتی رفتم مدرسه و کلاس‌ها را تعطیل کردم و معلم‌ها و بچه‌های ششم را فرستادم عیادتش و دسته گل و ازین بازی‌ها... و یک ساعتی در مدرسه تنها ماندم و فارغ از همه چیز برای خودم خیال بافتم.... و فردا صبح پدرش آمد سلام و احوالپرسی و گفت یک دست و یک پایش شکسته و کمی خونریزی داخل مغز و از طرف یارو آمریکاییه آمده‌اند عیادتش و وعده و وعید که وقتی خوب شد، در اصل چهار استخدامش کنند و با زبان بی‌زبانی حالیم کرد که گزارش را بیخود داده‌ام و حالا هم داده‌ام، دنبالش نکنم و رضایت طرفین و کاسه‌ی از آش داغ‌تر و از این حرف‌ها... خاک بر سر مملکت. + +اوایل امر توجهی به بچه‌ها نداشتم. خیال می‌کردم اختلاف سِنی میان‌مان آن قدر هست که کاری به کار همدیگر نداشته باشیم. همیشه سرم به کار خودم بود. در دفتر را می‌بستم و در گرمای بخاری دولت قلم صد تا یک غاز می‌زدم. اما این کار مرتب سه چهار هفته بیش‌تر دوام نکرد. خسته شدم. ناچار به مدرسه بیشتر می‌رسیدم. یاد روزهای قدیمی با دوستان قدیمی به خیر چه آدم‌های پاک و بی‌آلایشی بودند، چه شخصیت‌های بی‌نام و نشانی و هر کدام با چه زبانی و با چه ادا و اطوارهای مخصوص به خودشان و این جوان‌های چلفته‌ای. چه مقلدهای بی‌دردسری برای فرهنگی‌مابی! نه خبری از دیروزشان داشتند و نه از املاک تازه‌ای که با هفتاد واسطه به دست‌شان داده بودند، چیزی سرشان می‌شد. بدتر از همه بی‌دست و پایی‌شان بود. آرام و مرتب درست مثل واگن شاه عبدالعظیم می‌آمدند و می‌رفتند. فقط بلد بودند روزی ده دقیقه دیرتر بیایند و همین. و از این هم بدتر تنگ‌نظری‌شان بود. + +سه بار شاهد دعواهایی بودم که سر یک گلدان میخک یا شمعدانی بود. بچه‌باغبان‌ها زیاد بودند و هر کدام‌شان حداقل ماهی یک گلدان میخک یا شمعدانی می‌آوردند که در آن برف و سرما نعمتی بود. اول تصمیم گرفتم، مدرسه را با آن‌ها زینت دهم. ولی چه فایده؟ نه کسی آب‌شان می‌داد و نه مواظبتی. و باز بدتر از همه‌ی این‌ها، بی‌شخصیتی معلم‌ها بود که درمانده‌ام کرده بود. دو کلمه نمی‌توانستند حرف بزنند. عجب هیچ‌کاره‌هایی بودند! احساس کردم که روز به روز در کلاس‌ها معلم‌ها به جای دانش‌آموزان جاافتاده‌تر می‌شوند. در نتیجه گفتم بیش‌تر متوجه بچه‌ها باشم. + +آن‌ها که تنها با ناظم سر و کار داشتند و مثل این بود که به من فقط یک سلام نیمه‌جویده بدهکارند. با این همه نومیدکننده نبودند. توی کوچه مواظب‌شان بودم. می‌خواستم حرف و سخن‌ها و درد دل‌ها و افکارشان را از یک فحش نیمه‌کاره یا از یک ادای نیمه‌تمام حدس بزنم، که سلام‌نکرده در می‌رفتند. خیلی کم تنها به مدرسه می‌آمدند. پیدا بود که سر راه همدیگر می‌ایستند یا در خانه‌ی یکدیگر می‌روند. سه چهار نفرشان هم با اسکورت می‌آمدند. از بیست سی نفری که ناهار می‌ماندند، فقط دو نفرشان چلو خورش می‌آوردند؛ فراش اولی مدرسه برایم خبر می‌آورد. بقیه گوشت‌کوبیده، پنیر گردوئی، دم پختکی و از این جور چیزها. دو نفرشان هم بودند که نان سنگک خالی می‌آوردند. برادر بودند. پنجم و سوم. صبح که می‌آمدند، جیب‌هاشان باد کرده بود. سنگک را نصف می‌کردند و توی جیب‌هاشان می‌تپاندند و ظهر می‌شد، مثل آن‌هایی که ناهارشان را در خانه می‌خورند، می‌رفتند بیرون. من فقط بیرون رفتن‌شان را می‌دیدم. اما حتی همین‌ها هر کدام روزی، یکی دو قران از فراش مدرسه خرت و خورت می‌خریدند. از همان فراش قدیمی مدرسه که ماهی پنج تومان سرایداریش را وصول کرده بودم. هر روز که وارد اتاقم می‌شدم پشت سر من می‌آمد بارانی‌ام را بر می‌داشت و شروع می‌کرد به گزارش دادن، که دیروز باز دو نفر از معلم‌ها سر یک گلدان دعوا کرده‌اند یا مأمور فرماندار نظامی آمده یا دفتردار عوض شده و از این اباطیل... پیدا بود که فراش جدید هم در مطالبی که او می‌گفت، سهمی دارد. + +یک روز در حین گزارش دادن، اشاره‌ای کرد به این مطلب که دیروز عصر یکی از بچه‌های کلاس چهار دو تا کله قند به او فروخته است. درست مثل اینکه سر کلاف را به دستم داده باشد پرسیدم: + +- چند؟ + +- دو تومنش دادم آقا. + +- زحمت کشیدی. نگفتی از کجا آورده؟ + +- من که ضامن بهشت و جهنمش نبودم آقا. + +بعد پرسیدم: + +- چرا به آقای ناظم خبر ندادی؟ + +می‌دانستم که هم او و هم فراش جدید، ناظم را هووی خودشان می‌دانند و خیلی چیزهاشان از او مخفی بود. این بود که میان من و ناظم خاصه‌خرجی می‌کردند. در جوابم همین طور مردد مانده بود که در باز شد و فراش جدید آمد تو. که: + +- اگه خبرش می‌کرد آقا بایست سهمش رو می‌داد... + +اخمم را درهم کشیدم و گفتم: + +- تو باز رفتی تو کوک مردم! اونم این جوری سر نزده که نمی‌آیند تو اتاق کسی، پیرمرد! + +و بعد اسم پسرک را ازشان پرسیدم و حالی‌شان کردم که چندان مهم نیست و فرستادمشان برایم چای بیاورند. بعد کارم را زودتر تمام کردم و رفتم به اتاق دفتر احوالی از مادر ناظم پرسیدم و به هوای ورق زدن پرونده‌ها فهمیدم که پسرک شاگرد دوساله است و پدرش تاجر بازار. بعد برگشتم به اتاقم. یادداشتی برای پدر نوشتم که پس فردا صبح، بیاید مدرسه و دادم دست فراش جدید که خودش برساند و رسیدش را بیاورد. + +و پس فردا صبح یارو آمد. باید مدیر مدرسه بود تا دانست که اولیای اطفال چه راحت تن به کوچک‌ترین خرده‌فرمایش‌های مدرسه می‌دهند. حتم دارم که اگر از اجرای ثبت هم دنبال‌شان بفرستی به این زودی‌ها آفتابی نشوند. چهل و پنج ساله مردی بود با یخه‌ی بسته بی‌کراوات و پالتویی که بیش‌تر به قبا می‌ماند. و خجالتی می‌نمود. هنوز ننشسته، پرسیدم: + +- شما دو تا زن دارید آقا؟ + +درباره‌ی پسرش برای خودم پیش‌گویی‌هایی کرده بودم و گفتم این طوری به او رودست می‌زنم. پیدا بود که از سؤالم زیاد یکه نخورده است. گفتم برایش چای آوردند و سیگاری تعارفش کردم که ناشیانه دود کرد از ترس این که مبادا جلویم در بیاید که - به شما چه مربوط است و از این اعتراض‌ها - امانش ندادم و سؤالم را این جور دنبال کردم: + +- البته می‌بخشید. چون لابد به همین علت بچه شما دو سال در یک کلاس مانده. + +شروع کرده بودم برایش یک میتینگ بدهم که پرید وسط حرفم: + +- به سر شما قسم، روزی چهار زار پول تو جیبی داره آقا. پدرسوخته‌ی نمک به حروم...! + +حالیش کردم که علت، پول تو جیبی نیست و خواستم که عصبانی نشود و قول گرفتم که اصلاً به روی پسرش هم نیاورد و آن وقت میتینگم را برایش دادم که لابد پسر در خانه مهر و محبتی نمی‌بیند و غیب‌گویی‌های دیگر... تا عاقبت یارو خجالتش ریخت و سرِ درد دلش باز شد که عفریته زن اولش همچه بوده و همچون بوده و پسرش هم به خودش برده و کی طلاقش داده و از زن دومش چند تا بچه دارد و این نره‌خر حالا باید برای خودش نان‌آور شده باشد و زنش حق دارد که با دو تا بچه‌ی خرده‌پا به او نرسد... من هم کلی برایش صحبت کردم. چایی دومش را هم سر کشید و قول‌هایش را که داد و رفت، من به این فکر افتادم که «نکند علمای تعلیم و تربیت هم، همین جورها تخم دوزرده می‌کنند!» + +یک روز صبح که رسیدم، ناظم هنوز نیامده بود. از این اتفاق‌ها کم می‌افتاد. ده دقیقه‌ای از زنگ می‌گذشت و معلم‌ها در دفتر سرگرم اختلاط بودند. خودم هم وقتی معلم بودم به این مرض دچار بودم. اما وقتی مدیر شدم تازه فهمیدم که معلم‌ها چه لذتی می‌برند. حق هم داشتند. آدم وقتی مجبور باشد شکلکی را به صورت بگذارد که نه دیگران از آن می‌خندند و نه خود آدم لذتی می‌برد، پیداست که رفع تکلیف می‌کند. زنگ را گفتم زدند و بچه‌ها سر کلاس رفتند. دو تا از کلاس‌ها بی‌معلم بود. یکی از ششمی‌ها را فرستادم سر کلاس سوم که برای‌شان دیکته بگوید و خودم رفتم سر کلاس چهار. مدیر هم که باشی، باز باید تمرین کنی که مبادا فوت و فن معلمی از یادت برود. در حال صحبت با بچه‌ها بودم که فراش خبر آورد که خانمی توی دفتر منتظرم است. خیال کردم لابد همان زنکه‌ی بیکاره‌ای است که هفته‌ای یک بار به هوای سرکشی، به وضع درس و مشق بچه‌اش سری می‌زند. زن سفیدرویی بود با چشم‌های درشت محزون و موی بور. بیست و پنج ساله هم نمی‌نمود. اما بچه‌اش کلاس سوم بود. روز اول که دیدمش لباس نارنجی به تن داشت و تن بزک کرده بود. از زیارت من خیلی خوشحال شد و از مراتب فضل و ادبم خبر داشت. + +خیلی ساده آمده بود تا با دو تا مرد حرفی زده باشد. آن طور که ناظم خبر می‌داد، یک سالی طلاق گرفته بود و روی هم رفته آمد و رفتنش به مدرسه باعث دردسر بود. وسط بیابان و مدرسه‌ای پر از معلم‌های عزب و بی‌دست و پا و یک زن زیبا... ناچار جور در نمی‌آمد. این بود که دفعات بعد دست به سرش می‌کردم، اما از رو نمی‌رفت. سراغ ناظم و اتاق دفتر را می‌گرفت و صبر می‌کرد تا زنگ را بزنند و معلم‌ها جمع بشوند و لابد حرف و سخنی و خنده‌ای و بعد از معلم کلاس سوم سراغ کار و بار و بچه‌اش را می‌گرفت و زنگ بعد را که می‌زدند، خداحافظی می‌کرد و می‌رفت. آزاری نداشت. با چشم‌هایش نفس معلم‌ها را می‌برید. و حالا باز هم همان زن بود و آمده بود و من تا از پلکان پایین بروم در ذهنم جملات زننده‌ای ردیف می‌کردم، تا پایش را از مدرسه ببرد که در را باز کردم و سلام... + +عجب! او نبود. دخترک یکی دو ساله‌ای بود با دهان گشاد و موهای زبرش را به زحمت عقب سرش گلوله کرده بود و بفهمی نفهمی دستی توی صورتش برده بود. روی هم رفته زشت نبود. اما داد می‌زد که معلم است. گفتم که مدیر مدرسه‌ام و حکمش را داد دستم که دانشسرا دیده بود و تازه استخدام شده بود. برایمان معلم فرستاده بودند. خواستم بگویم «مگر رئیس فرهنگ نمی‌داند که این جا بیش از حد مرد است» ولی دیدم لزومی ندارد و فکر کردم این هم خودش تنوعی است. + +به هر صورت زنی بود و می‌توانست محیط خشن مدرسه را که به طرز ناشیانه‌ای پسرانه بود، لطافتی بدهد و خوش‌آمد گفتم و چای آوردند که نخورد و بردمش کلاس‌های سوم و چهارم را نشانش دادم که هر کدام را مایل است، قبول کند و صحبت از هجده ساعت درس که در انتظار او بود و برگشتیم به دفتر .پرسید غیر از او هم، معلم زن داریم. گفتم: + +- متأسفانه راه مدرسه‌ی ما را برای پاشنه‌ی کفش خانم‌ها نساخته‌اند. + +که خندید و احساس کردم زورکی می‌خندد. بعد کمی این دست و آن دست کرد و عاقبت: + +- آخه من شنیده بودم شما با معلماتون خیلی خوب تا می‌کنید. + +صدای جذابی داشت. فکر کردم حیف که این صدا را پای تخته سیاه خراب خواهد کرد. و گفتم: + +- اما نه این قدر که مدرسه تعطیل بشود خانم! و لابد به عرض‌تون رسیده که همکارهای شما، خودشون نشسته‌اند و تصمیم گرفته‌اند که هجده ساعت درس بدهند. بنده هیچ‌کاره‌ام. + +- اختیار دارید. + +و نفهمیدم با این «اختیار دارید» چه می‌خواست بگوید. اما پیدا بود که بحث سر ساعات درس نیست. آناً تصمیم گرفتم، امتحانی بکنم: + +- این را هم اطلاع داشته باشید که فقط دو تا از معلم‌های ما متأهل‌اند. + +که قرمز شد و برای این که کار دیگری نکرده باشد، برخاست و حکمش را از روی میز برداشت. پا به پا می‌شد که دیدم باید به دادش برسم. ساعت را از او پرسیدم. وقت زنگ بود. فراش را صدا کردم که زنگ را بزند و بعد به او گفتم، بهتر است مشورت دیگری هم با رئیس فرهنگ بکند و ما به هر صورت خوشحال خواهیم شد که افتخار همکاری با خانمی مثل ایشان را داشته باشیم و خداحافظ شما. از در دفتر که بیرون رفت، صدای زنگ برخاست و معلم‌ها انگار موشان را آتش زده‌اند، به عجله رسیدند و هر کدام از پشت سر، آن قدر او را پاییدند تا از در بزرگ آهنی مدرسه بیرون رفت. + +فردا صبح معلوم شد که ناظم، دنبال کار مادرش بوده است که قرار بود بستری شود، تا جای سرطان گرفته را یک دوره برق بگذارند. کل کار بیمارستان را من به کمک دوستانم انجام دادم و موقع آن رسیده بود که مادرش برود بیمارستان اما وحشتش گرفته بود و حاضر نبود به بیمارستان برود. و ناظم می‌خواست رسماً دخالت کنم و با هم برویم خانه‌شان و با زبان چرب و نرمی که به قول ناظم داشتم مادرش را راضی کنم. چاره‌ای نبود. مدرسه را به معلم‌ها سپردیم و راه افتادیم. بالاخره به خانه‌ی آن‌ها رسیدیم. خانه‌ای بسیار کوچک و اجاره‌ای. مادر با چشم‌های گود نشسته و انگار زغال به صورت مالیده! سیاه نبود اما رنگش چنان تیره بود که وحشتم گرفت. اصلاً صورت نبود. زخم سیاه شده‌ای بود که انگار از جای چشم‌ها و دهان سر باز کرده است. کلی با مادرش صحبت کردم. از پسرش و کلی دروغ و دونگ، و چادرش را روی چارقدش انداختیم و علی... و خلاصه در بیمارستان بستری شدند. + +فردا که به مدرسه آمدم، ناظم سرحال بود و پیدا بود که از شر چیزی خلاص شده است و خبر داد که معلم کلاس سه را گرفته‌اند. یک ماه و خرده‌ای می‌شد که مخفی بود و ما ورقه‌ی انجام کارش را به جانشین غیر رسمی‌اش داده بودیم و حقوقش لنگ نشده بود و تا خبر رسمی بشنود و در روزنامه‌ای بیابد و قضیه به اداره‌ی فرهنگ و لیست حقوق بکشد، باز هم می‌دادیم. اما خبر که رسمی شد، جانشین واجد شرایط هم نمی‌توانست بفرستد و باید طبق مقررات رفتار می‌کردیم و بدیش همین بود. کم کم احساس کردم که مدرسه خلوت شده است و کلاس‌ها اغلب اوقات بی‌کارند. جانشین معلم کلاس چهار هنوز سر و صورتی به کارش نداده بود و حالا یک کلاس دیگر هم بی‌معلم شد. این بود که باز هم به سراغ رئیس فرهنگ رفتم. معلوم شد آن دخترک ترسیده و «نرسیده متلک پیچش کرده‌اید» رئیس فرهنگ این طور می‌گفت. و ترجیح داده بود همان زیر نظر خودش دفترداری کند. و بعد قول و قرار و فردا و پس فردا و عاقبت چهار روز دوندگی تا دو تا معلم گرفتم. یکی جوانکی رشتی که گذاشتیمش کلاس چهار و دیگری باز یکی ازین آقاپسرهای بریانتین‌زده که هر روز کراوات عوض می‌کرد، با نقش‌ها و طرح‌های عجیب. عجب فرهنگ را با قرتی‌ها در آمیخته بودند! باداباد. او را هم گذاشتیم سر کلاس سه. اواخر بهمن، یک روز ناظم آمد اتاقم که بودجه‌ی مدرسه را زنده کرده است. گفتم: + +- مبارکه، چه قدر گرفتی؟ + +- هنوز هیچ چی آقا. قراره فردا سر ظهر بیاند این جا آقا و همین جا قالش رو بکنند. + +و فردا اصلاً مدرسه نرفتم. حتماً می‌خواست من هم باشم و در بده بستان ماهی پانزده قران، حق نظافت هر اتاق نظارت کنم و از مدیریتم مایه بگذارم تا تنخواه‌گردان مدرسه و حق آب و دیگر پول‌های عقب‌افتاده وصول بشود... فردا سه نفری آمده بودند مدرسه. ناهار هم به خرج ناظم خورده بودند. و قرار دیگری برای یک سور حسابی گذاشته بودند و رفته بودند و ناظم با زبان بی‌زبانی حالیم کرد که این بار حتماً باید باشم و آن طور که می‌گفت، جای شکرش باقی بود که مراعات کرده بودند و حق بوقی نخواسته بودند. اولین باری بود که چنین اهمیتی پیدا می‌کردم. این هم یک مزیت دیگر مدیری مدرسه بود! سی صد تومان از بودجه‌ی دولت بسته به این بود که به فلان مجلس بروی یا نروی. تا سه روز دیگر موعد سور بود، اصلاً یادم نیست چه کردم. اما همه‌اش در این فکر بودم که بروم یا نروم؟ یک بار دیگر استعفانامه‌ام را توی جیبم گذاشتم و بی این که صدایش را در بیاورم، روز سور هم نرفتم. + +بعد دیدم این طور که نمی‌شود. گفتم بروم قضایا را برای رئیس فرهنگ بگویم. و رفتم. سلام و احوالپرسی نشستم. اما چه بگویم؟ بگویم چون نمی‌خواستم در خوردن سور شرکت کنم، استعفا می‌دهم؟... دیدم چیزی ندارم که بگویم. و از این گذشته خفت‌آور نبود که به خاطر سیصد تومان جا بزنم و استعفا بدهم؟ و «خداحافظ؛ فقط آمده بودم سلام عرض کنم.» و از این دروغ‌ها و استعفانامه‌ام را توی جوی آب انداختم. اما ناظم؛ یک هفته‌ای مثل سگ بود. عصبانی، پر سر و صدا و شارت و شورت! حتی نرفتم احوال مادرش را بپرسم. یک هفته‌ی تمام می‌رفتم و در اتاقم را می‌بستم و سوراخ‌های گوشم را می‌گرفتم و تا اِز و چِزّ بچه‌ها بخوابد، از این سر تا آن سر اتاق را می‌کوبیدم. ده روز تمام، قلب من و بچه‌ها با هم و به یک اندازه از ترس و وحشت تپید. تا عاقبت پول‌ها وصول شد. منتها به جای سیصد و خرده‌ای، فقط صد و پنجاه تومان. علت هم این بود که در تنظیم صورت حساب‌ها اشتباهاتی رخ داده بود که ناچار اصلاحش کرده بودند! + +غیر از آن زنی که هفته‌ای یک بار به مدرسه سری می‌زد، از اولیای اطفال دو سه نفر دیگر هم بودند که مرتب بودند. یکی همان پاسبانی که با کمربند، پاهای پسرش را بست و فلک کرد. یکی هم کارمند پست و تلگرافی بود که ده روزی یک بار می‌آمد و پدر همان بچه‌ی شیطان. و یک استاد نجار که پسرش کلاس اول بود و خودش سواد داشت و به آن می‌بالید و کارآمد می‌نمود. یک مقنی هم بود درشت استخوان و بلندقد که بچه‌اش کلاس سوم بود و هفته‌ای یک بار می‌آمد و همان توی حیاط، ده پانزده دقیقه‌ای با فراش‌ها اختلاط می‌کرد و بی سر و صدا می‌رفت. نه کاری داشت، نه چیزی از آدم می‌خواست و همان طور که آمده بود چند دقیقه‌ای را با فراش صحبت می‌کرد و بعد می رفت. فقط یک روز نمی‌دانم چرا رفته بود بالای دیوار مدرسه. البته اول فکر کردم مأمور اداره برق است ولی بعد متوجه شدم که همان مرد مقنی است. بچه‌ها جیغ و فریاد می‌کردند و من همه‌اش درین فکر بودم که چه طور به سر دیوار رفته است؟ ماحصل داد و فریادش این بود که چرا اسم پسر او را برای گرفتن کفش و لباس به انجمن ندادیم. وقتی به او رسیدم نگاهی به او انداختم و بعد تشری به ناظم و معلم ها زدم که ولش کردند و بچه‌ها رفتند سر کلاس و بعد بی این که نگاهی به او بکنم، گفتم: + +- خسته نباشی اوستا. + +و همان طور که به طرف دفتر می‌رفتم رو به ناظم و معلم‌ها افزودم: + +- لابد جواب درست و حسابی نشنیده که رفته سر دیوار. + +که پشت سرم گرپ صدایی آمد و از در دفتر که رفتم تو، او و ناظم با هم وارد شدند. گفتم نشست. و به جای این‌که حرفی بزند به گریه افتاد. هرگز گمان نمی‌کردم از چنان قد و قامتی صدای گریه در بیاید. این بود که از اتاق بیرون آمدم و فراش را صدا زدم که آب برایش بیاورد و حالش که جا آمد، بیاوردش پهلوی من. اما دیگر از او خبری نشد که نشد. نه آن روز و نه هیچ روز دیگر. آن روز چند دقیقه‌ای بعد از شیشه‌ی اتاق خودم دیدمش که دمش را لای پایش گذاشته بود از در مدرسه بیرون می‌رفت و فراش جدید آمد که بله می‌گفتند از پسرش پنج تومان خواسته بودند تا اسمش را برای کفش و لباس به انجمن بدهند. پیدا بود باز توی کوک ناظم رفته است. مرخصش کردم و ناظم را خواستم. معلوم شد می‌خواسته ناظم را بزند. همین جوری و بی‌مقدمه. + +اواخر بهمن بود که یکی از روزهای برفی با یکی دیگر از اولیای اطفال آشنا شدم. یارو مرد بسیار کوتاهی بود؛ فرنگ مآب و بزک کرده و اتو کشیده که ننشسته از تحصیلاتش و از سفرهای فرنگش حرف زد. می‌خواست پسرش را آن وقت سال از مدرسه‌ی دیگر به آن جا بیاورد. پسرش از آن بچه‌هایی بود که شیر و مربای صبحانه‌اش را با قربان صدقه توی حلقشان می‌تپانند. کلاس دوم بود و ثلث اول دو تا تجدید آورده بود. می‌گفت در باغ ییلاقی‌اش که نزدیک مدرسه است، باغبانی دارند که پسرش شاگرد ماست و درس‌خوان است و پیدا است که بچه‌ها زیر سایه شما خوب پیشرفت می‌کنند. و از این پیزرها. و حال به خاطر همین بچه، توی این برف و سرما، آمده‌اند ساکن باغ ییلاقی شده‌اند. بلند شدم ناظم را صدا کردم و دست او و بچه‌اش را توی دست ناظم گذاشتم و خداحافظ شما... و نیم ساعت بعد ناظم برگشت که یارو خانه‌ی شهرش را به یک دبیرستان اجاره داده، به ماهی سه هزار و دویست تومان، و التماس دعا داشته، یعنی معلم سرخانه می‌خواسته و حتی بدش نمی‌آمده است که خود مدیر زحمت بکشند و ازین گنده‌گوزی‌ها... احساس کردم که ناظم دهانش آب افتاده است. و من به ناظم حالی کردم خودش برود بهتر است و فقط کاری بکند که نه صدای معلم‌ها در بیاید و نه آخر سال، برای یک معدل ده احتیاجی به من بمیرم و تو بمیری پیدا کند. همان روز عصر ناظم رفته بود و قرار و مدار برای هر روز عصر یک ساعت به ماهی صد و پنجاه تومان. + +دیگر دنیا به کام ناظم بود. حال مادرش هم بهتر بود و از بیمارستان مرخصش کرده بودند و به فکر زن گرفتن افتاده بود. و هر روز هم برای یک نفر نقشه می‌کشید حتی برای من هم. یک روز در آمد که چرا ما خودمان «انجمن خانه و مدرسه» نداشته باشیم؟ نشسته بود و حسابش را کرده بود دیده بود که پنجاه شصت نفری از اولیای مدرسه دستشان به دهان‌شان می‌رسد و از آن هم که به پسرش درس خصوصی می‌داد قول مساعد گرفته بود. حالیش کردم که مواظب حرف و سخن اداره‌ای باشد و هر کار دلش می‌خواهد بکند. کاغذ دعوت را هم برایش نوشتم با آب و تاب و خودش برای اداره‌ی فرهنگ، داد ماشین کردند و به وسیله‌ی خود بچه‌ها فرستاد. و جلسه با حضور بیست و چند نفری از اولیای بچه‌ها رسمی شد. خوبیش این بود که پاسبان کشیک پاسگاه هم آمده بود و دم در برای همه، پاشنه‌هایش را به هم می‌کوبید و معلم‌ها گوش تا گوش نشسته بودند و مجلس ابهتی داشت و ناظم، چای و شیرینی تهیه کرده بود و چراغ زنبوری کرایه کرده بود و باران هم گذاشت پشتش و سالون برای اولین بار در عمرش به نوایی رسید. + +یک سرهنگ بود که رئیسش کردیم و آن زن را که هفته‌ای یک بار می‌آمد نایب رئیس. آن که ناظم به پسرش درس خصوصی می‌داد نیامده بود. اما پاکت سربسته‌ای به اسم مدیر فرستاده بود که فی‌المجلس بازش کردیم. عذرخواهی از این‌که نتوانسته بود بیاید و وجه ناقابلی جوف پاکت. صد و پنجاه تومان. و پول را روی میز صندوق‌دار گذاشتیم که ضبط و ربط کند. نائب رئیس بزک کرده و معطر شیرینی تعارف می‌کرد و معلم‌ها با هر بار که شیرینی بر می‌داشتند، یک بار تا بناگوش سرخ می‌شدند و فراش‌ها دست به دست چای می‌آوردند. + +در فکر بودم که یک مرتبه احساس کردم، سیصد چهارصد تومان پول نقد، روی میز است و هشت صد تومان هم تعهد کرده بودند. پیرزن صندوقدار که کیف پولش را همراهش نیاورده بود ناچار حضار تصویب کردند که پول‌ها فعلاً پیش ناظم باشد. و صورت مجلس مرتب شد و امضاها ردیف پای آن و فردا فهمیدم که ناظم همان شب روی خشت نشسته بوده و به معلم‌ها سور داده بوده است. اولین کاری که کردم رونوشت مجلس آن شب را برای اداره‌ی فرهنگ فرستادم. و بعد همان استاد نجار را صدا کردم و دستور دادم برای مستراح‌ها دو روزه در بسازد که ناظم خیلی به سختی پولش را داد. و بعد در کوچه‌ی مدرسه درخت کاشتیم. تور والیبال را تعویض و تعدادی توپ در اختیار بچه‌ها گذاشتیم برای تمرین در بعد از ظهرها و آمادگی برای مسابقه با دیگر مدارس و در همین حین سر و کله‌ی بازرس تربیت بدنی هم پیدا شد و هر روز سرکشی و بیا و برو. تا یک روز که به مدرسه رسیدم شنیدم که از سالون سر و صدا می‌آید. صدای هالتر بود. ناظم سر خود رفته بود و سرخود دویست سیصد تومان داده بود و هالتر خریده بود و بچه‌های لاغر زیر بار آن گردن خود را خرد می‌کردند. من در این میان حرفی نزدم. می‌توانستم حرفی بزنم؟ من چیکاره بودم؟ اصلاً به من چه ربطی داشت؟ هر کار که دلشان می‌خواهد بکنند. مهم این بود که سالون مدرسه رونقی گرفته بود. ناظم هم راضی بود و معلم‌ها هم. چون نه خبر از حسادتی بود و نه حرف و سخنی پیش آمد. فقط می‌بایست به ناظم سفارش می کردم که فکر فراش‌ها هم باشد. + +کم کم خودمان را برای امتحان‌های ثلث دوم آماده می‌کردیم. این بود که اوایل اسفند، یک روز معلم‌ها را صدا زدم و در شورا مانندی که کردیم بی‌مقدمه برایشان داستان یکی از همکاران سابقم را گفتم که هر وقت بیست می‌داد تا دو روز تب داشت. البته معلم‌ها خندیدند. ناچار تشویق شدم و داستان آخوندی را گفتم که در بچگی معلم شرعیاتمان بود و زیر عبایش نمره می‌داد و دستش چنان می‌لرزید که عبا تکان می‌خورد و درست ده دقیقه طول می‌کشید. و تازه چند؟ بهترین شاگردها دوازده. و البته باز هم خندیدند. که این بار کلافه‌ام کرد. و بعد حالیشان کردم که بد نیست در طرح سؤال‌ها مشورت کنیم و از این حرف‌ها... + +و از شنبه‌ی بعد، امتحانات شروع شد. درست از نیمه‌ی دوم اسفند. سؤال‌ها را سه نفری می‌دیدیم. خودم با معلم هر کلاس و ناظم. در سالون میزها را چیده بودیم البته از وقتی هالتردار شده بود خیلی زیباتر شده بود. در سالون کاردستی‌های بچه‌ها در همه جا به چشم می‌خورد. هر کسی هر چیزی را به عنوان کاردستی درست کرده بودند و آورده بودند. که برای این کاردستی‌ها چه پول‌ها که خرج نشده بود و چه دست‌ها که نبریده بود و چه دعواها که نشده بود و چه عرق‌ها که ریخته نشده بود. پیش از هر امتحان که می‌شد، خودم یک میتینگ برای بچه‌ها می‌دادم که ترس از معلم و امتحان بی‌جا است و باید اعتماد به نفس داشت و ازین مزخرفات....ولی مگر حرف به گوش کسی می‌رفت؟ از در که وارد می‌شدند، چنان هجومی می‌بردند که نگو! به جاهای دور از نظر. یک بار چنان بود که احساس کردم مثل این‌که از ترس، لذت می‌برند. اگر معلم نبودی یا مدیر، به راحتی می‌توانستی حدس بزنی که کی‌ها با هم قرار و مداری دارند و کدام یک پهلو دست کدام یک خواهد نشست. یکی دو بار کوشیدم بالای دست یکی‌شان بایستم و ببینم چه می‌نویسد. ولی چنان مضطرب می‌شدند و دستشان به لرزه می‌افتاد که از نوشتن باز می‌ماندند. می‌دیدم که این مردان آینده، درین کلاس‌ها و امتحان‌ها آن قدر خواهند ترسید که وقتی دیپلمه بشوند یا لیسانسه، اصلاً آدم نوع جدیدی خواهند شد. آدمی انباشته از وحشت، انبانی از ترس و دلهره. به این ترتیب یک روز بیشتر دوام نیاوردم. چون دیدم نمی‌توانم قلب بچگانه‌ای داشته باشم تا با آن ترس و وحشت بچه‌ها را درک کنم و هم‌دردی نشان بدهم.این جور بود که می‌دیدم که معلم مدرسه هم نمی‌توانم باشم. + +دو روز قبل از عید کارنامه‌ها آماده بود و منتظر امضای مدیر. دویست و سی و شش تا امضا اقلاً تا ظهر طول می‌کشید. پیش از آن هم تا می‌توانستم از امضای دفترهای حضور و غیاب می‌گریختم. خیلی از جیره‌خورهای دولت در ادارات دیگر یا در میان همکارانم دیده بودم که در مواقع بیکاری تمرین امضا می‌کنند. پیش از آن نمی‌توانستم بفهمم چه طور از مدیری یک مدرسه یا کارمندی ساده یک اداره می‌شود به وزارت رسید. یا اصلاً آرزویش را داشت. نیم‌قراضه امضای آماده و هر کدام معرف یک شخصیت، بعد نیم‌ذرع زبان چرب و نرم که با آن، مار را از سوراخ بیرون بکشی، یا همه جا را بلیسی و یک دست هم قیافه. نه یک جور. دوازده جور. + +در این فکرها بودم که ناگهان در میان کارنامه‌ها چشمم به یک اسم آشنا افتاد. به اسم پسران جناب سرهنگ که رئیس انجمن بود. رفتم توی نخ نمراتش. همه متوسط بود و جای ایرادی نبود. و یک مرتبه به صرافت افتادم که از اول سال تا به حال بچه‌های مدرسه را فقط به اعتبار وضع مالی پدرشان قضاوت کرده‌ام. درست مثل این پسر سرهنگ که به اعتبار کیابیای پدرش درس نمی‌خواند. دیدم هر کدام که پدرشان فقیرتر است به نظر من باهوش‌تر می‌آمده‌اند. البته ناظم با این حرف‌ها کاری نداشت. مر قانونی را عمل می‌کرد. از یکی چشم می‌پوشید به دیگری سخت می‌گرفت. + +اما من مثل این که قضاوتم را درباره‌ی بچه‌ها از پیش کرده باشم و چه خوب بود که نمره‌ها در اختیار من نبود و آن یکی هم «انظباط» مال آخر سال بود. مسخره‌ترین کارها آن است که کسی به اصلاح وضعی دست بزند، اما در قلمروی که تا سر دماغش بیشتر نیست. و تازه مدرسه‌ی من، این قلمروی فعالیت من، تا سر دماغم هم نبود. به همان توی ذهنم ختم می‌شد. وضعی را که دیگران ترتیب داده بودند. به این ترتیب بعد از پنج شش ماه، می‌فهمیدم که حسابم یک حساب عقلایی نبوده است. احساساتی بوده است. ضعف‌های احساساتی مرا خشونت‌های عملی ناظم جبران می‌کرد و این بود که جمعاً نمی‌توانستم ازو بگذرم. مرد عمل بود. کار را می‌برید و پیش می‌رفت. در زندگی و در هر کاری، هر قدمی بر می‌داشت، برایش هدف بود. و چشم از وجوه دیگر قضیه می‌پوشید. این بود که برش داشت. و من نمی‌توانستم. چرا که اصلاً مدیر نبودم. خلاص... + +و کارنامه‌ی پسر سرهنگ را که زیر دستم عرق کرده بود، به دقت و احتیاج خشک کردم و امضایی زیر آن گذاشتم به قدری بد خط و مسخره بود که به یاد امضای فراش جدیدمان افتادم. حتماً جناب سرهنگ کلافه می‌شد که چرا چنین آدم بی‌سوادی را با این خط و ربط امضا مدیر مدرسه کرده‌اند. آخر یک جناب سرهنگ هم می‌داند که امضای آدم معرف شخصیت آدم است. + +اواخر تعطیلات نوروز رفتم به ملاقات معلم ترکه‌ای کلاس سوم. ناظم که با او میانه‌ی خوشی نداشت. ناچار با معلم حساب کلاس پنج و شش قرار و مداری گذاشته بودم که مختصری علاقه‌ای هم به آن حرف و سخن‌ها داشت. هم به وسیله‌ی او بود که می‌دانستم نشانی‌اش کجا است و توی کدام زندان است. در راه قبل از هر چیز خبر داد که رئیس فرهنگ عوض شده و این طور که شایع است یکی از هم دوره‌ای‌های من، جایش آمده. گفتم: + +- عجب! چرا؟ مگه رئیس قبلی چپش کم بود؟ + +- چه عرض کنم. می‌گند پا تو کفش یکی از نماینده‌ها کرده. شما خبر ندارید؟ + +- چه طور؟ از کجا خبر داشته باشم؟ + +- هیچ چی... می گند دو تا از کارچاق‌کن‌های انتخاباتی یارو از صندوق فرهنگ حقوق می‌گرفته‌اند؛ شب عیدی رئیس فرهنگ حقوق‌شون رو زده. + +- عجب! پس اونم می‌خواسته اصلاحات کنه! بیچاره. + +و بعد از این حرف زدیم که الحمدالله مدرسه مرتب است و آرام و معلم‌ها همکاری می‌کنند و ناظم بیش از اندازه همه‌کاره شده است. و من فهمیدم که باز لابد مشتری خصوصی تازه‌ای پیدا شده است که سر و صدای همه همکارها بلند شده. دم در زندان شلوغ بود. کلاه مخملی‌ها، عم‌قزی گل‌بته‌ها، خاله خانباجی‌ها و... اسم نوشتیم و نوبت گرفتیم و به جای پاها، دست‌هامان زیر بار کوچکی که داشتیم، خسته شد و خواب رفت تا نوبتمان شد. از این اتاق به آن اتاق و عاقبت نرده‌های آهنی و پشت آن معلم کلاس سه و... عجب چاق شده بود!درست مثل یک آدم حسابی شده بود. خوشحال شدیم و احوالپرسی و تشکر؛ و دیگر چه بگویم؟ بگویم چرا خودت را به دردسر انداختی؟ پیدا بود از مدرسه و کلاس به او خوش‌تر می‌گذرد. ایمانی بود و او آن را داشت و خوشبخت بود و دردسری نمی‌دید و زندان حداقل برایش کلاس درس بود. عاقبت پرسیدم: + +- پرونده‌ای هم برات درست کردند یا هنوز بلاتکلیفی؟ + +- امتحانمو دادم آقا مدیر، بد از آب در نیومد. + +- یعنی چه؟ + +- یعنی بی‌تکلیف نیستم. چون اسمم تو لیست جیره‌ی زندون رفته. خیالم راحته. چون سختی‌هاش گذشته. + +دیگر چه بگویم. دیدم چیزی ندارم خداحافظی کردم و او را با معلم حساب تنها گذاشتم و آمدم بیرون و تا مدت ملاقات تمام بشود، دم در زندان قدم زدم و به زندانی فکر کردم که برای خودم ساخته بودم. یعنی آن خرپول فرهنگ‌دوست ساخته بود. و من به میل و رغبت خودم را در آن زندانی کرده بودم. این یکی را به ضرب دگنک این جا آورده بودند. ناچار حق داشت که خیالش راحت باشد. اما من به میل و رغبت رفته بودم و چه بکنم؟ ناظم چه طور؟ راستی اگر رئیس فرهنگ از هم دوره‌ای‌های خودم باشد؛ چه طور است بروم و ازو بخواهم که ناظم را جای من بگذارد، یا همین معلم حساب را؟... که معلم حساب در آمد و راه افتادیم. با او هم دیگر حرفی نداشتم. سر پیچ خداحافظ شما و تاکسی گرفتم و یک سر به اداره‌ی فرهنگ زدم. گرچه دهم عید بود، اما هنوز رفت و آمد سال نو تمام نشده بود. برو و بیا و شیرینی و چای دو جانبه. رفتم تو. سلام و تبریک و همین تعارفات را پراندم. + +بله خودش بود. یکی از پخمه‌های کلاس. که آخر سال سوم کشتیارش شدم دو بیت شعر را حفظ کند، نتوانست که نتوانست. و حالا او رئیس بود و من آقا مدیر. راستی حیف از من، که حتی وزیر چنین رئیس فرهنگ‌هایی باشم! میز همان طور پاک بود و رفته. اما زیرسیگاری انباشته از خاکستر و ته سیگار. بلند شد و چلپ و چولوپ روبوسی کردیم و پهلوی خودش جا باز کرد و گوش تا گوش جیره‌خورهای فرهنگ تبریکات صمیمانه و بدگویی از ماسبق و هندوانه و پیزرها! و دو نفر که قد و قواره‌شان به درد گود زورخانه می‌خورد یا پای صندوق انتخابات شیرینی به مردم می‌دادند. نزدیک بود شیرینی را توی ظرفش بیندازم که دیدم بسیار احمقانه است. سیگارم که تمام شد قضیه‌ی رئیس فرهنگ قبلی و آن دو نفر را در گوشی ازش پرسیدم، حرفی نزد. فقط نگاهی می‌کرد که شبیه التماس بود و من فرصت جستم تا وضع معلم کلاس سوم را برایش روشن کنم و از او بخواهم تا آن جا که می‌تواند جلوی حقوقش را نگیرد. و از در که آمدم بیرون، تازه یادم آمد که برای کار دیگری پیش رئیس فرهنگ بودم. + +باز دیروز افتضاحی به پا شد. معقول یک ماهه‌ی فروردین راحت بودیم. اول اردیبهشت ماه جلالی و کوس رسوایی سر دیوار مدرسه. نزدیک آخر وقت یک جفت پدر و مادر، بچه‌شان در میان، وارد اتاق شدند. یکی بر افروخته و دیگری رنگ و رو باخته و بچه‌شان عیناً مثل این عروسک‌های کوکی. سلام و علیک و نشستند. خدایا دیگر چه اتفاقی افتاده است؟ + +- چه خبر شده که با خانوم سرافرازمون کردید؟ + +مرد اشاره‌ای به زنش کرد که بلند شد و دست بچه را گرفت و رفت بیرون و من ماندم و پدر. اما حرف نمی‌زد. به خودش فرصت می‌داد تا عصبانیتش بپزد. سیگارم را در آوردم و تعارفش کردم. مثل این که مگس مزاحمی را از روی دماغش بپراند، سیگار را رد کرد و من که سیگارم را آتش می‌زدم، فکر کردم لابد دردی دارد که چنین دست و پا بسته و چنین متکی به خانواده به مدرسه آمده. باز پرسیدم: + +- خوب، حالا چه فرمایش داشتید؟ + +که یک مرتبه ترکید: + +- اگه من مدیر مدرسه بودم و هم‌چه اتفاقی می‌افتاد، شیکم خودمو پاره می‌کردم. خجالت بکش مرد! برو استعفا بده. تا اهل محل نریختن تیکه تیکه‌ات کنند، دو تا گوشتو وردار و دررو. بچه‌های مردم می‌آن این جا درس بخونن و حسن اخلاق. نمی‌آن که... + +- این مزخرفات کدومه آقا! حرف حساب سرکار چیه؟ + +و حرکتی کردم که او را از در بیندازم بیرون. اما آخر باید می‌فهمیدم چه مرگش است. «ولی آخر با من چه کار دارد؟» + +- آبروی من رفته. آبروی صد ساله‌ی خونواده‌ام رفته. اگه در مدرسه‌ی تو رو تخته نکنم، تخم بابام نیستم. آخه من دیگه با این بچه چی کار کنم؟ تو این مدرسه ناموس مردم در خطره. کلانتری فهمیده؛ پزشک قانونی فهمیده؛ یک پرونده درست شده پنجاه ورق؛ تازه می‌گی حرف حسابم چیه؟ حرف حسابم اینه که صندلی و این مقام از سر تو زیاده. حرف حسابم اینه که می‌دم محاکمه‌ات کنند و از نون خوردن بندازنت... + +او می‌گفت و من گوش می‌کردم و مثل دو تا سگ هار به جان هم افتاده بودیم که در باز شد و ناظم آمد تو. به دادم رسید. در همان حال که من و پدر بچه در حال دعوا بودیم زن و بچه همان آقا رفته بودند و قضایا را برای ناظم تعریف کرده بودند و او فرستاده بوده فاعل را از کلاس کشیده بودند بیرون... و گفت چه طور است زنگ بزنیم و جلوی بچه‌ها ادبش کنیم و کردیم. یعنی این بار خود من رفتم میدان. پسرک نره‌خری بود از پنجمی‌ها با لباس مرتب و صورت سرخ و سفید و سالکی به گونه. جلوی روی بچه‌ها کشیدمش زیر مشت و لگد و بعد سه تا از ترکه‌ها را که فراش جدید فوری از باغ همسایه آورده بود، به سر و صورتش خرد کردم. چنان وحشی شده بودم که اگر ترکه‌ها نمی‌رسید، پسرک را کشته بودم. این هم بود که ناظم به دادش رسید و وساطت کرد و لاشه‌اش را توی دفتر بردند و بچه‌ها را مرخص کردند و من به اتاقم برگشتم و با حالی زار روی صندلی افتادم، نه از پدر خبری بود و نه از مادر و نه از عروسک‌های کوکی‌شان که ناموسش دست کاری شده بود. و تازه احساس کردم که این کتک‌کاری را باید به او می‌زدم. خیس عرق بودم و دهانم تلخ بود. تمام فحش‌هایی که می‌بایست به آن مردکه‌ی دبنگ می‌دادم و نداده بودم، در دهانم رسوب کرده بود و مثل دم مار تلخ شده بود. اصلاً چرا زدمش؟ چرا نگذاشتم مثل همیشه ناظم میدان‌داری کند که هم کارکشته‌تر بود و هم خونسردتر. لابد پسرک با دخترعمه‌اش هم نمی‌تواند بازی کند. لابد توی خانواده‌شان، دخترها سر ده دوازده سالگی باید از پسرهای هم سن رو بگیرند. نکند عیبی کرده باشد؟ و یک مرتبه به صرافت افتادم که بروم ببینم چه بلایی به سرش آورده‌ام. بلند شدم و یکی از فراش‌ها را صدا کردم که فهمیدم روانه‌اش کرده‌اند. آبی آورد که روی دستم می‌ریخت و صورتم را می‌شستم و می‌کوشیدم که لرزش دست‌هایم را نبیند. و در گوشم آهسته گفت که پسر مدیر شرکت اتوبوسرانی است و بدجوری کتک خورده و آن‌ها خیلی سعی کرده‌اند که تر و تمیزش کنند... + +احمق مثلا داشت توی دل مرا خالی می‌کرد. نمی‌دانست که من اول تصمیم را گرفتم، بعد مثل سگ هار شدم. و تازه می‌فهمیدم کسی را زده‌ام که لیاقتش را داشته. حتماً از این اتفاق‌ها جای دیگر هم می‌افتد. آدم بردارد پایین تنه بچه‌ی خودش را، یا به قول خودش ناموسش را بگذارد سر گذر که کلانتر محل و پزشک معاینه کنند! تا پرونده درست کنند؟ با این پدرو مادرها بچه‌ها حق دارند که قرتی و دزد و دروغگو از آب در بیایند. این مدرسه‌ها را اول برای پدر و مادرها باز کنند... + +با این افکار به خانه رسیدم. زنم در را که باز کرد؛ چشم‌هایش گرد شد. همیشه وقتی می‌ترسد این طور می‌شود. برای اینکه خیال نکند آدم کشته‌ام، زود قضایا را برایش گفتم. و دیدم که در ماند. یعنی ساکت ماند. آب سرد، عرق بیدمشک، سیگار پشت سیگار فایده نداشت، لقمه از گلویم پایین نمی‌رفت و دست‌ها هنوز می‌لرزید. هر کدام به اندازه‌ی یک ماه فعالیت کرده بودند. با سیگار چهارم شروع کردم: + +- می‌دانی زن؟ بابای یارو پول‌داره. مسلماً کار به دادگستری و این جور خنس‌ها می‌کشه. مدیریت که الفاتحه. اما خیلی دلم می‌خواد قضیه به دادگاه برسه. یک سال آزگار رو دل کشیده‌ام و دیگه خسته شده‌ام. دلم می‌خواد یکی بپرسه چرا بچه‌ی مردم رو این طوری زدی، چرا تنبیه بدنی کردی! آخه یک مدیر مدرسه هم حرف‌هایی داره که باید یک جایی بزنه... + +که بلند شد و رفت سراغ تلفن. دو سه تا از دوستانم را که در دادگستری کاره‌ای بودند، گرفت و خودم قضیه را برایشان گفتم که مواظب باشند. فردا پسرک فاعل به مدرسه نیامده بود. و ناظم برایم گفت که قضیه ازین قرار بوده است که دوتایی به هوای دیدن مجموعه تمبرهای فاعل با هم به خانه‌ای می‌روند و قضایا همان جا اتفاق می‌افتد و داد و هوار و دخالت پدر و مادرهای طرفین و خط و نشان و شبانه کلانتری؛ و تمام اهل محل خبر دارند. او هم نظرش این بود که کار به دادگستری خواهد کشید. + +و من یک هفته‌ی تمام به انتظار اخطاریه‌ی دادگستری صبح و عصر به مدرسه رفتم و مثل بخت‌النصر پشت پنجره ایستادم. اما در تمام این مدت نه از فاعل خبری شد، نه از مفعول و نه از پدر و مادر ناموس‌پرست و نه از مدیر شرکت اتوبوسرانی. انگار نه انگار که اتفاقی افتاده. بچه‌ها می‌آمدند و می‌رفتند؛ برای آب خوردن عجله می‌کردند؛ به جای بازی کتک‌کاری می‌کردند و همه چیز مثل قبل بود. فقط من ماندم و یک دنیا حرف و انتظار. تا عاقبت رسید.... احضاریه‌ای با تعیین وقت قبلی برای دو روز بعد، در فلان شعبه و پیش فلان بازپرس دادگستری. آخر کسی پیدا شده بود که به حرفم گوش کند. + +تا دو روز بعد که موعد احضار بود، اصلاً از خانه در نیامدم. نشستم و ماحصل حرف‌هایم را روی کاغذ آوردم. حرف‌هایی که با همه‌ی چرندی هر وزیر فرهنگی می‌توانست با آن یک برنامه‌ی هفت ساله برای کارش بریزد. و سر ساعت معین رفتم دادگستری. اتاق معین و بازپرس معین. در را باز کردم و سلام، و تا آمدم خودم را معرفی کنم و احضاریه را در بیاورم، یارو پیش‌دستی کرد و صندلی آورد و چای سفارش داد و «احتیاجی به این حرف‌ها نیست و قضیه‌ی کوچک بود و حل شد و راضی به زحمت شما نبودیم...» + +که عرق سرد بر بدن من نشست. چایی‌ام را که خوردم، روی همان کاغذ نشان‌دار دادگستری استعفانامه‌ام را نوشتم و به نام هم‌کلاسی پخمه‌ام که تازه رئیس شده بود، دم در پست کردم. +EOT; +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/fi_FI/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/fi_FI/Address.php new file mode 100644 index 0000000..8e0829e --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/fi_FI/Address.php @@ -0,0 +1,85 @@ + 'Ain'), array('02' => 'Aisne'), array('03' => 'Allier'), array('04' => 'Alpes-de-Haute-Provence'), array('05' => 'Hautes-Alpes'), + array('06' => 'Alpes-Maritimes'), array('07' => 'Ardèche'), array('08' => 'Ardennes'), array('09' => 'Ariège'), array('10' => 'Aube'), + array('11' => 'Aude'), array('12' => 'Aveyron'), array('13' => 'Bouches-du-Rhône'), array('14' => 'Calvados'), array('15' => 'Cantal'), + array('16' => 'Charente'), array('17' => 'Charente-Maritime'), array('18' => 'Cher'), array('19' => 'Corrèze'), array('2A' => 'Corse-du-Sud'), + array('2B' => 'Haute-Corse'), array('21' => "Côte-d'Or"), array('22' => "Côtes-d'Armor"), array('23' => 'Creuse'), array('24' => 'Dordogne'), + array('25' => 'Doubs'), array('26' => 'Drôme'), array('27' => 'Eure'), array('28' => 'Eure-et-Loir'), array('29' => 'Finistère'), array('30' => 'Gard'), + array('31' => 'Haute-Garonne'), array('32' => 'Gers'), array('33' => 'Gironde'), array('34' => 'Hérault'), array('35' => 'Ille-et-Vilaine'), + array('36' => 'Indre'), array('37' => 'Indre-et-Loire'), array('38' => 'Isère'), array('39' => 'Jura'), array('40' => 'Landes'), array('41' => 'Loir-et-Cher'), + array('42' => 'Loire'), array('43' => 'Haute-Loire'), array('44' => 'Loire-Atlantique'), array('45' => 'Loiret'), array('46' => 'Lot'), + array('47' => 'Lot-et-Garonne'), array('48' => 'Lozère'), array('49' => 'Maine-et-Loire'), array('50' => 'Manche'), array('51' => 'Marne'), + array('52' => 'Haute-Marne'), array('53' => 'Mayenne'), array('54' => 'Meurthe-et-Moselle'), array('55' => 'Meuse'), array('56' => 'Morbihan'), + array('57' => 'Moselle'), array('58' => 'Nièvre'), array('59' => 'Nord'), array('60' => 'Oise'), array('61' => 'Orne'), array('62' => 'Pas-de-Calais'), + array('63' => 'Puy-de-Dôme'), array('64' => 'Pyrénées-Atlantiques'), array('65' => 'Hautes-Pyrénées'), array('66' => 'Pyrénées-Orientales'), + array('67' => 'Bas-Rhin'), array('68' => 'Haut-Rhin'), array('69' => 'Rhône'), array('70' => 'Haute-Saône'), array('71' => 'Saône-et-Loire'), + array('72' => 'Sarthe'), array('73' => 'Savoie'), array('74' => 'Haute-Savoie'), array('75' => 'Paris'), array('76' => 'Seine-Maritime'), + array('77' => 'Seine-et-Marne'), array('78' => 'Yvelines'), array('79' => 'Deux-Sèvres'), array('80' => 'Somme'), array('81' => 'Tarn'), + array('82' => 'Tarn-et-Garonne'), array('83' => 'Var'), array('84' => 'Vaucluse'), array('85' => 'Vendée'), array('86' => 'Vienne'), + array('87' => 'Haute-Vienne'), array('88' => 'Vosges'), array('89' => 'Yonne'), array('90' => 'Territoire de Belfort'), array('91' => 'Essonne'), + array('92' => 'Hauts-de-Seine'), array('93' => 'Seine-Saint-Denis'), array('94' => 'Val-de-Marne'), array('95' => "Val-d'Oise"), + array('971' => 'Guadeloupe'), array('972' => 'Martinique'), array('973' => 'Guyane'), array('974' => 'La Réunion'), array('976' => 'Mayotte') + ); + + /** + * @example 'rue' + */ + public static function streetPrefix() + { + return static::randomElement(static::$streetPrefix); + } + + /** + * Randomly returns a french region. + * + * @example 'Guadeloupe' + * + * @return string + */ + public static function region() + { + return static::randomElement(static::$regions); + } + + /** + * Randomly returns a french department ('departmentNumber' => 'departmentName'). + * + * @example array('2B' => 'Haute-Corse') + * + * @return array + */ + public static function department() + { + return static::randomElement(static::$departments); + } + + /** + * Randomly returns a french department name. + * + * @example 'Ardèche' + * + * @return string + */ + public static function departmentName() + { + $randomDepartmentName = array_values(static::department()); + + return $randomDepartmentName[0]; + } + + /** + * Randomly returns a french department number. + * + * @example '59' + * + * @return string + */ + public static function departmentNumber() + { + $randomDepartmentNumber = array_keys(static::department()); + + return $randomDepartmentNumber[0]; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Company.php b/vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Company.php new file mode 100644 index 0000000..5f44066 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Company.php @@ -0,0 +1,169 @@ +generator->parse($format)); + + if ($this->isCatchPhraseValid($catchPhrase)) { + break; + } + } while (true); + + return $catchPhrase; + } + + /** + * Generates a siret number (14 digits) that passes the Luhn check. + * + * @see http://fr.wikipedia.org/wiki/Syst%C3%A8me_d'identification_du_r%C3%A9pertoire_des_%C3%A9tablissements + * @return string + */ + public function siret($formatted = true) + { + $siret = $this->siren(false); + $nicFormat = static::randomElement(static::$siretNicFormats); + $siret .= $this->numerify($nicFormat); + $siret .= Luhn::computeCheckDigit($siret); + if ($formatted) { + $siret = substr($siret, 0, 3) . ' ' . substr($siret, 3, 3) . ' ' . substr($siret, 6, 3) . ' ' . substr($siret, 9, 5); + } + + return $siret; + } + + /** + * Generates a siren number (9 digits) that passes the Luhn check. + * + * @see http://fr.wikipedia.org/wiki/Syst%C3%A8me_d%27identification_du_r%C3%A9pertoire_des_entreprises + * @return string + */ + public function siren($formatted = true) + { + $siren = $this->numerify('%#######'); + $siren .= Luhn::computeCheckDigit($siren); + if ($formatted) { + $siren = substr($siren, 0, 3) . ' ' . substr($siren, 3, 3) . ' ' . substr($siren, 6, 3); + } + + return $siren; + } + + /** + * @var array An array containing string which should not appear twice in a catch phrase. + */ + protected static $wordsWhichShouldNotAppearTwice = array('sécurité', 'simpl'); + + /** + * Validates a french catch phrase. + * + * @param string $catchPhrase The catch phrase to validate. + * + * @return boolean (true if valid, false otherwise) + */ + protected static function isCatchPhraseValid($catchPhrase) + { + foreach (static::$wordsWhichShouldNotAppearTwice as $word) { + // Fastest way to check if a piece of word does not appear twice. + $beginPos = strpos($catchPhrase, $word); + $endPos = strrpos($catchPhrase, $word); + + if ($beginPos !== false && $beginPos != $endPos) { + return false; + } + } + + return true; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Internet.php new file mode 100644 index 0000000..8e3024b --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/fr_FR/Internet.php @@ -0,0 +1,9 @@ +generator->parse($format); + } + + public static function country() + { + return static::randomElement(static::$country); + } + + public static function postcode() + { + return static::toUpper(static::bothify(static::randomElement(static::$postcode))); + } + + public static function regionSuffix() + { + return static::randomElement(static::$regionSuffix); + } + + public static function region() + { + return static::randomElement(static::$region); + } + + public static function cityPrefix() + { + return static::randomElement(static::$cityPrefix); + } + + public function city() + { + return static::randomElement(static::$city); + } + + public function streetPrefix() + { + return static::randomElement(static::$streetPrefix); + } + + public static function street() + { + return static::randomElement(static::$street); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/hy_AM/Company.php b/vendor/fzaninotto/faker/src/Faker/Provider/hy_AM/Company.php new file mode 100644 index 0000000..8ef3cce --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/hy_AM/Company.php @@ -0,0 +1,54 @@ +generator->parse($format); + } + + public static function street() + { + return static::randomElement(static::$street); + } + + public static function buildingNumber() + { + return static::numberBetween(1, 999); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/id_ID/Company.php b/vendor/fzaninotto/faker/src/Faker/Provider/id_ID/Company.php new file mode 100644 index 0000000..7839f1e --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/id_ID/Company.php @@ -0,0 +1,43 @@ +generator->parse($lastNameRandomElement); + } + + /** + * Return last name for male + * + * @access public + * @return string last name + */ + public static function lastNameMale() + { + return static::randomElement(static::$lastNameMale); + } + + /** + * Return last name for female + * + * @access public + * @return string last name + */ + public static function lastNameFemale() + { + return static::randomElement(static::$lastNameFemale); + } + + /** + * For academic title + * + * @access public + * @return string suffix + */ + public static function suffix() + { + return static::randomElement(static::$suffix); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/id_ID/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/id_ID/PhoneNumber.php new file mode 100644 index 0000000..de5c969 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/id_ID/PhoneNumber.php @@ -0,0 +1,55 @@ + + */ +class Address extends \Faker\Provider\Address +{ + /** + * @var array Countries in icelandic + */ + protected static $country = array( + 'Afganistan', 'Albanía', 'Alsír', 'Andorra', 'Angóla', 'Angvilla', 'Antígva og Barbúda', 'Argentína', + 'Armenía', 'Arúba', 'Aserbaídsjan', 'Austur-Kongó', 'Austurríki', 'Austur-Tímor', 'Álandseyjar', + 'Ástralía', 'Bahamaeyjar', 'Bandaríkin', 'Bandaríska Samóa', 'Bangladess', 'Barbados', 'Barein', + 'Belgía', 'Belís', 'Benín', 'Bermúdaeyjar', 'Bosnía og Hersegóvína', 'Botsvana', 'Bouvet-eyja', 'Bólivía', + 'Brasilía', 'Bresku Indlandshafseyjar', 'Bretland', 'Brúnei', 'Búlgaría', 'Búrkína Fasó', 'Búrúndí', 'Bútan', + 'Cayman-eyjar', 'Chile', 'Cooks-eyjar', 'Danmörk', 'Djíbútí', 'Dóminíka', 'Dóminíska lýðveldið', 'Egyptaland', + 'Eistland', 'Ekvador', 'El Salvador', 'England', 'Erítrea', 'Eþíópía', 'Falklandseyjar', 'Filippseyjar', + 'Finnland', 'Fídjieyjar', 'Fílabeinsströndin', 'Frakkland', 'Franska Gvæjana', 'Franska Pólýnesía', + 'Frönsku suðlægu landsvæðin', 'Færeyjar', 'Gabon', 'Gambía', 'Gana', 'Georgía', 'Gíbraltar', 'Gínea', + 'Gínea-Bissá', 'Grenada', 'Grikkland', 'Grænhöfðaeyjar', 'Grænland', 'Gvadelúpeyjar', 'Gvam', 'Gvatemala', + 'Gvæjana', 'Haítí', 'Heard og McDonalds-eyjar', 'Holland', 'Hollensku Antillur', 'Hondúras', 'Hong Kong', + 'Hvíta-Rússland', 'Indland', 'Indónesía', 'Írak', 'Íran', 'Írland', 'Ísland', 'Ísrael', 'Ítalía', 'Jamaíka', + 'Japan', 'Jemen', 'Jólaey', 'Jómfrúaeyjar', 'Jórdanía', 'Kambódía', 'Kamerún', 'Kanada', 'Kasakstan', 'Katar', + 'Kenía', 'Kirgisistan', 'Kína', 'Kíribatí', 'Kongó', 'Austur-Kongó', 'Vestur-Kongó', 'Kostaríka', 'Kókoseyjar', + 'Kólumbía', 'Kómoreyjar', 'Kórea', 'Norður-Kórea;', 'Suður-Kórea', 'Króatía', 'Kúba', 'Kúveit', 'Kýpur', + 'Laos', 'Lesótó', 'Lettland', 'Liechtenstein', 'Litháen', 'Líbanon', 'Líbería', 'Líbía', 'Lúxemborg', + 'Madagaskar', 'Makaó', 'Makedónía', 'Malasía', 'Malaví', 'Maldíveyjar', 'Malí', 'Malta', 'Marokkó', + 'Marshall-eyjar', 'Martiník', 'Mayotte', 'Máritanía', 'Máritíus', 'Mexíkó', 'Mið-Afríkulýðveldið', + 'Miðbaugs-Gínea', 'Míkrónesía', 'Mjanmar', 'Moldóva', 'Mongólía', 'Montserrat', 'Mónakó', 'Mósambík', + 'Namibía', 'Nárú', 'Nepal', 'Niue', 'Níger', 'Nígería', 'Níkaragva', 'Norður-Írland', 'Norður-Kórea', + 'Norður-Maríanaeyjar', 'Noregur', 'Norfolkeyja', 'Nýja-Kaledónía', 'Nýja-Sjáland', 'Óman', 'Pakistan', + 'Palá', 'Palestína', 'Panama', 'Papúa Nýja-Gínea', 'Paragvæ', 'Páfagarður', 'Perú', 'Pitcairn', 'Portúgal', + 'Pólland', 'Púertó Ríkó', 'Réunion', 'Rúanda', 'Rúmenía', 'Rússland', 'Salómonseyjar', 'Sambía', + 'Sameinuðu arabísku furstadæmin', 'Samóa', 'San Marínó', 'Sankti Helena', 'Sankti Kristófer og Nevis', + 'Sankti Lúsía', 'Sankti Pierre og Miquelon', 'Sankti Vinsent og Grenadíneyjar', 'Saó Tóme og Prinsípe', + 'Sádi-Arabía', 'Senegal', 'Serbía', 'Seychelles-eyjar', 'Simbabve', 'Singapúr', 'Síerra Leóne', 'Skotland', + 'Slóvakía', 'Slóvenía', 'Smáeyjar Bandaríkjanna', 'Sómalía', 'Spánn', 'Srí Lanka', 'Suður-Afríka', + 'Suður-Georgía og Suður-Sandvíkureyjar', 'Suður-Kórea', 'Suðurskautslandið', 'Súdan', 'Súrínam', 'Jan Mayen', + 'Svartfjallaland', 'Svasíland', 'Sviss', 'Svíþjóð', 'Sýrland', 'Tadsjikistan', 'Taíland', 'Taívan', 'Tansanía', + 'Tékkland', 'Tonga', 'Tógó', 'Tókelá', 'Trínidad og Tóbagó', 'Tsjad', 'Tsjetsjenía', 'Turks- og Caicos-eyjar', + 'Túnis', 'Túrkmenistan', 'Túvalú', 'Tyrkland', 'Ungverjaland', 'Úganda', 'Úkraína', 'Úrúgvæ', 'Úsbekistan', + 'Vanúatú', 'Venesúela', 'Vestur-Kongó', 'Vestur-Sahara', 'Víetnam', 'Wales', 'Wallis- og Fútúnaeyjar', 'Þýskaland' + ); + + /** + * @var array Icelandic cities. + */ + protected static $cityNames = array( + 'Reykjavík', 'Seltjarnarnes', 'Vogar', 'Kópavogur', 'Garðabær', 'Hafnarfjörður', 'Reykjanesbær', 'Grindavík', + 'Sandgerði', 'Garður', 'Reykjanesbær', 'Mosfellsbær', 'Akranes', 'Borgarnes', 'Reykholt', 'Stykkishólmur', + 'Flatey', 'Grundarfjörður', 'Ólafsvík', 'Snæfellsbær', 'Hellissandur', 'Búðardalur', 'Reykhólahreppur', + 'Ísafjörður', 'Hnífsdalur', 'Bolungarvík', 'Súðavík', 'Flateyri', 'Suðureyri', 'Patreksfjörður', + 'Tálknafjörður', 'Bíldudalur', 'Þingeyri', 'Staður', 'Hólmavík', 'Drangsnes', 'Árneshreppur', 'Hvammstangi', + 'Blönduós', 'Skagaströnd', 'Sauðárkrókur', 'Varmahlíð', 'Hofsós', 'Fljót', 'Siglufjörður', 'Akureyri', + 'Grenivík', 'Grímsey', 'Dalvík', 'Ólafsfjörður', 'Hrísey', 'Húsavík', 'Fosshóll', 'Laugar', 'Mývatn', + 'Kópasker', 'Raufarhöfn', 'Þórshöfn', 'Bakkafjörður', 'Vopnafjörður', 'Egilsstaðir', 'Seyðisfjörður', + 'Mjóifjörður', 'Borgarfjörður', 'Reyðarfjörður', 'Eskifjörður', 'Neskaupstaður', 'Fáskrúðsfjörður', + 'Stöðvarfjörður', 'Breiðdalsvík', 'Djúpivogur', 'Höfn', 'Selfoss', 'Hveragerði', 'Þorlákshöfn', 'Ölfus', + 'Eyrarbakki', 'Stokkseyri', 'Laugarvatn', 'Flúðir', 'Hella', 'Hvolsvöllur', 'Vík', 'Kirkjubæjarklaustur', + 'Vestmannaeyjar' + ); + + /** + * @var array Street name suffix. + */ + protected static $streetSuffix = array( + 'ás', 'bakki', 'braut', 'bær', 'brún', 'berg', 'fold', 'gata', 'gróf', + 'garðar', 'höfði', 'heimar', 'hamar', 'hólar', 'háls', 'kvísl', 'lækur', + 'leiti', 'land', 'múli', 'nes', 'rimi', 'stígur', 'stræti', 'stekkur', + 'slóð', 'skógar', 'sel', 'teigur', 'tún', 'vangur', 'vegur', 'vogur', + 'vað' + ); + + /** + * @var array Street name prefix. + */ + protected static $streetPrefix = array( + 'Aðal', 'Austur', 'Bakka', 'Braga', 'Báru', 'Brunn', 'Fiski', 'Leifs', + 'Týs', 'Birki', 'Suður', 'Norður', 'Vestur', 'Austur', 'Sanda', 'Skógar', + 'Stór', 'Sunnu', 'Tungu', 'Tangar', 'Úlfarfells', 'Vagn', 'Vind', 'Ysti', + 'Þing', 'Hamra', 'Hóla', 'Kríu', 'Iðu', 'Spóa', 'Starra', 'Uglu', 'Vals' + ); + + /** + * @var Icelandic zip code. + **/ + protected static $postcode = array( + '%##' + ); + + /** + * @var array Icelandic regions. + */ + protected static $regionNames = array( + 'Höfuðborgarsvæðið', 'Norðurland', 'Suðurland', 'Vesturland', 'Vestfirðir', 'Austurland', 'Suðurnes' + ); + + /** + * @var array Icelandic building numbers. + */ + protected static $buildingNumber = array( + '%##', '%#', '%#', '%', '%', '%', '%?', '% ?', + ); + + /** + * @var array Icelandic city format. + */ + protected static $cityFormats = array( + '{{cityName}}', + ); + + /** + * @var array Icelandic street's name formats. + */ + protected static $streetNameFormats = array( + '{{streetPrefix}}{{streetSuffix}}', + '{{streetPrefix}}{{streetSuffix}}', + '{{firstNameMale}}{{streetSuffix}}', + '{{firstNameFemale}}{{streetSuffix}}' + ); + + /** + * @var array Icelandic street's address formats. + */ + protected static $streetAddressFormats = array( + '{{streetName}} {{buildingNumber}}' + ); + + /** + * @var array Icelandic address format. + */ + protected static $addressFormats = array( + "{{streetAddress}}\n{{postcode}} {{city}}", + ); + + /** + * Randomly return a real city name. + * + * @return string + */ + public static function cityName() + { + return static::randomElement(static::$cityNames); + } + + /** + * Randomly return a street prefix. + * + * @return string + */ + public static function streetPrefix() + { + return static::randomElement(static::$streetPrefix); + } + + /** + * Randomly return a building number. + * + * @return string + */ + public static function buildingNumber() + { + return static::toUpper(static::bothify(static::randomElement(static::$buildingNumber))); + } + + /** + * Randomly return a real region name. + * + * @return string + */ + public static function region() + { + return static::randomElement(static::$regionNames); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Company.php b/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Company.php new file mode 100644 index 0000000..6b93451 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Company.php @@ -0,0 +1,53 @@ + + */ +class Company extends \Faker\Provider\Company +{ + /** + * @var array Danish company name formats. + */ + protected static $formats = array( + '{{lastName}} {{companySuffix}}', + '{{lastName}} {{companySuffix}}', + '{{lastName}} {{companySuffix}}', + '{{firstname}} {{lastName}} {{companySuffix}}', + '{{middleName}} {{companySuffix}}', + '{{middleName}} {{companySuffix}}', + '{{middleName}} {{companySuffix}}', + '{{firstname}} {{middleName}} {{companySuffix}}', + '{{lastName}} & {{lastName}} {{companySuffix}}', + '{{lastName}} og {{lastName}} {{companySuffix}}', + '{{lastName}} & {{lastName}} {{companySuffix}}', + '{{lastName}} og {{lastName}} {{companySuffix}}', + '{{middleName}} & {{middleName}} {{companySuffix}}', + '{{middleName}} og {{middleName}} {{companySuffix}}', + '{{middleName}} & {{lastName}}', + '{{middleName}} og {{lastName}}', + ); + + /** + * @var array Company suffixes. + */ + protected static $companySuffix = array('ehf.', 'hf.', 'sf.'); + + /** + * @link http://www.rsk.is/atvinnurekstur/virdisaukaskattur/ + * + * @var string VSK number format. + */ + protected static $vskFormat = '%####'; + + /** + * Generates a VSK number (5 digits). + * + * @return string + */ + public static function vsk() + { + return static::numerify(static::$vskFormat); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Internet.php new file mode 100644 index 0000000..a265da6 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Internet.php @@ -0,0 +1,23 @@ + + */ +class Internet extends \Faker\Provider\Internet +{ + /** + * @var array Some email domains in Denmark. + */ + protected static $freeEmailDomain = array( + 'gmail.com', 'yahoo.com', 'hotmail.com', 'visir.is', 'simnet.is', 'internet.is' + ); + + /** + * @var array Some TLD. + */ + protected static $tld = array( + 'com', 'com', 'com', 'net', 'is', 'is', 'is', + ); +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Payment.php b/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Payment.php new file mode 100644 index 0000000..c119c38 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/Payment.php @@ -0,0 +1,19 @@ + + */ +class Person extends \Faker\Provider\Person +{ + /** + * @var array Icelandic person name formats. + */ + protected static $maleNameFormats = array( + '{{firstNameMale}} {{lastNameMale}}', + '{{firstNameMale}} {{lastNameMale}}', + '{{firstNameMale}} {{middleName}} {{lastNameMale}}', + '{{firstNameMale}} {{middleName}} {{lastNameMale}}', + ); + + protected static $femaleNameFormats = array( + '{{firstNameFemale}} {{lastNameFemale}}', + '{{firstNameFemale}} {{lastNameFemale}}', + '{{firstNameFemale}} {{middleName}} {{lastNameFemale}}', + '{{firstNameFemale}} {{middleName}} {{lastNameFemale}}', + ); + + /** + * @var string Icelandic women names. + */ + protected static $firstNameFemale = array('Aagot', 'Abela', 'Abigael', 'Ada', 'Adda', 'Addý', 'Adela', 'Adelía', 'Adríana', 'Aðalbjörg', 'Aðalbjört', 'Aðalborg', 'Aðaldís', 'Aðalfríður', 'Aðalheiður', 'Aðalrós', 'Aðalsteina', 'Aðalsteinunn', 'Aðalveig', 'Agata', 'Agatha', 'Agða', 'Agla', 'Agnea', 'Agnes', 'Agneta', 'Alanta', 'Alba', 'Alberta', 'Albína', 'Alda', 'Aldís', 'Aldný', 'Aleta', 'Aletta', 'Alexa', 'Alexandra', 'Alexandría', 'Alexis', 'Alexía', 'Alfa', 'Alfífa', 'Alice', 'Alida', 'Alída', 'Alína', 'Alís', 'Alísa', 'Alla', 'Allý', 'Alma', 'Alrún', 'Alva', 'Alvilda', 'Amadea', 'Amal', 'Amalía', 'Amanda', 'Amelía', 'Amilía', 'Amíra', 'Amy', 'Amý', 'Analía', 'Anastasía', 'Andra', 'Andrá', 'Andrea', 'Anetta', 'Angela', 'Angelíka', 'Anika', 'Anita', 'Aníka', 'Anína', 'Aníta', 'Anja', 'Ann', 'Anna', 'Annabella', 'Annalísa', 'Anne', 'Annelí', 'Annetta', 'Anney', 'Annika', 'Annía', 'Anný', 'Antonía', 'Apríl', 'Ardís', 'Arey', 'Arinbjörg', 'Aris', 'Arisa', 'Aría', 'Aríanna', 'Aríella', 'Arín', 'Arína', 'Arís', 'Armenía', 'Arna', 'Arnbjörg', 'Arnborg', 'Arndís', 'Arney', 'Arnfinna', 'Arnfríður', 'Arngerður', 'Arngunnur', 'Arnheiður', 'Arnhildur', 'Arnika', 'Arnkatla', 'Arnlaug', 'Arnleif', 'Arnlín', 'Arnljót', 'Arnóra', 'Arnrós', 'Arnrún', 'Arnþóra', 'Arnþrúður', 'Asírí', 'Askja', 'Assa', 'Astrid', 'Atalía', 'Atena', 'Athena', 'Atla', 'Atlanta', 'Auðbjörg', 'Auðbjört', 'Auðdís', 'Auðlín', 'Auðna', 'Auðný', 'Auðrún', 'Auður', 'Aurora', 'Axelía', 'Axelma', 'Aþena', 'Ágústa', 'Ágústína', 'Álfdís', 'Álfey', 'Álfgerður', 'Álfheiður', 'Álfhildur', 'Álfrós', 'Álfrún', 'Álfsól', 'Árbjörg', 'Árbjört', 'Árdís', 'Árelía', 'Árlaug', 'Ármey', 'Árna', 'Árndís', 'Árney', 'Árnheiður', 'Árnína', 'Árný', 'Áróra', 'Ársól', 'Ársæl', 'Árún', 'Árveig', 'Árvök', 'Árþóra', 'Ása', 'Ásbjörg', 'Ásborg', 'Ásdís', 'Ásfríður', 'Ásgerður', 'Áshildur', 'Áskatla', 'Ásla', 'Áslaug', 'Ásleif', 'Ásný', 'Ásrós', 'Ásrún', 'Ást', 'Ásta', 'Ástbjörg', 'Ástbjört', 'Ástdís', 'Ástfríður', 'Ástgerður', 'Ástheiður', 'Ásthildur', 'Ástríður', 'Ástrós', 'Ástrún', 'Ástveig', 'Ástþóra', 'Ástþrúður', 'Ásvör', 'Baldey', 'Baldrún', 'Baldvina', 'Barbara', 'Barbára', 'Bassí', 'Bára', 'Bebba', 'Begga', 'Belinda', 'Bella', 'Benedikta', 'Bengta', 'Benidikta', 'Benía', 'Beníta', 'Benna', 'Benney', 'Benný', 'Benta', 'Bentey', 'Bentína', 'Bera', 'Bergdís', 'Bergey', 'Bergfríður', 'Bergheiður', 'Berghildur', 'Berglaug', 'Berglind', 'Berglín', 'Bergljót', 'Bergmannía', 'Bergný', 'Bergrán', 'Bergrín', 'Bergrós', 'Bergrún', 'Bergþóra', 'Berit', 'Bernódía', 'Berta', 'Bertha', 'Bessí', 'Bestla', 'Beta', 'Betanía', 'Betsý', 'Bettý', 'Bil', 'Birgit', 'Birgitta', 'Birna', 'Birta', 'Birtna', 'Bíbí', 'Bína', 'Bjargdís', 'Bjargey', 'Bjargheiður', 'Bjarghildur', 'Bjarglind', 'Bjarkey', 'Bjarklind', 'Bjarma', 'Bjarndís', 'Bjarney', 'Bjarnfríður', 'Bjarngerður', 'Bjarnheiður', 'Bjarnhildur', 'Bjarnlaug', 'Bjarnrún', 'Bjarnveig', 'Bjarný', 'Bjarnþóra', 'Bjarnþrúður', 'Bjartey', 'Bjartmey', 'Björg', 'Björgey', 'Björgheiður', 'Björghildur', 'Björk', 'Björney', 'Björnfríður', 'Björt', 'Bláey', 'Blíða', 'Blín', 'Blómey', 'Blædís', 'Blær', 'Bobba', 'Boga', 'Bogdís', 'Bogey', 'Bogga', 'Boghildur', 'Borg', 'Borgdís', 'Borghildur', 'Borgný', 'Borgrún', 'Borgþóra', 'Botnía', 'Bóel', 'Bót', 'Bóthildur', 'Braga', 'Braghildur', 'Branddís', 'Brá', 'Brák', 'Brigitta', 'Brimdís', 'Brimhildur', 'Brimrún', 'Brit', 'Britt', 'Britta', 'Bríana', 'Bríanna', 'Bríet', 'Bryndís', 'Brynfríður', 'Bryngerður', 'Brynheiður', 'Brynhildur', 'Brynja', 'Brynný', 'Burkney', 'Bylgja', 'Camilla', 'Carla', 'Carmen', 'Cecilia', 'Cecilía', 'Charlotta', 'Charlotte', 'Christina', 'Christine', 'Clara', 'Daðey', 'Daðína', 'Dagbjörg', 'Dagbjört', 'Dagfríður', 'Daggrós', 'Dagheiður', 'Dagmar', 'Dagmey', 'Dagný', 'Dagrún', 'Daldís', 'Daley', 'Dalía', 'Dalla', 'Dallilja', 'Dalrós', 'Dana', 'Daney', 'Danfríður', 'Danheiður', 'Danhildur', 'Danía', 'Daníela', 'Daníella', 'Dara', 'Debora', 'Debóra', 'Dendý', 'Didda', 'Dilja', 'Diljá', 'Dimmblá', 'Dimmey', 'Día', 'Díana', 'Díanna', 'Díma', 'Dís', 'Dísa', 'Dísella', 'Donna', 'Doris', 'Dorothea', 'Dóa', 'Dómhildur', 'Dóra', 'Dórey', 'Dóris', 'Dórothea', 'Dórótea', 'Dóróthea', 'Drauma', 'Draumey', 'Drífa', 'Droplaug', 'Drótt', 'Dröfn', 'Dúa', 'Dúfa', 'Dúna', 'Dýrborg', 'Dýrfinna', 'Dýrleif', 'Dýrley', 'Dýrunn', 'Dæja', 'Dögg', 'Dögun', 'Ebba', 'Ebonney', 'Edda', 'Edel', 'Edil', 'Edit', 'Edith', 'Eðna', 'Efemía', 'Egedía', 'Eggrún', 'Egla', 'Eiðný', 'Eiðunn', 'Eik', 'Einbjörg', 'Eindís', 'Einey', 'Einfríður', 'Einhildur', 'Einína', 'Einrún', 'Eir', 'Eirdís', 'Eirfinna', 'Eiríka', 'Eirný', 'Eirún', 'Elba', 'Eldbjörg', 'Eldey', 'Eldlilja', 'Eldrún', 'Eleina', 'Elektra', 'Elena', 'Elenborg', 'Elfa', 'Elfur', 'Elina', 'Elinborg', 'Elisabeth', 'Elía', 'Elíana', 'Elín', 'Elína', 'Elíná', 'Elínbet', 'Elínbjörg', 'Elínbjört', 'Elínborg', 'Elíndís', 'Elíngunnur', 'Elínheiður', 'Elínrós', 'Elírós', 'Elísa', 'Elísabet', 'Elísabeth', 'Elka', 'Ella', 'Ellen', 'Elley', 'Ellisif', 'Ellín', 'Elly', 'Ellý', 'Elma', 'Elna', 'Elsa', 'Elsabet', 'Elsie', 'Elsí', 'Elsý', 'Elva', 'Elvi', 'Elvíra', 'Elvý', 'Embla', 'Emelía', 'Emelíana', 'Emelína', 'Emeralda', 'Emilía', 'Emilíana', 'Emilíanna', 'Emilý', 'Emma', 'Emmý', 'Emý', 'Enea', 'Eneka', 'Engilbjört', 'Engilráð', 'Engilrós', 'Engla', 'Enika', 'Enja', 'Enóla', 'Eres', 'Erika', 'Erin', 'Erla', 'Erlen', 'Erlín', 'Erna', 'Esja', 'Esmeralda', 'Ester', 'Esther', 'Estiva', 'Ethel', 'Etna', 'Eufemía', 'Eva', 'Evelyn', 'Evey', 'Evfemía', 'Evgenía', 'Evíta', 'Evlalía', 'Ey', 'Eybjörg', 'Eybjört', 'Eydís', 'Eyfríður', 'Eygerður', 'Eygló', 'Eyhildur', 'Eyja', 'Eyjalín', 'Eyleif', 'Eylín', 'Eyrós', 'Eyrún', 'Eyveig', 'Eyvör', 'Eyþóra', 'Eyþrúður', 'Fanndís', 'Fanney', 'Fannlaug', 'Fanny', 'Fanný', 'Febrún', 'Fema', 'Filipía', 'Filippa', 'Filippía', 'Finna', 'Finnbjörg', 'Finnbjörk', 'Finnboga', 'Finnborg', 'Finndís', 'Finney', 'Finnfríður', 'Finnlaug', 'Finnrós', 'Fía', 'Fídes', 'Fífa', 'Fjalldís', 'Fjóla', 'Flóra', 'Folda', 'Fransiska', 'Franziska', 'Frán', 'Fregn', 'Freydís', 'Freygerður', 'Freyja', 'Freylaug', 'Freyleif', 'Friðbjörg', 'Friðbjört', 'Friðborg', 'Friðdís', 'Friðdóra', 'Friðey', 'Friðfinna', 'Friðgerður', 'Friðjóna', 'Friðlaug', 'Friðleif', 'Friðlín', 'Friðmey', 'Friðný', 'Friðrika', 'Friðrikka', 'Friðrós', 'Friðrún', 'Friðsemd', 'Friðveig', 'Friðþóra', 'Frigg', 'Fríða', 'Fríður', 'Frostrós', 'Fróðný', 'Fura', 'Fönn', 'Gabríela', 'Gabríella', 'Gauja', 'Gauthildur', 'Gefjun', 'Gefn', 'Geira', 'Geirbjörg', 'Geirdís', 'Geirfinna', 'Geirfríður', 'Geirhildur', 'Geirlaug', 'Geirlöð', 'Geirný', 'Geirríður', 'Geirrún', 'Geirþrúður', 'Georgía', 'Gerða', 'Gerður', 'Gestheiður', 'Gestný', 'Gestrún', 'Gillý', 'Gilslaug', 'Gissunn', 'Gía', 'Gígja', 'Gísela', 'Gísla', 'Gísley', 'Gíslína', 'Gíslný', 'Gíslrún', 'Gíslunn', 'Gíta', 'Gjaflaug', 'Gloría', 'Gló', 'Glóa', 'Glóbjört', 'Glódís', 'Glóð', 'Glóey', 'Gná', 'Góa', 'Gógó', 'Grein', 'Gret', 'Greta', 'Grélöð', 'Grét', 'Gréta', 'Gríma', 'Grímey', 'Grímheiður', 'Grímhildur', 'Gróa', 'Guðbjörg', 'Guðbjört', 'Guðborg', 'Guðdís', 'Guðfinna', 'Guðfríður', 'Guðjóna', 'Guðlaug', 'Guðleif', 'Guðlín', 'Guðmey', 'Guðmunda', 'Guðmundína', 'Guðný', 'Guðríður', 'Guðrún', 'Guðsteina', 'Guðveig', 'Gullbrá', 'Gullveig', 'Gullý', 'Gumma', 'Gunnbjörg', 'Gunnbjört', 'Gunnborg', 'Gunndís', 'Gunndóra', 'Gunnella', 'Gunnfinna', 'Gunnfríður', 'Gunnharða', 'Gunnheiður', 'Gunnhildur', 'Gunnjóna', 'Gunnlaug', 'Gunnleif', 'Gunnlöð', 'Gunnrún', 'Gunnur', 'Gunnveig', 'Gunnvör', 'Gunný', 'Gunnþóra', 'Gunnþórunn', 'Gurrý', 'Gúa', 'Gyða', 'Gyðja', 'Gyðríður', 'Gytta', 'Gæfa', 'Gæflaug', 'Hadda', 'Haddý', 'Hafbjörg', 'Hafborg', 'Hafdís', 'Hafey', 'Hafliða', 'Haflína', 'Hafný', 'Hafrós', 'Hafrún', 'Hafsteina', 'Hafþóra', 'Halla', 'Hallbera', 'Hallbjörg', 'Hallborg', 'Halldís', 'Halldóra', 'Halley', 'Hallfríður', 'Hallgerður', 'Hallgunnur', 'Hallkatla', 'Hallný', 'Hallrún', 'Hallveig', 'Hallvör', 'Hanna', 'Hanney', 'Hansa', 'Hansína', 'Harpa', 'Hauður', 'Hákonía', 'Heba', 'Hedda', 'Hedí', 'Heiða', 'Heiðbjörg', 'Heiðbjörk', 'Heiðbjört', 'Heiðbrá', 'Heiðdís', 'Heiðlaug', 'Heiðlóa', 'Heiðný', 'Heiðrós', 'Heiðrún', 'Heiður', 'Heiðveig', 'Hekla', 'Helen', 'Helena', 'Helga', 'Hella', 'Helma', 'Hendrikka', 'Henný', 'Henrietta', 'Henrika', 'Henríetta', 'Hera', 'Herbjörg', 'Herbjört', 'Herborg', 'Herdís', 'Herfríður', 'Hergerður', 'Herlaug', 'Hermína', 'Hersilía', 'Herta', 'Hertha', 'Hervör', 'Herþrúður', 'Hilda', 'Hildegard', 'Hildibjörg', 'Hildigerður', 'Hildigunnur', 'Hildiríður', 'Hildisif', 'Hildur', 'Hilma', 'Himinbjörg', 'Hind', 'Hinrika', 'Hinrikka', 'Hjalta', 'Hjaltey', 'Hjálmdís', 'Hjálmey', 'Hjálmfríður', 'Hjálmgerður', 'Hjálmrós', 'Hjálmrún', 'Hjálmveig', 'Hjördís', 'Hjörfríður', 'Hjörleif', 'Hjörný', 'Hjörtfríður', 'Hlaðgerður', 'Hlédís', 'Hlíf', 'Hlín', 'Hlökk', 'Hólmbjörg', 'Hólmdís', 'Hólmfríður', 'Hrafna', 'Hrafnborg', 'Hrafndís', 'Hrafney', 'Hrafngerður', 'Hrafnheiður', 'Hrafnhildur', 'Hrafnkatla', 'Hrafnlaug', 'Hrafntinna', 'Hraundís', 'Hrefna', 'Hreindís', 'Hróðný', 'Hrólfdís', 'Hrund', 'Hrönn', 'Hugbjörg', 'Hugbjört', 'Hugborg', 'Hugdís', 'Hugljúf', 'Hugrún', 'Huld', 'Hulda', 'Huldís', 'Huldrún', 'Húnbjörg', 'Húndís', 'Húngerður', 'Hvönn', 'Hödd', 'Högna', 'Hörn', 'Ida', 'Idda', 'Iða', 'Iðunn', 'Ilmur', 'Immý', 'Ina', 'Inda', 'India', 'Indiana', 'Indía', 'Indíana', 'Indíra', 'Indra', 'Inga', 'Ingdís', 'Ingeborg', 'Inger', 'Ingey', 'Ingheiður', 'Inghildur', 'Ingibjörg', 'Ingibjört', 'Ingiborg', 'Ingifinna', 'Ingifríður', 'Ingigerður', 'Ingilaug', 'Ingileif', 'Ingilín', 'Ingimaría', 'Ingimunda', 'Ingiríður', 'Ingirós', 'Ingisól', 'Ingiveig', 'Ingrid', 'Ingrún', 'Ingunn', 'Ingveldur', 'Inna', 'Irena', 'Irene', 'Irja', 'Irma', 'Irmý', 'Irpa', 'Isabel', 'Isabella', 'Ída', 'Íma', 'Ína', 'Ír', 'Íren', 'Írena', 'Íris', 'Írunn', 'Ísabel', 'Ísabella', 'Ísadóra', 'Ísafold', 'Ísalind', 'Ísbjörg', 'Ísdís', 'Ísey', 'Ísfold', 'Ísgerður', 'Íshildur', 'Ísis', 'Íslaug', 'Ísleif', 'Ísmey', 'Ísold', 'Ísól', 'Ísrún', 'Íssól', 'Ísveig', 'Íunn', 'Íva', 'Jakobína', 'Jana', 'Jane', 'Janetta', 'Jannika', 'Jara', 'Jarún', 'Jarþrúður', 'Jasmín', 'Járnbrá', 'Járngerður', 'Jenetta', 'Jenna', 'Jenný', 'Jensína', 'Jessý', 'Jovina', 'Jóa', 'Jóanna', 'Jódís', 'Jófríður', 'Jóhanna', 'Jólín', 'Jóna', 'Jónanna', 'Jónasína', 'Jónbjörg', 'Jónbjört', 'Jóndís', 'Jóndóra', 'Jóney', 'Jónfríður', 'Jóngerð', 'Jónheiður', 'Jónhildur', 'Jóninna', 'Jónída', 'Jónína', 'Jónný', 'Jóný', 'Jóra', 'Jóríður', 'Jórlaug', 'Jórunn', 'Jósebína', 'Jósefín', 'Jósefína', 'Judith', 'Júdea', 'Júdit', 'Júlía', 'Júlíana', 'Júlíanna', 'Júlíetta', 'Júlírós', 'Júnía', 'Júníana', 'Jökla', 'Jökulrós', 'Jörgína', 'Kaðlín', 'Kaja', 'Kalla', 'Kamilla', 'Kamí', 'Kamma', 'Kapitola', 'Kapítóla', 'Kara', 'Karen', 'Karin', 'Karitas', 'Karí', 'Karín', 'Karína', 'Karítas', 'Karla', 'Karlinna', 'Karlína', 'Karlotta', 'Karolína', 'Karó', 'Karólín', 'Karólína', 'Kassandra', 'Kata', 'Katarína', 'Katerína', 'Katharina', 'Kathinka', 'Katinka', 'Katla', 'Katrín', 'Katrína', 'Katý', 'Kára', 'Kellý', 'Kendra', 'Ketilbjörg', 'Ketilfríður', 'Ketilríður', 'Kiddý', 'Kira', 'Kirsten', 'Kirstín', 'Kittý', 'Kjalvör', 'Klara', 'Kládía', 'Klementína', 'Kleópatra', 'Kolbjörg', 'Kolbrá', 'Kolbrún', 'Koldís', 'Kolfinna', 'Kolfreyja', 'Kolgríma', 'Kolka', 'Konkordía', 'Konný', 'Korka', 'Kormlöð', 'Kornelía', 'Kókó', 'Krista', 'Kristbjörg', 'Kristborg', 'Kristel', 'Kristensa', 'Kristey', 'Kristfríður', 'Kristgerður', 'Kristin', 'Kristine', 'Kristíana', 'Kristíanna', 'Kristín', 'Kristína', 'Kristjana', 'Kristjóna', 'Kristlaug', 'Kristlind', 'Kristlín', 'Kristný', 'Kristólína', 'Kristrós', 'Kristrún', 'Kristveig', 'Kristvina', 'Kristþóra', 'Kría', 'Kæja', 'Laila', 'Laíla', 'Lana', 'Lara', 'Laufey', 'Laufheiður', 'Laufhildur', 'Lauga', 'Laugey', 'Laugheiður', 'Lára', 'Lárensína', 'Láretta', 'Lárey', 'Lea', 'Leikný', 'Leila', 'Lena', 'Leonóra', 'Leóna', 'Leónóra', 'Lilja', 'Liljá', 'Liljurós', 'Lill', 'Lilla', 'Lillian', 'Lillý', 'Lily', 'Lilý', 'Lind', 'Linda', 'Linddís', 'Lingný', 'Lisbeth', 'Listalín', 'Liv', 'Líba', 'Líf', 'Lífdís', 'Lín', 'Lína', 'Línbjörg', 'Líndís', 'Líneik', 'Líney', 'Línhildur', 'Lísa', 'Lísabet', 'Lísandra', 'Lísbet', 'Lísebet', 'Lív', 'Ljósbjörg', 'Ljósbrá', 'Ljótunn', 'Lofn', 'Loftveig', 'Logey', 'Lokbrá', 'Lotta', 'Louisa', 'Lousie', 'Lovísa', 'Lóa', 'Lóreley', 'Lukka', 'Lúcía', 'Lúðvíka', 'Lúísa', 'Lúna', 'Lúsinda', 'Lúsía', 'Lúvísa', 'Lydia', 'Lydía', 'Lyngheiður', 'Lýdía', 'Læla', 'Maddý', 'Magda', 'Magdalena', 'Magðalena', 'Magga', 'Maggey', 'Maggý', 'Magna', 'Magndís', 'Magnea', 'Magnes', 'Magney', 'Magnfríður', 'Magnheiður', 'Magnhildur', 'Magnúsína', 'Magný', 'Magnþóra', 'Maía', 'Maídís', 'Maísól', 'Maj', 'Maja', 'Malen', 'Malena', 'Malía', 'Malín', 'Malla', 'Manda', 'Manúela', 'Mara', 'Mardís', 'Marela', 'Marella', 'Maren', 'Marey', 'Marfríður', 'Margit', 'Margot', 'Margret', 'Margrét', 'Margrjet', 'Margunnur', 'Marheiður', 'Maria', 'Marie', 'Marikó', 'Marinella', 'Marit', 'Marí', 'María', 'Maríam', 'Marían', 'Maríana', 'Maríanna', 'Marín', 'Marína', 'Marínella', 'Maríon', 'Marísa', 'Marísól', 'Marít', 'Maríuerla', 'Marja', 'Markrún', 'Marlaug', 'Marlena', 'Marlín', 'Marlís', 'Marólína', 'Marsa', 'Marselía', 'Marselína', 'Marsibil', 'Marsilía', 'Marsý', 'Marta', 'Martha', 'Martína', 'Mary', 'Marý', 'Matta', 'Mattea', 'Matthea', 'Matthilda', 'Matthildur', 'Matthía', 'Mattíana', 'Mattína', 'Mattý', 'Maxima', 'Mábil', 'Málfríður', 'Málhildur', 'Málmfríður', 'Mánadís', 'Máney', 'Mára', 'Meda', 'Mekkin', 'Mekkín', 'Melinda', 'Melissa', 'Melkorka', 'Melrós', 'Messíana', 'Metta', 'Mey', 'Mikaela', 'Mikaelína', 'Mikkalína', 'Milda', 'Mildríður', 'Milla', 'Millý', 'Minerva', 'Minna', 'Minney', 'Minný', 'Miriam', 'Mirja', 'Mirjam', 'Mirra', 'Mist', 'Mía', 'Mínerva', 'Míra', 'Míranda', 'Mítra', 'Mjaðveig', 'Mjalldís', 'Mjallhvít', 'Mjöll', 'Mona', 'Monika', 'Módís', 'Móeiður', 'Móey', 'Móheiður', 'Móna', 'Mónika', 'Móníka', 'Munda', 'Mundheiður', 'Mundhildur', 'Mundína', 'Myrra', 'Mýr', 'Mýra', 'Mýrún', 'Mörk', 'Nadia', 'Nadía', 'Nadja', 'Nana', 'Nanna', 'Nanný', 'Nansý', 'Naomí', 'Naómí', 'Natalie', 'Natalía', 'Náttsól', 'Nella', 'Nellý', 'Nenna', 'Nicole', 'Niðbjörg', 'Nikíta', 'Nikoletta', 'Nikólína', 'Ninja', 'Ninna', 'Nína', 'Níní', 'Njála', 'Njóla', 'Norma', 'Nóa', 'Nóra', 'Nótt', 'Nýbjörg', 'Odda', 'Oddbjörg', 'Oddfreyja', 'Oddfríður', 'Oddgerður', 'Oddhildur', 'Oddlaug', 'Oddleif', 'Oddný', 'Oddrún', 'Oddveig', 'Oddvör', 'Oktavía', 'Októvía', 'Olga', 'Ollý', 'Ora', 'Orka', 'Ormheiður', 'Ormhildur', 'Otkatla', 'Otta', 'Óda', 'Ófelía', 'Óla', 'Ólafía', 'Ólafína', 'Ólavía', 'Ólivía', 'Ólína', 'Ólöf', 'Ósa', 'Ósk', 'Ótta', 'Pamela', 'París', 'Patricia', 'Patrisía', 'Pála', 'Páldís', 'Páley', 'Pálfríður', 'Pálhanna', 'Pálheiður', 'Pálhildur', 'Pálín', 'Pálína', 'Pálmey', 'Pálmfríður', 'Pálrún', 'Perla', 'Peta', 'Petra', 'Petrea', 'Petrína', 'Petronella', 'Petrónella', 'Petrós', 'Petrún', 'Petrúnella', 'Pétrína', 'Pétrún', 'Pía', 'Polly', 'Pollý', 'Pría', 'Rafney', 'Rafnhildur', 'Ragna', 'Ragnbjörg', 'Ragney', 'Ragnfríður', 'Ragnheiður', 'Ragnhildur', 'Rakel', 'Ramóna', 'Randalín', 'Randíður', 'Randý', 'Ranka', 'Rannva', 'Rannveig', 'Ráðhildur', 'Rán', 'Rebekka', 'Reginbjörg', 'Regína', 'Rein', 'Renata', 'Reyn', 'Reyndís', 'Reynheiður', 'Reynhildur', 'Rikka', 'Ripley', 'Rita', 'Ríkey', 'Rín', 'Ríta', 'Ronja', 'Rorí', 'Roxanna', 'Róberta', 'Róbjörg', 'Rós', 'Rósa', 'Rósalind', 'Rósanna', 'Rósbjörg', 'Rósborg', 'Róselía', 'Rósey', 'Rósfríður', 'Róshildur', 'Rósinkara', 'Rósinkransa', 'Róska', 'Róslaug', 'Róslind', 'Róslinda', 'Róslín', 'Rósmary', 'Rósmarý', 'Rósmunda', 'Rósný', 'Runný', 'Rut', 'Ruth', 'Rúbý', 'Rún', 'Rúna', 'Rúndís', 'Rúnhildur', 'Rúrí', 'Röfn', 'Rögn', 'Röskva', 'Sabína', 'Sabrína', 'Saga', 'Salbjörg', 'Saldís', 'Salgerður', 'Salín', 'Salína', 'Salka', 'Salma', 'Salný', 'Salome', 'Salóme', 'Salvör', 'Sandra', 'Sanna', 'Santía', 'Sara', 'Sarína', 'Sefanía', 'Selja', 'Selka', 'Selma', 'Senía', 'Septíma', 'Sera', 'Serena', 'Seselía', 'Sesilía', 'Sesselía', 'Sesselja', 'Sessilía', 'Sif', 'Sigdís', 'Sigdóra', 'Sigfríð', 'Sigfríður', 'Sigga', 'Siggerður', 'Sigmunda', 'Signa', 'Signhildur', 'Signý', 'Sigríður', 'Sigrún', 'Sigurást', 'Sigurásta', 'Sigurbára', 'Sigurbirna', 'Sigurbjörg', 'Sigurbjört', 'Sigurborg', 'Sigurdís', 'Sigurdóra', 'Sigurdríf', 'Sigurdrífa', 'Sigurða', 'Sigurey', 'Sigurfinna', 'Sigurfljóð', 'Sigurgeira', 'Sigurhanna', 'Sigurhelga', 'Sigurhildur', 'Sigurjóna', 'Sigurlaug', 'Sigurleif', 'Sigurlilja', 'Sigurlinn', 'Sigurlín', 'Sigurlína', 'Sigurmunda', 'Sigurnanna', 'Sigurósk', 'Sigurrós', 'Sigursteina', 'Sigurunn', 'Sigurveig', 'Sigurvina', 'Sigurþóra', 'Sigyn', 'Sigþóra', 'Sigþrúður', 'Silfa', 'Silfá', 'Silfrún', 'Silja', 'Silka', 'Silla', 'Silva', 'Silvana', 'Silvía', 'Sirra', 'Sirrý', 'Siv', 'Sía', 'Símonía', 'Sísí', 'Síta', 'Sjöfn', 'Skarpheiður', 'Skugga', 'Skuld', 'Skúla', 'Skúlína', 'Snjáfríður', 'Snjáka', 'Snjófríður', 'Snjólaug', 'Snorra', 'Snót', 'Snæbjörg', 'Snæbjört', 'Snæborg', 'Snæbrá', 'Snædís', 'Snæfríður', 'Snælaug', 'Snærós', 'Snærún', 'Soffía', 'Sofie', 'Sofía', 'Solveig', 'Sonja', 'Sonný', 'Sophia', 'Sophie', 'Sól', 'Sóla', 'Sólbjörg', 'Sólbjört', 'Sólborg', 'Sólbrá', 'Sólbrún', 'Sóldís', 'Sóldögg', 'Sóley', 'Sólfríður', 'Sólgerður', 'Sólhildur', 'Sólín', 'Sólkatla', 'Sóllilja', 'Sólný', 'Sólrós', 'Sólrún', 'Sólveig', 'Sólvör', 'Sónata', 'Stefana', 'Stefanía', 'Stefánný', 'Steina', 'Steinbjörg', 'Steinborg', 'Steindís', 'Steindóra', 'Steiney', 'Steinfríður', 'Steingerður', 'Steinhildur', 'Steinlaug', 'Steinrós', 'Steinrún', 'Steinunn', 'Steinvör', 'Steinþóra', 'Stella', 'Stígheiður', 'Stígrún', 'Stína', 'Stjarna', 'Styrgerður', 'Sumarlína', 'Sumarrós', 'Sunna', 'Sunnefa', 'Sunneva', 'Sunniva', 'Sunníva', 'Susan', 'Súla', 'Súsan', 'Súsanna', 'Svafa', 'Svala', 'Svalrún', 'Svana', 'Svanbjörg', 'Svanbjört', 'Svanborg', 'Svandís', 'Svaney', 'Svanfríður', 'Svanheiður', 'Svanhildur', 'Svanhvít', 'Svanlaug', 'Svanrós', 'Svanþrúður', 'Svava', 'Svea', 'Sveina', 'Sveinbjörg', 'Sveinborg', 'Sveindís', 'Sveiney', 'Sveinfríður', 'Sveingerður', 'Sveinhildur', 'Sveinlaug', 'Sveinrós', 'Sveinrún', 'Sveinsína', 'Sveinveig', 'Sylgja', 'Sylva', 'Sylvía', 'Sæbjörg', 'Sæbjört', 'Sæborg', 'Sædís', 'Sæfinna', 'Sæfríður', 'Sæhildur', 'Sælaug', 'Sæmunda', 'Sæný', 'Særós', 'Særún', 'Sæsól', 'Sæunn', 'Sævör', 'Sölva', 'Sölvey', 'Sölvína', 'Tala', 'Talía', 'Tamar', 'Tamara', 'Tanía', 'Tanja', 'Tanya', 'Tanya', 'Tara', 'Tea', 'Teitný', 'Tekla', 'Telma', 'Tera', 'Teresa', 'Teresía', 'Thea', 'Thelma', 'Theodóra', 'Theódóra', 'Theresa', 'Tindra', 'Tinna', 'Tirsa', 'Tía', 'Tíbrá', 'Tína', 'Todda', 'Torbjörg', 'Torfey', 'Torfheiður', 'Torfhildur', 'Tóbý', 'Tóka', 'Tóta', 'Tristana', 'Trú', 'Tryggva', 'Tryggvína', 'Týra', 'Ugla', 'Una', 'Undína', 'Unna', 'Unnbjörg', 'Unndís', 'Unnur', 'Urður', 'Úa', 'Úlfa', 'Úlfdís', 'Úlfey', 'Úlfheiður', 'Úlfhildur', 'Úlfrún', 'Úlla', 'Úna', 'Úndína', 'Úranía', 'Úrsúla', 'Vagna', 'Vagnbjörg', 'Vagnfríður', 'Vaka', 'Vala', 'Valbjörg', 'Valbjörk', 'Valbjört', 'Valborg', 'Valdheiður', 'Valdís', 'Valentína', 'Valería', 'Valey', 'Valfríður', 'Valgerða', 'Valgerður', 'Valhildur', 'Valka', 'Vallý', 'Valný', 'Valrós', 'Valrún', 'Valva', 'Valý', 'Valþrúður', 'Vanda', 'Vár', 'Veig', 'Veiga', 'Venus', 'Vera', 'Veronika', 'Verónika', 'Veróníka', 'Vetrarrós', 'Vébjörg', 'Védís', 'Végerður', 'Vélaug', 'Véný', 'Vibeka', 'Victoría', 'Viðja', 'Vigdís', 'Vigný', 'Viktoria', 'Viktoría', 'Vilborg', 'Vildís', 'Vilfríður', 'Vilgerður', 'Vilhelmína', 'Villa', 'Villimey', 'Vilma', 'Vilný', 'Vinbjörg', 'Vinný', 'Vinsý', 'Virginía', 'Víbekka', 'Víf', 'Vígdögg', 'Víggunnur', 'Víóla', 'Víóletta', 'Vísa', 'Von', 'Von', 'Voney', 'Vordís', 'Ylfa', 'Ylfur', 'Ylja', 'Ylva', 'Ynja', 'Yrja', 'Yrsa', 'Ýja', 'Ýma', 'Ýr', 'Ýrr', 'Þalía', 'Þeba', 'Þeódís', 'Þeódóra', 'Þjóðbjörg', 'Þjóðhildur', 'Þoka', 'Þorbjörg', 'Þorfinna', 'Þorgerður', 'Þorgríma', 'Þorkatla', 'Þorlaug', 'Þorleif', 'Þorsteina', 'Þorstína', 'Þóra', 'Þóranna', 'Þórarna', 'Þórbjörg', 'Þórdís', 'Þórða', 'Þórelfa', 'Þórelfur', 'Þórey', 'Þórfríður', 'Þórgunna', 'Þórgunnur', 'Þórhalla', 'Þórhanna', 'Þórheiður', 'Þórhildur', 'Þórkatla', 'Þórlaug', 'Þórleif', 'Þórný', 'Þórodda', 'Þórsteina', 'Þórsteinunn', 'Þórstína', 'Þórunn', 'Þórveig', 'Þórvör', 'Þrá', 'Þrúða', 'Þrúður', 'Þula', 'Þura', 'Þurí', 'Þuríður', 'Þurý', 'Þúfa', 'Þyri', 'Þyrí', 'Þöll', 'Ægileif', 'Æsa', 'Æsgerður', 'Ögmunda', 'Ögn', 'Ölrún', 'Ölveig', 'Örbrún', 'Örk', 'Ösp'); + + /** + * @var string Icelandic men names. + */ + protected static $firstNameMale = array('Aage', 'Abel', 'Abraham', 'Adam', 'Addi', 'Adel', 'Adíel', 'Adólf', 'Adrían', 'Adríel', 'Aðalberg', 'Aðalbergur', 'Aðalbert', 'Aðalbjörn', 'Aðalborgar', 'Aðalgeir', 'Aðalmundur', 'Aðalráður', 'Aðalsteinn', 'Aðólf', 'Agnar', 'Agni', 'Albert', 'Aldar', 'Alex', 'Alexander', 'Alexíus', 'Alfons', 'Alfred', 'Alfreð', 'Ali', 'Allan', 'Alli', 'Almar', 'Alrekur', 'Alvar', 'Alvin', 'Amír', 'Amos', 'Anders', 'Andreas', 'André', 'Andrés', 'Andri', 'Anes', 'Anfinn', 'Angantýr', 'Angi', 'Annar', 'Annarr', 'Annas', 'Annel', 'Annes', 'Anthony', 'Anton', 'Antoníus', 'Aran', 'Arent', 'Ares', 'Ari', 'Arilíus', 'Arinbjörn', 'Aríel', 'Aríus', 'Arnald', 'Arnaldur', 'Arnar', 'Arnberg', 'Arnbergur', 'Arnbjörn', 'Arndór', 'Arnes', 'Arnfinnur', 'Arnfreyr', 'Arngeir', 'Arngils', 'Arngrímur', 'Arnkell', 'Arnlaugur', 'Arnleifur', 'Arnljótur', 'Arnmóður', 'Arnmundur', 'Arnoddur', 'Arnold', 'Arnór', 'Arnsteinn', 'Arnúlfur', 'Arnviður', 'Arnþór', 'Aron', 'Arthur', 'Arthúr', 'Artúr', 'Asael', 'Askur', 'Aspar', 'Atlas', 'Atli', 'Auðbergur', 'Auðbert', 'Auðbjörn', 'Auðgeir', 'Auðkell', 'Auðmundur', 'Auðólfur', 'Auðun', 'Auðunn', 'Austar', 'Austmann', 'Austmar', 'Austri', 'Axel', 'Ágúst', 'Áki', 'Álfar', 'Álfgeir', 'Álfgrímur', 'Álfur', 'Álfþór', 'Ámundi', 'Árbjartur', 'Árbjörn', 'Árelíus', 'Árgeir', 'Árgils', 'Ármann', 'Árni', 'Ársæll', 'Ás', 'Ásberg', 'Ásbergur', 'Ásbjörn', 'Ásgautur', 'Ásgeir', 'Ásgils', 'Ásgrímur', 'Ási', 'Áskell', 'Áslaugur', 'Áslákur', 'Ásmar', 'Ásmundur', 'Ásólfur', 'Ásröður', 'Ástbjörn', 'Ástgeir', 'Ástmar', 'Ástmundur', 'Ástráður', 'Ástríkur', 'Ástvald', 'Ástvaldur', 'Ástvar', 'Ástvin', 'Ástþór', 'Ásvaldur', 'Ásvarður', 'Ásþór', 'Baldur', 'Baldvin', 'Baldwin', 'Baltasar', 'Bambi', 'Barði', 'Barri', 'Bassi', 'Bastían', 'Baugur', 'Bárður', 'Beinir', 'Beinteinn', 'Beitir', 'Bekan', 'Benedikt', 'Benidikt', 'Benjamín', 'Benoný', 'Benóní', 'Benóný', 'Bent', 'Berent', 'Berg', 'Bergfinnur', 'Berghreinn', 'Bergjón', 'Bergmann', 'Bergmar', 'Bergmundur', 'Bergsteinn', 'Bergsveinn', 'Bergur', 'Bergvin', 'Bergþór', 'Bernhard', 'Bernharð', 'Bernharður', 'Berni', 'Bernódus', 'Bersi', 'Bertel', 'Bertram', 'Bessi', 'Betúel', 'Bill', 'Birgir', 'Birkir', 'Birnir', 'Birtingur', 'Birtir', 'Bjargar', 'Bjargmundur', 'Bjargþór', 'Bjarkan', 'Bjarkar', 'Bjarki', 'Bjarmar', 'Bjarmi', 'Bjarnar', 'Bjarnfinnur', 'Bjarnfreður', 'Bjarnharður', 'Bjarnhéðinn', 'Bjarni', 'Bjarnlaugur', 'Bjarnleifur', 'Bjarnólfur', 'Bjarnsteinn', 'Bjarnþór', 'Bjartmann', 'Bjartmar', 'Bjartur', 'Bjartþór', 'Bjólan', 'Bjólfur', 'Björgmundur', 'Björgólfur', 'Björgúlfur', 'Björgvin', 'Björn', 'Björnólfur', 'Blængur', 'Blær', 'Blævar', 'Boði', 'Bogi', 'Bolli', 'Borgar', 'Borgúlfur', 'Borgþór', 'Bóas', 'Bói', 'Bótólfur', 'Bragi', 'Brandur', 'Breki', 'Bresi', 'Brestir', 'Brimar', 'Brimi', 'Brimir', 'Brími', 'Brjánn', 'Broddi', 'Bruno', 'Bryngeir', 'Brynjar', 'Brynjólfur', 'Brynjúlfur', 'Brynleifur', 'Brynsteinn', 'Bryntýr', 'Brynþór', 'Burkni', 'Búi', 'Búri', 'Bæring', 'Bæringur', 'Bæron', 'Böðvar', 'Börkur', 'Carl', 'Cecil', 'Christian', 'Christopher', 'Cýrus', 'Daði', 'Dagbjartur', 'Dagfari', 'Dagfinnur', 'Daggeir', 'Dagmann', 'Dagnýr', 'Dagur', 'Dagþór', 'Dalbert', 'Dalli', 'Dalmann', 'Dalmar', 'Dalvin', 'Damjan', 'Dan', 'Danelíus', 'Daniel', 'Danival', 'Daníel', 'Daníval', 'Dante', 'Daríus', 'Darri', 'Davíð', 'Demus', 'Deníel', 'Dennis', 'Diðrik', 'Díómedes', 'Dofri', 'Dolli', 'Dominik', 'Dómald', 'Dómaldi', 'Dómaldur', 'Dónald', 'Dónaldur', 'Dór', 'Dóri', 'Dósóþeus', 'Draupnir', 'Dreki', 'Drengur', 'Dufgus', 'Dufþakur', 'Dugfús', 'Dúi', 'Dúnn', 'Dvalinn', 'Dýri', 'Dýrmundur', 'Ebbi', 'Ebeneser', 'Ebenezer', 'Eberg', 'Edgar', 'Edilon', 'Edílon', 'Edvard', 'Edvin', 'Edward', 'Eðvald', 'Eðvar', 'Eðvarð', 'Efraím', 'Eggert', 'Eggþór', 'Egill', 'Eiðar', 'Eiður', 'Eikar', 'Eilífur', 'Einar', 'Einir', 'Einvarður', 'Einþór', 'Eiríkur', 'Eivin', 'Elberg', 'Elbert', 'Eldar', 'Eldgrímur', 'Eldjárn', 'Eldmar', 'Eldon', 'Eldór', 'Eldur', 'Elentínus', 'Elfar', 'Elfráður', 'Elimar', 'Elinór', 'Elis', 'Elí', 'Elías', 'Elíeser', 'Elímar', 'Elínbergur', 'Elínmundur', 'Elínór', 'Elís', 'Ellert', 'Elli', 'Elliði', 'Ellís', 'Elmar', 'Elvar', 'Elvin', 'Elvis', 'Emanúel', 'Embrek', 'Emerald', 'Emil', 'Emmanúel', 'Engilbert', 'Engilbjartur', 'Engiljón', 'Engill', 'Enok', 'Eric', 'Erik', 'Erlar', 'Erlendur', 'Erling', 'Erlingur', 'Ernestó', 'Ernir', 'Ernst', 'Eron', 'Erpur', 'Esekíel', 'Esjar', 'Esra', 'Estefan', 'Evald', 'Evan', 'Evert', 'Eyberg', 'Eyjólfur', 'Eylaugur', 'Eyleifur', 'Eymar', 'Eymundur', 'Eyríkur', 'Eysteinn', 'Eyvar', 'Eyvindur', 'Eyþór', 'Fabrisíus', 'Falgeir', 'Falur', 'Fannar', 'Fannberg', 'Fanngeir', 'Fáfnir', 'Fálki', 'Felix', 'Fengur', 'Fenrir', 'Ferdinand', 'Ferdínand', 'Fertram', 'Feykir', 'Filip', 'Filippus', 'Finn', 'Finnbjörn', 'Finnbogi', 'Finngeir', 'Finnjón', 'Finnlaugur', 'Finnur', 'Finnvarður', 'Fífill', 'Fjalar', 'Fjarki', 'Fjólar', 'Fjólmundur', 'Fjölnir', 'Fjölvar', 'Fjörnir', 'Flemming', 'Flosi', 'Flóki', 'Flórent', 'Flóvent', 'Forni', 'Fossmar', 'Fólki', 'Francis', 'Frank', 'Franklín', 'Frans', 'Franz', 'Fránn', 'Frár', 'Freybjörn', 'Freygarður', 'Freymar', 'Freymóður', 'Freymundur', 'Freyr', 'Freysteinn', 'Freyviður', 'Freyþór', 'Friðberg', 'Friðbergur', 'Friðbert', 'Friðbjörn', 'Friðfinnur', 'Friðgeir', 'Friðjón', 'Friðlaugur', 'Friðleifur', 'Friðmann', 'Friðmar', 'Friðmundur', 'Friðrik', 'Friðsteinn', 'Friður', 'Friðvin', 'Friðþjófur', 'Friðþór', 'Friedrich', 'Fritz', 'Frímann', 'Frosti', 'Fróði', 'Fróðmar', 'Funi', 'Fúsi', 'Fylkir', 'Gabriel', 'Gabríel', 'Gael', 'Galdur', 'Gamalíel', 'Garðar', 'Garibaldi', 'Garpur', 'Garri', 'Gaui', 'Gaukur', 'Gauti', 'Gautrekur', 'Gautur', 'Gautviður', 'Geir', 'Geirarður', 'Geirfinnur', 'Geirharður', 'Geirhjörtur', 'Geirhvatur', 'Geiri', 'Geirlaugur', 'Geirleifur', 'Geirmundur', 'Geirólfur', 'Geirröður', 'Geirtryggur', 'Geirvaldur', 'Geirþjófur', 'Geisli', 'Gellir', 'Georg', 'Gerald', 'Gerðar', 'Geri', 'Gestur', 'Gilbert', 'Gilmar', 'Gils', 'Gissur', 'Gizur', 'Gídeon', 'Gígjar', 'Gísli', 'Gjúki', 'Glói', 'Glúmur', 'Gneisti', 'Gnúpur', 'Gnýr', 'Goði', 'Goðmundur', 'Gottskálk', 'Gottsveinn', 'Gói', 'Grani', 'Grankell', 'Gregor', 'Greipur', 'Greppur', 'Gretar', 'Grettir', 'Grétar', 'Grímar', 'Grímkell', 'Grímlaugur', 'Grímnir', 'Grímólfur', 'Grímur', 'Grímúlfur', 'Guðberg', 'Guðbergur', 'Guðbjarni', 'Guðbjartur', 'Guðbjörn', 'Guðbrandur', 'Guðfinnur', 'Guðfreður', 'Guðgeir', 'Guðjón', 'Guðlaugur', 'Guðleifur', 'Guðleikur', 'Guðmann', 'Guðmar', 'Guðmon', 'Guðmundur', 'Guðni', 'Guðráður', 'Guðröður', 'Guðsteinn', 'Guðvarður', 'Guðveigur', 'Guðvin', 'Guðþór', 'Gumi', 'Gunnar', 'Gunnberg', 'Gunnbjörn', 'Gunndór', 'Gunngeir', 'Gunnhallur', 'Gunnlaugur', 'Gunnleifur', 'Gunnólfur', 'Gunnóli', 'Gunnröður', 'Gunnsteinn', 'Gunnvaldur', 'Gunnþór', 'Gustav', 'Gutti', 'Guttormur', 'Gústaf', 'Gústav', 'Gylfi', 'Gyrðir', 'Gýgjar', 'Gýmir', 'Haddi', 'Haddur', 'Hafberg', 'Hafgrímur', 'Hafliði', 'Hafnar', 'Hafni', 'Hafsteinn', 'Hafþór', 'Hagalín', 'Hagbarður', 'Hagbert', 'Haki', 'Hallberg', 'Hallbjörn', 'Halldór', 'Hallfreður', 'Hallgarður', 'Hallgeir', 'Hallgils', 'Hallgrímur', 'Hallkell', 'Hallmann', 'Hallmar', 'Hallmundur', 'Hallsteinn', 'Hallur', 'Hallvarður', 'Hallþór', 'Hamar', 'Hannes', 'Hannibal', 'Hans', 'Harald', 'Haraldur', 'Harri', 'Harry', 'Harrý', 'Hartmann', 'Hartvig', 'Hauksteinn', 'Haukur', 'Haukvaldur', 'Hákon', 'Háleygur', 'Hálfdan', 'Hálfdán', 'Hámundur', 'Hárekur', 'Hárlaugur', 'Hásteinn', 'Hávar', 'Hávarður', 'Hávarr', 'Hávarr', 'Heiðar', 'Heiðarr', 'Heiðberg', 'Heiðbert', 'Heiðlindur', 'Heiðmann', 'Heiðmar', 'Heiðmundur', 'Heiðrekur', 'Heikir', 'Heilmóður', 'Heimir', 'Heinrekur', 'Heisi', 'Hektor', 'Helgi', 'Helmút', 'Hemmert', 'Hendrik', 'Henning', 'Henrik', 'Henry', 'Henrý', 'Herbert', 'Herbjörn', 'Herfinnur', 'Hergeir', 'Hergill', 'Hergils', 'Herjólfur', 'Herlaugur', 'Herleifur', 'Herluf', 'Hermann', 'Hermóður', 'Hermundur', 'Hersir', 'Hersteinn', 'Hersveinn', 'Hervar', 'Hervarður', 'Hervin', 'Héðinn', 'Hilaríus', 'Hilbert', 'Hildar', 'Hildibergur', 'Hildibrandur', 'Hildigeir', 'Hildiglúmur', 'Hildimar', 'Hildimundur', 'Hildingur', 'Hildir', 'Hildiþór', 'Hilmar', 'Hilmir', 'Himri', 'Hinrik', 'Híram', 'Hjallkár', 'Hjalti', 'Hjarnar', 'Hjálmar', 'Hjálmgeir', 'Hjálmtýr', 'Hjálmur', 'Hjálmþór', 'Hjörleifur', 'Hjörtur', 'Hjörtþór', 'Hjörvar', 'Hleiðar', 'Hlégestur', 'Hlér', 'Hlini', 'Hlíðar', 'Hlíðberg', 'Hlífar', 'Hljómur', 'Hlynur', 'Hlöðmundur', 'Hlöður', 'Hlöðvarður', 'Hlöðver', 'Hnefill', 'Hnikar', 'Hnikarr', 'Holgeir', 'Holger', 'Holti', 'Hólm', 'Hólmar', 'Hólmbert', 'Hólmfastur', 'Hólmgeir', 'Hólmgrímur', 'Hólmkell', 'Hólmsteinn', 'Hólmþór', 'Hóseas', 'Hrafn', 'Hrafnar', 'Hrafnbergur', 'Hrafnkell', 'Hrafntýr', 'Hrannar', 'Hrappur', 'Hraunar', 'Hreggviður', 'Hreiðar', 'Hreiðmar', 'Hreimur', 'Hreinn', 'Hringur', 'Hrímnir', 'Hrollaugur', 'Hrolleifur', 'Hróaldur', 'Hróar', 'Hróbjartur', 'Hróðgeir', 'Hróðmar', 'Hróðólfur', 'Hróðvar', 'Hrói', 'Hrólfur', 'Hrómundur', 'Hrútur', 'Hrærekur', 'Hugberg', 'Hugi', 'Huginn', 'Hugleikur', 'Hugo', 'Hugó', 'Huldar', 'Huxley', 'Húbert', 'Húgó', 'Húmi', 'Húnbogi', 'Húni', 'Húnn', 'Húnröður', 'Hvannar', 'Hyltir', 'Hylur', 'Hængur', 'Hænir', 'Höður', 'Högni', 'Hörður', 'Höskuldur', 'Illugi', 'Immanúel', 'Indriði', 'Ingberg', 'Ingi', 'Ingiberg', 'Ingibergur', 'Ingibert', 'Ingibjartur', 'Ingibjörn', 'Ingileifur', 'Ingimagn', 'Ingimar', 'Ingimundur', 'Ingivaldur', 'Ingiþór', 'Ingjaldur', 'Ingmar', 'Ingólfur', 'Ingvaldur', 'Ingvar', 'Ingvi', 'Ingþór', 'Ismael', 'Issi', 'Ían', 'Ígor', 'Ími', 'Ísak', 'Ísar', 'Ísarr', 'Ísbjörn', 'Íseldur', 'Ísgeir', 'Ísidór', 'Ísleifur', 'Ísmael', 'Ísmar', 'Ísólfur', 'Ísrael', 'Ívan', 'Ívar', 'Jack', 'Jafet', 'Jaki', 'Jakob', 'Jakop', 'Jamil', 'Jan', 'Janus', 'Jarl', 'Jason', 'Járngrímur', 'Játgeir', 'Játmundur', 'Játvarður', 'Jenni', 'Jens', 'Jeremías', 'Jes', 'Jesper', 'Jochum', 'Johan', 'John', 'Joshua', 'Jóakim', 'Jóann', 'Jóel', 'Jóhann', 'Jóhannes', 'Jói', 'Jómar', 'Jómundur', 'Jón', 'Jónar', 'Jónas', 'Jónatan', 'Jónbjörn', 'Jóndór', 'Jóngeir', 'Jónmundur', 'Jónsteinn', 'Jónþór', 'Jósafat', 'Jósavin', 'Jósef', 'Jósep', 'Jósteinn', 'Jósúa', 'Jóvin', 'Julian', 'Júlí', 'Júlían', 'Júlíus', 'Júní', 'Júníus', 'Júrek', 'Jökull', 'Jörfi', 'Jörgen', 'Jörmundur', 'Jörri', 'Jörundur', 'Jörvar', 'Jörvi', 'Kaj', 'Kakali', 'Kaktus', 'Kaldi', 'Kaleb', 'Kali', 'Kalman', 'Kalmann', 'Kalmar', 'Kaprasíus', 'Karel', 'Karim', 'Karkur', 'Karl', 'Karles', 'Karli', 'Karvel', 'Kaspar', 'Kasper', 'Kastíel', 'Katarínus', 'Kató', 'Kár', 'Kári', 'Keran', 'Ketilbjörn', 'Ketill', 'Kilían', 'Kiljan', 'Kjalar', 'Kjallakur', 'Kjaran', 'Kjartan', 'Kjarval', 'Kjárr', 'Kjói', 'Klemens', 'Klemenz', 'Klængur', 'Knútur', 'Knörr', 'Koðrán', 'Koggi', 'Kolbeinn', 'Kolbjörn', 'Kolfinnur', 'Kolgrímur', 'Kolmar', 'Kolskeggur', 'Kolur', 'Kolviður', 'Konráð', 'Konstantínus', 'Kormákur', 'Kornelíus', 'Kort', 'Kópur', 'Kraki', 'Kris', 'Kristall', 'Kristberg', 'Kristbergur', 'Kristbjörn', 'Kristdór', 'Kristens', 'Krister', 'Kristfinnur', 'Kristgeir', 'Kristian', 'Kristinn', 'Kristján', 'Kristjón', 'Kristlaugur', 'Kristleifur', 'Kristmann', 'Kristmar', 'Kristmundur', 'Kristofer', 'Kristófer', 'Kristvaldur', 'Kristvarður', 'Kristvin', 'Kristþór', 'Krummi', 'Kveldúlfur', 'Lambert', 'Lars', 'Laufar', 'Laugi', 'Lauritz', 'Lár', 'Lárent', 'Lárentíus', 'Lárus', 'Leiðólfur', 'Leif', 'Leifur', 'Leiknir', 'Leo', 'Leon', 'Leonard', 'Leonhard', 'Leó', 'Leópold', 'Leví', 'Lér', 'Liljar', 'Lindar', 'Lindberg', 'Línberg', 'Líni', 'Ljósálfur', 'Ljótur', 'Ljúfur', 'Loðmundur', 'Loftur', 'Logi', 'Loki', 'Lórens', 'Lórenz', 'Ludvig', 'Lundi', 'Lúðvíg', 'Lúðvík', 'Lúkas', 'Lúter', 'Lúther', 'Lyngar', 'Lýður', 'Lýtingur', 'Maggi', 'Magngeir', 'Magni', 'Magnús', 'Magnþór', 'Makan', 'Manfred', 'Manfreð', 'Manúel', 'Mar', 'Marbjörn', 'Marel', 'Margeir', 'Margrímur', 'Mari', 'Marijón', 'Marinó', 'Marías', 'Marínó', 'Marís', 'Maríus', 'Marjón', 'Markó', 'Markús', 'Markþór', 'Maron', 'Marri', 'Mars', 'Marsellíus', 'Marteinn', 'Marten', 'Marthen', 'Martin', 'Marvin', 'Mathías', 'Matthías', 'Matti', 'Mattías', 'Max', 'Maximus', 'Máni', 'Már', 'Márus', 'Mekkinó', 'Melkíor', 'Melkólmur', 'Melrakki', 'Mensalder', 'Merkúr', 'Methúsalem', 'Metúsalem', 'Meyvant', 'Michael', 'Mikael', 'Mikjáll', 'Mikkael', 'Mikkel', 'Mildinberg', 'Mías', 'Mímir', 'Míó', 'Mír', 'Mjöllnir', 'Mjölnir', 'Moli', 'Morgan', 'Moritz', 'Mosi', 'Móði', 'Móri', 'Mórits', 'Móses', 'Muggur', 'Muni', 'Muninn', 'Múli', 'Myrkvi', 'Mýrkjartan', 'Mörður', 'Narfi', 'Natan', 'Natanael', 'Nataníel', 'Náttmörður', 'Náttúlfur', 'Neisti', 'Nenni', 'Neptúnus', 'Nicolas', 'Nikanor', 'Nikolai', 'Nikolas', 'Nikulás', 'Nils', 'Níels', 'Níls', 'Njáll', 'Njörður', 'Nonni', 'Norbert', 'Norðmann', 'Normann', 'Nóam', 'Nóel', 'Nói', 'Nóni', 'Nóri', 'Nóvember', 'Númi', 'Nývarð', 'Nökkvi', 'Oddbergur', 'Oddbjörn', 'Oddfreyr', 'Oddgeir', 'Oddi', 'Oddkell', 'Oddleifur', 'Oddmar', 'Oddsteinn', 'Oddur', 'Oddvar', 'Oddþór', 'Oktavíus', 'Októ', 'Októvíus', 'Olaf', 'Olav', 'Olgeir', 'Oliver', 'Olivert', 'Orfeus', 'Ormar', 'Ormur', 'Orri', 'Orvar', 'Otkell', 'Otri', 'Otti', 'Ottó', 'Otur', 'Óðinn', 'Ófeigur', 'Ólafur', 'Óli', 'Óliver', 'Ólíver', 'Ómar', 'Ómi', 'Óskar', 'Ósvald', 'Ósvaldur', 'Ósvífur', 'Óttar', 'Óttarr', 'Parmes', 'Patrek', 'Patrekur', 'Patrick', 'Patrik', 'Páll', 'Pálmar', 'Pálmi', 'Pedró', 'Per', 'Peter', 'Pétur', 'Pjetur', 'Príor', 'Rafael', 'Rafn', 'Rafnar', 'Rafnkell', 'Ragnar', 'Ragúel', 'Randver', 'Rannver', 'Rasmus', 'Ráðgeir', 'Ráðvarður', 'Refur', 'Reginbaldur', 'Reginn', 'Reidar', 'Reifnir', 'Reimar', 'Reinar', 'Reinhart', 'Reinhold', 'Reynald', 'Reynar', 'Reynir', 'Reyr', 'Richard', 'Rikharð', 'Rikharður', 'Ríkarður', 'Ríkharð', 'Ríkharður', 'Ríó', 'Robert', 'Rolf', 'Ronald', 'Róbert', 'Rólant', 'Róman', 'Rómeó', 'Rósant', 'Rósar', 'Rósberg', 'Rósenberg', 'Rósi', 'Rósinberg', 'Rósinkar', 'Rósinkrans', 'Rósmann', 'Rósmundur', 'Rudolf', 'Runi', 'Runólfur', 'Rúbar', 'Rúben', 'Rúdólf', 'Rúnar', 'Rúrik', 'Rútur', 'Röðull', 'Rögnvald', 'Rögnvaldur', 'Rögnvar', 'Rökkvi', 'Safír', 'Sakarías', 'Salmann', 'Salmar', 'Salómon', 'Salvar', 'Samson', 'Samúel', 'Sandel', 'Sandri', 'Sandur', 'Saxi', 'Sebastian', 'Sebastían', 'Seifur', 'Seimur', 'Sesar', 'Sesil', 'Sigbergur', 'Sigbert', 'Sigbjartur', 'Sigbjörn', 'Sigdór', 'Sigfastur', 'Sigfinnur', 'Sigfreður', 'Sigfús', 'Siggeir', 'Sighvatur', 'Sigjón', 'Siglaugur', 'Sigmann', 'Sigmar', 'Sigmundur', 'Signar', 'Sigri', 'Sigríkur', 'Sigsteinn', 'Sigtryggur', 'Sigtýr', 'Sigur', 'Sigurbaldur', 'Sigurberg', 'Sigurbergur', 'Sigurbjarni', 'Sigurbjartur', 'Sigurbjörn', 'Sigurbrandur', 'Sigurdór', 'Sigurður', 'Sigurfinnur', 'Sigurgeir', 'Sigurgestur', 'Sigurgísli', 'Sigurgrímur', 'Sigurhans', 'Sigurhjörtur', 'Sigurjón', 'Sigurkarl', 'Sigurlaugur', 'Sigurlás', 'Sigurleifur', 'Sigurliði', 'Sigurlinni', 'Sigurmann', 'Sigurmar', 'Sigurmon', 'Sigurmundur', 'Sigurnýas', 'Sigurnýjas', 'Siguroddur', 'Siguróli', 'Sigurpáll', 'Sigursteinn', 'Sigursveinn', 'Sigurvaldi', 'Sigurvin', 'Sigurþór', 'Sigvaldi', 'Sigvarður', 'Sigþór', 'Silli', 'Sindri', 'Símon', 'Sírnir', 'Sírus', 'Sívar', 'Sjafnar', 'Skafti', 'Skapti', 'Skarphéðinn', 'Skefill', 'Skeggi', 'Skíði', 'Skírnir', 'Skjöldur', 'Skorri', 'Skuggi', 'Skúli', 'Skúta', 'Skær', 'Skæringur', 'Smári', 'Smiður', 'Smyrill', 'Snjóki', 'Snjólaugur', 'Snjólfur', 'Snorri', 'Snæbjartur', 'Snæbjörn', 'Snæhólm', 'Snælaugur', 'Snær', 'Snæringur', 'Snævar', 'Snævarr', 'Snæþór', 'Soffanías', 'Sophanías', 'Sophus', 'Sófónías', 'Sófus', 'Sókrates', 'Sólberg', 'Sólbergur', 'Sólbjartur', 'Sólbjörn', 'Sólimann', 'Sólmar', 'Sólmundur', 'Sólon', 'Sólver', 'Sólvin', 'Spartakus', 'Sporði', 'Spói', 'Stanley', 'Stapi', 'Starkaður', 'Starri', 'Stefan', 'Stefán', 'Stefnir', 'Steinar', 'Steinarr', 'Steinberg', 'Steinbergur', 'Steinbjörn', 'Steindór', 'Steinfinnur', 'Steingrímur', 'Steini', 'Steinkell', 'Steinmann', 'Steinmar', 'Steinmóður', 'Steinn', 'Steinólfur', 'Steinröður', 'Steinvarður', 'Steinþór', 'Stirnir', 'Stígur', 'Stormur', 'Stórólfur', 'Sturla', 'Sturlaugur', 'Sturri', 'Styr', 'Styrbjörn', 'Styrkár', 'Styrmir', 'Styrr', 'Sumarliði', 'Svafar', 'Svali', 'Svan', 'Svanberg', 'Svanbergur', 'Svanbjörn', 'Svangeir', 'Svanhólm', 'Svani', 'Svanlaugur', 'Svanmundur', 'Svanur', 'Svanþór', 'Svavar', 'Sváfnir', 'Sveinar', 'Sveinberg', 'Sveinbjartur', 'Sveinbjörn', 'Sveinjón', 'Sveinlaugur', 'Sveinmar', 'Sveinn', 'Sveinungi', 'Sveinþór', 'Svend', 'Sverre', 'Sverrir', 'Svölnir', 'Svörfuður', 'Sýrus', 'Sæberg', 'Sæbergur', 'Sæbjörn', 'Sæi', 'Sælaugur', 'Sæmann', 'Sæmundur', 'Sær', 'Sævald', 'Sævaldur', 'Sævar', 'Sævarr', 'Sævin', 'Sæþór', 'Sölmundur', 'Sölvar', 'Sölvi', 'Sören', 'Sörli', 'Tandri', 'Tarfur', 'Teitur', 'Theodór', 'Theódór', 'Thomas', 'Thor', 'Thorberg', 'Thór', 'Tindar', 'Tindri', 'Tindur', 'Tinni', 'Tími', 'Tímon', 'Tímoteus', 'Tímóteus', 'Tístran', 'Tjaldur', 'Tjörfi', 'Tjörvi', 'Tobías', 'Tolli', 'Tonni', 'Torfi', 'Tóbías', 'Tói', 'Tóki', 'Tómas', 'Tór', 'Trausti', 'Tristan', 'Trostan', 'Trúmann', 'Tryggvi', 'Tumas', 'Tumi', 'Tyrfingur', 'Týr', 'Ubbi', 'Uggi', 'Ulrich', 'Uni', 'Unnar', 'Unnbjörn', 'Unndór', 'Unnsteinn', 'Unnþór', 'Urðar', 'Uxi', 'Úddi', 'Úlfar', 'Úlfgeir', 'Úlfhéðinn', 'Úlfkell', 'Úlfljótur', 'Úlftýr', 'Úlfur', 'Úlrik', 'Úranus', 'Vagn', 'Vakur', 'Valberg', 'Valbergur', 'Valbjörn', 'Valbrandur', 'Valdemar', 'Valdi', 'Valdimar', 'Valdór', 'Valentín', 'Valentínus', 'Valgarð', 'Valgarður', 'Valgeir', 'Valíant', 'Vallaður', 'Valmar', 'Valmundur', 'Valsteinn', 'Valter', 'Valtýr', 'Valur', 'Valves', 'Valþór', 'Varmar', 'Vatnar', 'Váli', 'Vápni', 'Veigar', 'Veigur', 'Ver', 'Vermundur', 'Vernharð', 'Vernharður', 'Vestar', 'Vestmar', 'Veturliði', 'Vébjörn', 'Végeir', 'Vékell', 'Vélaugur', 'Vémundur', 'Vésteinn', 'Victor', 'Viðar', 'Vigfús', 'Viggó', 'Vignir', 'Vigri', 'Vigtýr', 'Vigur', 'Vikar', 'Viktor', 'Vilberg', 'Vilbergur', 'Vilbert', 'Vilbjörn', 'Vilbogi', 'Vilbrandur', 'Vilgeir', 'Vilhelm', 'Vilhjálmur', 'Vili', 'Viljar', 'Vilji', 'Villi', 'Vilmar', 'Vilmundur', 'Vincent', 'Vinjar', 'Virgill', 'Víðar', 'Víðir', 'Vífill', 'Víglundur', 'Vígmar', 'Vígmundur', 'Vígsteinn', 'Vígþór', 'Víkingur', 'Vopni', 'Vorm', 'Vöggur', 'Völundur', 'Vörður', 'Vöttur', 'Walter', 'Werner', 'Wilhelm', 'Willard', 'William', 'Willum', 'Ylur', 'Ymir', 'Yngvar', 'Yngvi', 'Yrkill', 'Ýmir', 'Ýrar', 'Zakaría', 'Zakarías', 'Zophanías', 'Zophonías', 'Zóphanías', 'Zóphonías', 'Þangbrandur', 'Þengill', 'Þeyr', 'Þiðrandi', 'Þiðrik', 'Þinur', 'Þjálfi', 'Þjóðann', 'Þjóðbjörn', 'Þjóðgeir', 'Þjóðleifur', 'Þjóðmar', 'Þjóðólfur', 'Þjóðrekur', 'Þjóðvarður', 'Þjóstar', 'Þjóstólfur', 'Þorberg', 'Þorbergur', 'Þorbjörn', 'Þorbrandur', 'Þorfinnur', 'Þorgarður', 'Þorgautur', 'Þorgeir', 'Þorgestur', 'Þorgils', 'Þorgísl', 'Þorgnýr', 'Þorgrímur', 'Þorkell', 'Þorlaugur', 'Þorlákur', 'Þorleifur', 'Þorleikur', 'Þormar', 'Þormóður', 'Þormundur', 'Þorri', 'Þorsteinn', 'Þorvaldur', 'Þorvar', 'Þorvarður', 'Þór', 'Þórar', 'Þórarinn', 'Þórbergur', 'Þórbjörn', 'Þórður', 'Þórgnýr', 'Þórgrímur', 'Þórhaddur', 'Þórhalli', 'Þórhallur', 'Þórir', 'Þórlaugur', 'Þórleifur', 'Þórlindur', 'Þórmar', 'Þórmundur', 'Þóroddur', 'Þórormur', 'Þórólfur', 'Þórsteinn', 'Þórörn', 'Þrastar', 'Þráinn', 'Þrándur', 'Þróttur', 'Þrúðmar', 'Þrymur', 'Þröstur', 'Þyrnir', 'Ægir', 'Æsir', 'Ævar', 'Ævarr', 'Ögmundur', 'Ögri', 'Ölnir', 'Ölver', 'Ölvir', 'Öndólfur', 'Önundur', 'Örlaugur', 'Örlygur', 'Örn', 'Örnólfur', 'Örvar', 'Össur', 'Öxar'); + + /** + * @var string Icelandic middle names. + */ + protected static $middleName = array( + 'Aðaldal', 'Aldan', 'Arnberg', 'Arnfjörð', 'Austan', 'Austdal', 'Austfjörð', 'Áss', 'Bakkdal', 'Bakkmann', 'Bald', 'Ben', 'Bergholt', 'Bergland', 'Bíldsfells', 'Bjarg', 'Bjarndal', 'Bjarnfjörð', 'Bláfeld', 'Blómkvist', 'Borgdal', 'Brekkmann', 'Brim', 'Brúnsteð', 'Dalhoff', 'Dan', 'Diljan', 'Ektavon', 'Eldberg', 'Elísberg', 'Elvan', 'Espólín', 'Eyhlíð', 'Eyvík', 'Falk', 'Finndal', 'Fossberg', 'Freydal', 'Friðhólm', 'Giljan', 'Gilsfjörð', 'Gnarr', 'Gnurr', 'Grendal', 'Grindvík', 'Gull', 'Haffjörð', 'Hafnes', 'Hafnfjörð', 'Har', 'Heimdal', 'Heimsberg', 'Helgfell', 'Herberg', 'Hildiberg', 'Hjaltdal', 'Hlíðkvist', 'Hnappdal', 'Hnífsdal', 'Hofland', 'Hofteig', 'Hornfjörð', 'Hólmberg', 'Hrafnan', 'Hrafndal', 'Hraunberg', 'Hreinberg', 'Hreindal', 'Hrútfjörð', 'Hvammdal', 'Hvítfeld', 'Höfðdal', 'Hörðdal', 'Íshólm', 'Júl', 'Kjarrval', 'Knaran', 'Knarran', 'Krossdal', 'Laufkvist', 'Laufland', 'Laugdal', 'Laxfoss', 'Liljan', 'Linddal', 'Línberg', 'Ljós', 'Loðmfjörð', 'Lyngberg', 'Magdal', 'Magg', 'Matt', 'Miðdal', 'Miðvík', 'Mjófjörð', 'Móberg', 'Mýrmann', 'Nesmann', 'Norðland', 'Núpdal', 'Ólfjörð', 'Ósland', 'Ósmann', 'Reginbald', 'Reykfell', 'Reykfjörð', 'Reynholt', 'Salberg', 'Sandhólm', 'Seljan', 'Sigurhólm', 'Skagalín', 'Skíðdal', 'Snæberg', 'Snædahl', 'Sólan', 'Stardal', 'Stein', 'Steinbekk', 'Steinberg', 'Storm', 'Straumberg', 'Svanhild', 'Svarfdal', 'Sædal', 'Val', 'Valagils', 'Vald', 'Varmdal', 'Vatnsfjörð', 'Vattar', 'Vattnes', 'Viðfjörð', 'Vídalín', 'Víking', 'Vopnfjörð', 'Yngling', 'Þor', 'Önfjörð', 'Örbekk', 'Öxdal', 'Öxndal' + ); + + /** + * Randomly return a icelandic middle name. + * + * @return string + */ + public static function middleName() + { + return static::randomElement(static::$middleName); + } + + /** + * Generate prepared last name for further processing + * + * @return string + */ + public function lastName() + { + $name = static::firstNameMale(); + + if (substr($name, -2) === 'ur') { + $name = substr($name, 0, strlen($name) - 2); + } + + if (substr($name, -1) !== 's') { + $name .= 's'; + } + + return $name; + } + + /** + * Randomly return a icelandic last name for woman. + * + * @return string + */ + public function lastNameMale() + { + return $this->lastName().'dóttir'; + } + + /** + * Randomly return a icelandic last name for man. + * + * @return string + */ + public function lastNameFemale() + { + return $this->lastName().'son'; + } + + /** + * Randomly return a icelandic Kennitala (Social Security number) format. + * + * @link http://en.wikipedia.org/wiki/Kennitala + * + * @return string + */ + public static function ssn() + { + // random birth date + $birthdate = new \DateTime('@' . mt_rand(0, time())); + + // last four buffer + $lastFour = null; + + // security variable reference + $ref = '32765432'; + + // valid flag + $valid = false; + + while (! $valid) { + // make two random numbers + $rand = static::randomDigit().static::randomDigit(); + + // 8 char string with birth date and two random numbers + $tmp = $birthdate->format('dmy').$rand; + + // loop through temp string + for ($i = 7, $sum = 0; $i >= 0; $i--) { + // calculate security variable + $sum += ($tmp[$i] * $ref[$i]); + } + + // subtract 11 if not 11 + $chk = ($sum % 11 === 0) ? 0 : (11 - ($sum % 11)); + + if ($chk < 10) { + $lastFour = $rand.$chk.substr($birthdate->format('Y'), 1, 1); + + $valid = true; + } + } + + return sprintf('%s-%s', $birthdate->format('dmy'), $lastFour); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/PhoneNumber.php new file mode 100644 index 0000000..de91f74 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/is_IS/PhoneNumber.php @@ -0,0 +1,20 @@ + + */ +class PhoneNumber extends \Faker\Provider\PhoneNumber +{ + /** + * @var array Icelandic phone number formats. + */ + protected static $formats = array( + '+354 ### ####', + '+354 #######', + '+354#######', + '### ####', + '#######', + ); +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Address.php new file mode 100644 index 0000000..ebfcac0 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/it_IT/Address.php @@ -0,0 +1,97 @@ +generator->parse($format); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Company.php b/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Company.php new file mode 100644 index 0000000..937f375 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Company.php @@ -0,0 +1,17 @@ +generator->parse($format)); + } + + /** + * @example 'yamada.jp' + */ + public function domainName() + { + return static::randomElement(static::$lastNameAscii) . '.' . $this->tld(); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Person.php new file mode 100644 index 0000000..20fb6cd --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/Person.php @@ -0,0 +1,100 @@ +generator->parse($format); + } + + /** + * @example 'アオタ' + */ + public static function firstKanaName() + { + return static::randomElement(static::$firstKanaName); + } + + /** + * @example 'アキラ' + */ + public static function lastKanaName() + { + return static::randomElement(static::$lastKanaName); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/PhoneNumber.php new file mode 100644 index 0000000..f4230d1 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ja_JP/PhoneNumber.php @@ -0,0 +1,12 @@ +generator->parse($format); + } + + public static function country() + { + return static::randomElement(static::$country); + } + + public static function postcode() + { + return static::toUpper(static::bothify(static::randomElement(static::$postcode))); + } + + public static function regionSuffix() + { + return static::randomElement(static::$regionSuffix); + } + + public static function region() + { + return static::randomElement(static::$region); + } + + public static function citySuffix() + { + return static::randomElement(static::$citySuffix); + } + + public function city() + { + return static::randomElement(static::$city); + } + + public static function streetSuffix() + { + return static::randomElement(static::$streetSuffix); + } + + public static function street() + { + return static::randomElement(static::$street); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Color.php b/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Color.php new file mode 100644 index 0000000..082a9d6 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Color.php @@ -0,0 +1,12 @@ +generator->parse($format); + } + + public static function companyPrefix() + { + return static::randomElement(static::$companyPrefixes); + } + + public static function companyNameElement() + { + return static::randomElement(static::$companyElements); + } + + public static function companyNameSuffix() + { + return static::randomElement(static::$companyNameSuffixes); + } + + /** + * National Business Identification Numbers + * + * @link http://egov.kz/wps/portal/!utWCM/p/b1/04_Sj9Q1MjAwsDQ1s9CP0I_KSyzLTE8syczPS8wB8aPM4oO8PE2cnAwdDSxMw4wMHE08nZ2CA0KDXcwMgQoikRUYWIY4gxS4hwU4mRkbGBgTp98AB3A0IKQ_XD8KVQkWF4AV4LHCzyM_N1U_uKhUPzcqx83SU9cRANth_Rk!/dl4/d5/L0lHSkovd0RNQU5rQUVnQSEhLzRKVUUvZW4!/ + * @param \DateTime $registrationDate + * @return string 12 digits, like 150140000019 + */ + public static function businessIdentificationNumber(\DateTime $registrationDate = null) + { + if (!$registrationDate) { + $registrationDate = \Faker\Provider\DateTime::dateTimeThisYear(); + } + + $dateAsString = $registrationDate->format('ym'); + $legalEntityType = (string) static::numberBetween(4, 6); + $legalEntityAdditionalType = (string) static::numberBetween(0, 3); + $randomDigits = (string) static::numerify('######'); + + return $dateAsString . $legalEntityType . $legalEntityAdditionalType . $randomDigits; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Internet.php new file mode 100644 index 0000000..75999c2 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/Internet.php @@ -0,0 +1,9 @@ +format('ymd'); + $genderAndCenturyId = (string) static::numberBetween(1, 6); + $randomDigits = (string) static::numerify('#####'); + + return $dateAsString . $genderAndCenturyId . $randomDigits; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/PhoneNumber.php new file mode 100644 index 0000000..edb38dd --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/kk_KZ/PhoneNumber.php @@ -0,0 +1,16 @@ +generator->parse($format); + } + + public static function country() + { + return static::randomElement(static::$country); + } + + public static function postcode() + { + return static::toUpper(static::bothify(static::randomElement(static::$postcode))); + } + + public static function regionSuffix() + { + return static::randomElement(static::$regionSuffix); + } + + public static function region() + { + return static::randomElement(static::$region); + } + + public static function cityPrefix() + { + return static::randomElement(static::$cityPrefix); + } + + public function city() + { + return static::randomElement(static::$city); + } + + public static function streetPrefix() + { + return static::randomElement(static::$streetPrefix); + } + + public static function street() + { + return static::randomElement(static::$street); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/Internet.php new file mode 100644 index 0000000..26d5853 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/Internet.php @@ -0,0 +1,9 @@ +bothify("??######"); + } + + public function passportNumber() + { + return $this->bothify("??#######"); + } + + /** + * National Personal Identity number (personas kods) + * @link https://en.wikipedia.org/wiki/National_identification_number#Latvia + * @param \DateTime $birthdate + * @return string on format XXXXXX-XXXXX + */ + public function personalIdentityNumber(\DateTime $birthdate = null) + { + if (!$birthdate) { + $birthdate = \Faker\Provider\DateTime::dateTimeThisCentury(); + } + + $datePart = $birthdate->format('dmy'); + $randomDigits = (string) static::numerify('####'); + + $checksum = Luhn::computeCheckDigit($datePart . $randomDigits); + + return $datePart . '-' . $randomDigits . $checksum; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/PhoneNumber.php new file mode 100644 index 0000000..f6b6148 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/lv_LV/PhoneNumber.php @@ -0,0 +1,13 @@ +format('dmy'); + + /** + * @todo These number should be random based on birth year + * @link http://no.wikipedia.org/wiki/F%C3%B8dselsnummer + */ + $randomDigits = (string)static::numerify('##'); + + switch($gender) { + case static::GENDER_MALE: + $genderDigit = static::randomElement(array(1,3,5,7,9)); + break; + case static::GENDER_FEMALE: + $genderDigit = static::randomElement(array(0,2,4,6,8)); + break; + default: + $genderDigit = (string)static::numerify('#'); + } + + + $digits = $datePart.$randomDigits.$genderDigit; + + /** + * @todo Calculate modulo 11 of $digits + * @link http://no.wikipedia.org/wiki/F%C3%B8dselsnummer + */ + $checksum = (string)static::numerify('##'); + + + return $digits.$checksum; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/no_NO/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/no_NO/PhoneNumber.php new file mode 100644 index 0000000..7c80fcf --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/no_NO/PhoneNumber.php @@ -0,0 +1,22 @@ + 'Aareal Bank Aktiengesellschaft (Spółka Akcyjna) - Oddział w Polsce', + '249' => 'Alior Bank SA', + '247' => 'Banco Espirito Santo de Investimento, S.A. Spółka Akcyjna Oddział w Polsce', + '238' => 'Banco Mais S.A. (SA) Oddział w Polsce', + '106' => 'Bank BPH SA', + '219' => 'Bank DnB NORD Polska SA', + '203' => 'Bank Gospodarki Żywnościowej SA', + '113' => 'Bank Gospodarstwa Krajowego', + '122' => 'Bank Handlowo - Kredytowy SA (w likwidacji 31.03.92)', + '103' => 'Bank Handlowy w Warszawie SA', + '116' => 'Bank Millennium SA', + '154' => 'Bank Ochrony Środowiska SA', + '260' => 'Bank of China (Luxembourg)S.A. Spółka Akcyjna Oddział w Polsce', + '221' => 'Bank of Tokyo-Mitsubishi UFJ (Polska) SA', + '132' => 'Bank Pocztowy SA', + '124' => 'Bank Polska Kasa Opieki SA', + '193' => 'BANK POLSKIEJ SPÓŁDZIELCZOŚCI SA', + '109' => 'Bank Zachodni WBK SA', + '224' => 'Banque PSA Finance SA Oddział w Polsce', + '160' => 'BNP PARIBAS BANK POLSKA SA', + '235' => 'BNP PARIBAS SA Oddział w Polsce', + '243' => 'BNP Paribas Securities Services SKAOddział w Polsce', + '229' => 'BPI Bank Polskich Inwestycji SA', + '215' => 'BRE Bank Hipoteczny SA', + '114' => 'BRE Bank SA', + '239' => 'CAIXABANK, S.A. (SPÓŁKA AKCYJNA)ODDZIAŁ W POLSCE', + '254' => 'Citibank Europe plc (Publiczna Spółka Akcyjna) Oddział w Polsce', + '194' => 'Credit Agricole Bank Polska SA', + '252' => 'CREDIT SUISSE (LUXEMBOURG) S.A. Spółka Akcyjna, Oddział w Polsce', + '236' => 'Danske Bank A/S SA Oddział w Polsce', + '191' => 'Deutsche Bank PBC SA', + '188' => 'Deutsche Bank Polska SA', + '174' => 'DZ BANK Polska SA', + '241' => 'Elavon Financial Services Limited (Spółka z ograniczoną odpowiedzialnością) Oddział w Polsce', + '147' => 'Euro Bank SA', + '265' => 'EUROCLEAR Bank SA/NV (Spółka Akcyjna) - Oddział w Polsce', + '207' => 'FCE Bank Polska SA', + '214' => 'Fiat Bank Polska SA', + '253' => 'FM Bank SA', + '248' => 'Getin Noble Bank SA', + '128' => 'HSBC Bank Polska SA', + '195' => 'Idea Bank SA', + '255' => 'Ikano Bank GmbH (Sp. z o.o.) Oddział w Polsce', + '262' => 'Industrial and Commercial Bank of China (Europe) S.A. (Spółka Akcyjna) Oddział w Polsce', + '105' => 'ING Bank Śląski SA', + '266' => 'Intesa Sanpaolo S.p.A. Spółka Akcyjna Oddział w Polsce', + '168' => 'INVEST - BANK SA', + '258' => 'J.P. Morgan Europe Limited Sp. z o.o. Oddział w Polsce', + '158' => 'Mercedes-Benz Bank Polska SA', + '130' => 'Meritum Bank ICB SA', + '101' => 'Narodowy Bank Polski', + '256' => 'Nordea Bank AB SA Oddział w Polsce', + '144' => 'NORDEA BANK POLSKA SA', + '232' => 'Nykredit Realkredit A/S SA - Oddział w Polsce', + '189' => 'Pekao Bank Hipoteczny SA', + '187' => 'Polski Bank Przedsiębiorczości SA', + '102' => 'Powszechna Kasa Oszczędności Bank Polski SA', + '200' => 'Rabobank Polska SA', + '175' => 'Raiffeisen Bank Polska SA', + '167' => 'RBS Bank (Polska) SA', + '264' => 'RCI Banque Spółka Akcyjna Oddział w Polsce', + '212' => 'Santander Consumer Bank SA', + '263' => 'Saxo Bank A/S Spółka Akcyjna Oddział w Polsce', + '161' => 'SGB-Bank SA', + '237' => 'Skandinaviska Enskilda Banken AB (SA) - Oddział w Polsce', + '184' => 'Societe Generale SA Oddział w Polsce', + '225' => 'Svenska Handelsbanken AB SA Oddział w Polsce', + '227' => 'Sygma Banque Societe Anonyme (SA) Oddział w Polsce', + '216' => 'Toyota Bank Polska SA', + '257' => 'UBS Limited (spółka z ograniczoną odpowiedzialnością) Oddział w Polsce', + '261' => 'Vanquis Bank Limited (spółka z ograniczoną odpowiedzialnością) Oddział w Polsce', + '213' => 'VOLKSWAGEN BANK POLSKA SA', + ); + + /** + * @example 'Euro Bank SA' + */ + public static function bank() + { + return static::randomElement(static::$banks); + } + + /** + * International Bank Account Number (IBAN) + * @link http://en.wikipedia.org/wiki/International_Bank_Account_Number + * @param string $prefix for generating bank account number of a specific bank + * @param string $countryCode ISO 3166-1 alpha-2 country code + * @param integer $length total length without country code and 2 check digits + * @return string + */ + public static function bankAccountNumber($prefix = '', $countryCode = 'PL', $length = null) + { + return static::iban($countryCode, $prefix, $length); + } + + protected static function addBankCodeChecksum($iban, $countryCode = 'PL') + { + if ($countryCode != "PL" || strlen($iban) <= 8) { + return $iban; + } + $checksum = 0; + $weights = array(7, 1, 3, 9, 7, 1, 3); + for ($i = 0; $i < 7; $i++) { + $checksum += $weights[$i] * (int) $iban[$i]; + } + $checksum = $checksum % 10; + + return substr($iban, 0, 7) . $checksum . substr($iban, 8); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Person.php new file mode 100644 index 0000000..c6b2402 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/Person.php @@ -0,0 +1,226 @@ +generator->parse(static::randomElement(static::$lastNameFormat)); + } + + public static function lastNameMale() + { + return static::randomElement(static::$lastNameMale); + } + + public static function lastNameFemale() + { + return static::randomElement(static::$lastNameFemale); + } + + public function title($gender = null) + { + return static::randomElement(static::$title); + } + + /** + * replaced by specific unisex Polish title + */ + public static function titleMale() + { + return static::title(); + } + + /** + * replaced by specific unisex Polish title + */ + public static function titleFemale() + { + return static::title(); + } + + /** + * PESEL - Universal Electronic System for Registration of the Population + * @link http://en.wikipedia.org/wiki/PESEL + * @param DateTime $birthdate + * @param string $sex M for male or F for female + * @return string 11 digit number, like 44051401358 + */ + public static function pesel($birthdate = null, $sex = null) + { + if ($birthdate === null) { + $birthdate = \Faker\Provider\DateTime::dateTimeThisCentury(); + } + + $weights = array(1, 3, 7, 9, 1, 3, 7, 9, 1, 3); + $length = count($weights); + + $fullYear = (int) $birthdate->format('Y'); + $year = (int) $birthdate->format('y'); + $month = $birthdate->format('m') + (((int) ($fullYear/100) - 14) % 5) * 20; + $day = $birthdate->format('d'); + + $result = array((int) ($year / 10), $year % 10, (int) ($month / 10), $month % 10, (int) ($day / 10), $day % 10); + + for ($i = 6; $i < $length; $i++) { + $result[$i] = static::randomDigit(); + } + if ($sex == "M") { + $result[$length - 1] |= 1; + } elseif ($sex == "F") { + $result[$length - 1] ^= 1; + } + $checksum = 0; + for ($i = 0; $i < $length; $i++) { + $checksum += $weights[$i] * $result[$i]; + } + $checksum = (10 - ($checksum % 10)) % 10; + $result[] = $checksum; + + return implode('', $result); + } + + /** + * National Identity Card number + * @link http://en.wikipedia.org/wiki/Polish_National_Identity_Card + * @return string 3 letters and 6 digits, like ABA300000 + */ + public static function personalIdentityNumber() + { + $range = str_split("ABCDEFGHIJKLMNPRSTUVWXYZ"); + $low = array("A", static::randomElement($range), static::randomElement($range)); + $high = array(static::randomDigit(), static::randomDigit(), static::randomDigit(), static::randomDigit(), static::randomDigit()); + $weights = array(7, 3, 1, 7, 3, 1, 7, 3); + $checksum = 0; + for ($i = 0, $size = count($low); $i < $size; $i++) { + $checksum += $weights[$i] * (ord($low[$i]) - 55); + } + for ($i = 0, $size = count($high); $i < $size; $i++) { + $checksum += $weights[$i+3] * $high[$i]; + } + $checksum %= 10; + + return implode('', $low).$checksum.implode('', $high); + } + + /** + * Taxpayer Identification Number (NIP in Polish) + * @link http://en.wikipedia.org/wiki/PESEL#Other_identifiers + * @link http://pl.wikipedia.org/wiki/NIP + * @return string 10 digit number + */ + public static function taxpayerIdentificationNumber() + { + $weights = array(6, 5, 7, 2, 3, 4, 5, 6, 7); + $result = array(); + do { + $result = array( + static::randomDigitNotNull(), static::randomDigitNotNull(), static::randomDigitNotNull(), + static::randomDigit(), static::randomDigit(), static::randomDigit(), + static::randomDigit(), static::randomDigit(), static::randomDigit(), + ); + $checksum = 0; + for ($i = 0, $size = count($result); $i < $size; $i++) { + $checksum += $weights[$i] * $result[$i]; + } + $checksum %= 11; + } while ($checksum == 10); + $result[] = $checksum; + + return implode('', $result); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/PhoneNumber.php new file mode 100644 index 0000000..65bc5c0 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/pl_PL/PhoneNumber.php @@ -0,0 +1,18 @@ + + + Prof. Hart will answer or forward your message. + + We would prefer to send you information by email. + + + **The Legal Small Print** + + + (Three Pages) + + ***START**THE SMALL PRINT!**FOR PUBLIC DOMAIN EBOOKS**START*** + Why is this "Small Print!" statement here? You know: lawyers. + They tell us you might sue us if there is something wrong with + your copy of this eBook, even if you got it for free from + someone other than us, and even if what's wrong is not our + fault. So, among other things, this "Small Print!" statement + disclaims most of our liability to you. It also tells you how + you may distribute copies of this eBook if you want to. + + *BEFORE!* YOU USE OR READ THIS EBOOK + By using or reading any part of this PROJECT GUTENBERG-tm + eBook, you indicate that you understand, agree to and accept + this "Small Print!" statement. If you do not, you can receive + a refund of the money (if any) you paid for this eBook by + sending a request within 30 days of receiving it to the person + you got it from. If you received this eBook on a physical + medium (such as a disk), you must return it with your request. + + ABOUT PROJECT GUTENBERG-TM EBOOKS + This PROJECT GUTENBERG-tm eBook, like most PROJECT GUTENBERG-tm eBooks, + is a "public domain" work distributed by Professor Michael S. Hart + through the Project Gutenberg Association (the "Project"). + Among other things, this means that no one owns a United States copyright + on or for this work, so the Project (and you!) can copy and + distribute it in the United States without permission and + without paying copyright royalties. Special rules, set forth + below, apply if you wish to copy and distribute this eBook + under the "PROJECT GUTENBERG" trademark. + + Please do not use the "PROJECT GUTENBERG" trademark to market + any commercial products without permission. + + To create these eBooks, the Project expends considerable + efforts to identify, transcribe and proofread public domain + works. Despite these efforts, the Project's eBooks and any + medium they may be on may contain "Defects". Among other + things, Defects may take the form of incomplete, inaccurate or + corrupt data, transcription errors, a copyright or other + intellectual property infringement, a defective or damaged + disk or other eBook medium, a computer virus, or computer + codes that damage or cannot be read by your equipment. + + LIMITED WARRANTY; DISCLAIMER OF DAMAGES + But for the "Right of Replacement or Refund" described below, + [1] Michael Hart and the Foundation (and any other party you may + receive this eBook from as a PROJECT GUTENBERG-tm eBook) disclaims + all liability to you for damages, costs and expenses, including + legal fees, and [2] YOU HAVE NO REMEDIES FOR NEGLIGENCE OR + UNDER STRICT LIABILITY, OR FOR BREACH OF WARRANTY OR CONTRACT, + INCLUDING BUT NOT LIMITED TO INDIRECT, CONSEQUENTIAL, PUNITIVE + OR INCIDENTAL DAMAGES, EVEN IF YOU GIVE NOTICE OF THE + POSSIBILITY OF SUCH DAMAGES. + + If you discover a Defect in this eBook within 90 days of + receiving it, you can receive a refund of the money (if any) + you paid for it by sending an explanatory note within that + time to the person you received it from. If you received it + on a physical medium, you must return it with your note, and + such person may choose to alternatively give you a replacement + copy. If you received it electronically, such person may + choose to alternatively give you a second opportunity to + receive it electronically. + + THIS EBOOK IS OTHERWISE PROVIDED TO YOU "AS-IS". NO OTHER + WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, ARE MADE TO YOU AS + TO THE EBOOK OR ANY MEDIUM IT MAY BE ON, INCLUDING BUT NOT + LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A + PARTICULAR PURPOSE. + + Some states do not allow disclaimers of implied warranties or + the exclusion or limitation of consequential damages, so the + above disclaimers and exclusions may not apply to you, and you + may have other legal rights. + + INDEMNITY + You will indemnify and hold Michael Hart, the Foundation, + and its trustees and agents, and any volunteers associated + with the production and distribution of Project Gutenberg-tm + texts harmless, from all liability, cost and expense, including + legal fees, that arise directly or indirectly from any of the + following that you do or cause: [1] distribution of this eBook, + [2] alteration, modification, or addition to the eBook, + or [3] any Defect. + + DISTRIBUTION UNDER "PROJECT GUTENBERG-tm" + You may distribute copies of this eBook electronically, or by + disk, book or any other medium if you either delete this + "Small Print!" and all other references to Project Gutenberg, + or: + + [1] Only give exact copies of it. Among other things, this + requires that you do not remove, alter or modify the + eBook or this "small print!" statement. You may however, + if you wish, distribute this eBook in machine readable + binary, compressed, mark-up, or proprietary form, + including any form resulting from conversion by word + processing or hypertext software, but only so long as + *EITHER*: + + [*] The eBook, when displayed, is clearly readable, and + does *not* contain characters other than those + intended by the author of the work, although tilde + (~), asterisk (*) and underline (_) characters may + be used to convey punctuation intended by the + author, and additional characters may be used to + indicate hypertext links; OR + + [*] The eBook may be readily converted by the reader at + no expense into plain ASCII, EBCDIC or equivalent + form by the program that displays the eBook (as is + the case, for instance, with most word processors); + OR + + [*] You provide, or agree to also provide on request at + no additional cost, fee or expense, a copy of the + eBook in its original plain ASCII form (or in EBCDIC + or other equivalent proprietary form). + + [2] Honor the eBook refund and replacement provisions of this + "Small Print!" statement. + + [3] Pay a trademark license fee to the Foundation of 20% of the + gross profits you derive calculated using the method you + already use to calculate your applicable taxes. If you + don't derive profits, no royalty is due. Royalties are + payable to "Project Gutenberg Literary Archive Foundation" + the 60 days following each date you prepare (or were + legally required to prepare) your annual (or equivalent + periodic) tax return. Please contact us beforehand to + let us know your plans and to work out the details. + + WHAT IF YOU *WANT* TO SEND MONEY EVEN IF YOU DON'T HAVE TO? + Project Gutenberg is dedicated to increasing the number of + public domain and licensed works that can be freely distributed + in machine readable form. + + The Project gratefully accepts contributions of money, time, + public domain materials, or royalty free copyright licenses. + Money should be paid to the: + "Project Gutenberg Literary Archive Foundation." + + If you are interested in contributing scanning equipment or + software or other items, please contact Michael Hart at: + hart@pobox.com + + [Portions of this eBook's header and trailer may be reprinted only + when distributed free of all fees. Copyright (C) 2001, 2002 by + Michael S. Hart. Project Gutenberg is a TradeMark and may not be + used in any sales of Project Gutenberg eBooks or other materials be + they hardware or software or any other related product without + express permission.] + + *END THE SMALL PRINT! FOR PUBLIC DOMAIN EBOOKS*Ver.02/11/02*END* + + */ +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Address.php new file mode 100644 index 0000000..2f3593f --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Address.php @@ -0,0 +1,132 @@ +generator->numerify('########0001'); + $n .= check_digit($n); + $n .= check_digit($n); + + return $formatted? vsprintf('%d%d.%d%d%d.%d%d%d/%d%d%d%d-%d%d', str_split($n)) : $n; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Internet.php new file mode 100644 index 0000000..7481a6f --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/Internet.php @@ -0,0 +1,9 @@ +generator->numerify('#########'); + $n .= check_digit($n); + $n .= check_digit($n); + + return $formatted? vsprintf('%d%d%d.%d%d%d.%d%d%d-%d%d', str_split($n)) : $n; + } + + /** + * A random RG number, following Sao Paulo state's rules. + * @link http://pt.wikipedia.org/wiki/C%C3%A9dula_de_identidade + * @param bool $formatted If the number should have dots/dashes or not. + * @return string + */ + public function rg($formatted = true) + { + $n = $this->generator->numerify('########'); + $n .= check_digit($n); + + return $formatted? vsprintf('%d%d.%d%d%d.%d%d%d-%s', str_split($n)) : $n; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/PhoneNumber.php new file mode 100644 index 0000000..c66b009 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/PhoneNumber.php @@ -0,0 +1,142 @@ + '')); + } + + return $number; + } + + /** + * Generates an 8-digit landline number without formatting characters. + * @param bool $formatted [def: true] If it should return a formatted number or not. + * @return string + */ + public static function landline($formatted = true) + { + $number = static::numerify(static::randomElement(static::$landlineFormats)); + + if (!$formatted) { + $number = strtr($number, array('-' => '')); + } + + return $number; + } + + /** + * Randomizes between cellphone and landline numbers. + * @param bool $formatted [def: true] If it should return a formatted number or not. + * @return mixed + */ + public static function phone($formatted = true) + { + $options = static::randomElement(array( + array('cellphone', false), + array('cellphone', true), + array('landline', null), + )); + + return call_user_func("static::{$options[0]}", $formatted, $options[1]); + } + + /** + * Generates a complete phone number. + * @param string $type [def: landline] One of "landline" or "cellphone". Defaults to "landline" on invalid values. + * @param bool $formatted [def: true] If the number should be formatted or not. + * @return string + */ + protected static function anyPhoneNumber($type, $formatted = true) + { + $area = static::areaCode(); + $number = ($type == 'cellphone')? + static::cellphone($formatted, in_array($area, static::$ninthDigitAreaCodes)) : + static::landline($formatted); + + return $formatted? "($area) $number" : $area.$number; + } + + /** + * Concatenates {@link areaCode} and {@link cellphone} into a national cellphone number. The ninth digit is + * derived from the area code. + * @param bool $formatted [def: true] If it should return a formatted number or not. + * @return string + */ + public static function cellphoneNumber($formatted = true) + { + return static::anyPhoneNumber('cellphone', $formatted); + } + + /** + * Concatenates {@link areaCode} and {@link landline} into a national landline number. + * @param bool $formatted [def: true] If it should return a formatted number or not. + * @return string + */ + public static function landlineNumber($formatted = true) + { + return static::anyPhoneNumber('landline', $formatted); + } + + /** + * Randomizes between complete cellphone and landline numbers. + * @return mixed + */ + public static function phoneNumber() + { + $method = static::randomElement(array('cellphoneNumber', 'landlineNumber')); + return call_user_func("static::$method", true); + } + + /** + * Randomizes between complete cellphone and landline numbers, cleared from formatting symbols. + * @return mixed + */ + public static function phoneNumberCleared() + { + $method = static::randomElement(array('cellphoneNumber', 'landlineNumber')); + return call_user_func("static::$method", false); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/check_digit.php b/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/check_digit.php new file mode 100644 index 0000000..ab67db9 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/pt_BR/check_digit.php @@ -0,0 +1,35 @@ += 12; + $verifier = 0; + + for ($i = 1; $i <= $length; $i++) { + if (!$second_algorithm) { + $multiplier = $i+1; + } else { + $multiplier = ($i >= 9)? $i-7 : $i+1; + } + $verifier += $numbers[$length-$i] * $multiplier; + } + + $verifier = 11 - ($verifier % 11); + if ($verifier >= 10) { + $verifier = 0; + } + + return $verifier; +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/Address.php new file mode 100644 index 0000000..4de0e93 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/Address.php @@ -0,0 +1,124 @@ + 0; $i--) { + $numbers[$i] = substr($number, $i - 1, 1); + $partial[$i] = $numbers[$i] * $factor; + $sum += $partial[$i]; + if ($factor == $base) { + $factor = 1; + } + $factor++; + } + $res = $sum % 11; + + if ($res == 0 || $res == 1) { + $digit = 0; + } else { + $digit = 11 - $res; + } + + return $digit; + } + + /** + * + * @link http://nomesportugueses.blogspot.pt/2012/01/lista-dos-cem-nomes-mais-usados-em.html + */ + + protected static $firstNameMale = array( + 'Rodrigo', 'João', 'Martim', 'Afonso', 'Tomás', 'Gonçalo', 'Francisco', 'Tiago', + 'Diogo', 'Guilherme', 'Pedro', 'Miguel', 'Rafael', 'Gabriel', 'Santiago', 'Dinis', + 'David', 'Duarte', 'José', 'Simão', 'Daniel', 'Lucas', 'Gustavo', 'André', 'Denis', + 'Salvador', 'António', 'Vasco', 'Henrique', 'Lourenço', 'Manuel', 'Eduardo', 'Bernardo', + 'Leandro', 'Luís', 'Diego', 'Leonardo', 'Alexandre', 'Rúben', 'Mateus', 'Ricardo', + 'Vicente', 'Filipe', 'Bruno', 'Nuno', 'Carlos', 'Rui', 'Hugo', 'Samuel', 'Álvaro', + 'Matias', 'Fábio', 'Ivo', 'Paulo', 'Jorge', 'Xavier', 'Marco', 'Isaac', 'Raúl','Benjamim', + 'Renato', 'Artur', 'Mário', 'Frederico', 'Cristiano', 'Ivan', 'Sérgio', 'Micael', + 'Vítor', 'Edgar', 'Kevin', 'Joaquim', 'Igor', 'Ângelo', 'Enzo', 'Valentim', 'Flávio', + 'Joel', 'Fernando', 'Sebastião', 'Tomé', 'César', 'Cláudio', 'Nelson', 'Lisandro', 'Jaime', + 'Gil', 'Mauro', 'Sandro', 'Hélder', 'Matheus', 'William', 'Gaspar', 'Márcio', + 'Martinho', 'Emanuel', 'Marcos', 'Telmo', 'Davi', 'Wilson' + ); + + protected static $firstNameFemale = array( + 'Maria', 'Leonor', 'Matilde', 'Mariana', 'Ana', 'Beatriz', 'Inês', 'Lara', 'Carolina', 'Margarida', + 'Joana', 'Sofia', 'Diana', 'Francisca', 'Laura', 'Sara', 'Madalena', 'Rita', 'Mafalda', 'Catarina', + 'Luana', 'Marta', 'Íris', 'Alice', 'Bianca', 'Constança', 'Gabriela', 'Eva', 'Clara', 'Bruna', 'Daniela', + 'Iara', 'Filipa', 'Vitória', 'Ariana', 'Letícia', 'Bárbara', 'Camila', 'Rafaela', 'Carlota', 'Yara', + 'Núria', 'Raquel', 'Ema', 'Helena', 'Benedita', 'Érica', 'Isabel', 'Nicole', 'Lia', 'Alícia', 'Mara', + 'Jéssica', 'Soraia', 'Júlia', 'Luna', 'Victória', 'Luísa', 'Teresa', 'Miriam', 'Adriana', 'Melissa', + 'Andreia', 'Juliana', 'Alexandra', 'Yasmin', 'Tatiana', 'Leticia', 'Luciana', 'Eduarda', 'Cláudia', + 'Débora', 'Fabiana', 'Renata', 'Kyara', 'Kelly', 'Irina', 'Mélanie', 'Nádia', 'Cristiana', 'Liliana', + 'Patrícia', 'Vera', 'Doriana', 'Ângela', 'Mia', 'Erica', 'Mónica', 'Isabela', 'Salomé', 'Cátia', + 'Verónica', 'Violeta', 'Lorena', 'Érika', 'Vanessa', 'Iris', 'Anna', 'Viviane', 'Rebeca', 'Neuza', + ); + + protected static $lastName = array( + 'Abreu', 'Almeida', 'Alves', 'Amaral', 'Amorim', 'Andrade', 'Anjos', 'Antunes', 'Araújo', 'Assunção', + 'Azevedo', 'Baptista', 'Barbosa', 'Barros', 'Batista', 'Borges', 'Branco', 'Brito', 'Campos', 'Cardoso', + 'Carneiro', 'Carvalho', 'Castro', 'Coelho', 'Correia', 'Costa', 'Cruz', 'Cunha', 'Domingues', 'Esteves', + 'Faria', 'Fernandes', 'Ferreira', 'Figueiredo', 'Fonseca', 'Freitas', 'Garcia', 'Gaspar', 'Gomes', + 'Gonçalves', 'Guerreiro', 'Henriques', 'Jesus', 'Leal', 'Leite', 'Lima', 'Lopes', 'Loureiro', 'Lourenço', + 'Macedo', 'Machado', 'Magalhães', 'Maia', 'Marques', 'Martins', 'Matias', 'Matos', 'Melo', 'Mendes', + 'Miranda', 'Monteiro', 'Morais', 'Moreira', 'Mota', 'Moura', 'Nascimento', 'Neto', 'Neves', 'Nogueira', + 'Nunes', 'Oliveira', 'Pacheco', 'Paiva', 'Pereira', 'Pinheiro', 'Pinho', 'Pinto', 'Pires', 'Ramos', + 'Reis', 'Ribeiro', 'Rocha', 'Rodrigues', 'Santos', 'Silva', 'Simões', 'Soares', 'Sousa', + 'Sá', 'Tavares', 'Teixeira', 'Torres', 'Valente', 'Vaz', 'Vicente', 'Vieira', + ); +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/PhoneNumber.php new file mode 100644 index 0000000..618a01c --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/pt_PT/PhoneNumber.php @@ -0,0 +1,50 @@ +generator->parse($format); + } + + public function address() + { + $format = static::randomElement(static::$addressFormats); + + return $this->generator->parse($format); + } + + public function streetAddress() + { + $format = static::randomElement(static::$streetAddressFormats); + + return $this->generator->parse($format); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ro_MD/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/ro_MD/Person.php new file mode 100644 index 0000000..4b77fdf --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ro_MD/Person.php @@ -0,0 +1,90 @@ +generator->parse($format); + } + + /** + * @example 'Cluj' + */ + public function county() + { + return static::randomElement(static::$counties); + } + + public function address() + { + $format = static::randomElement(static::$addressFormats); + + return $this->generator->parse($format); + } + + public function streetAddress() + { + $format = static::randomElement(static::$streetAddressFormats); + + return $this->generator->parse($format); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/Person.php new file mode 100644 index 0000000..76b1658 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/Person.php @@ -0,0 +1,202 @@ + '01', 'AR' => '02', 'AG' => '03', 'B' => '40', 'BC' => '04', 'BH' => '05', + 'BN' => '06', 'BT' => '07', 'BV' => '08', 'BR' => '09', 'BZ' => '10', 'CS' => '11', + 'CL' => '51', 'CJ' => '12', 'CT' => '13', 'CV' => '14', 'DB' => '15', 'DJ' => '16', + 'GL' => '17', 'GR' => '52', 'GJ' => '18', 'HR' => '19', 'HD' => '20', 'IL' => '21', + 'IS' => '22', 'IF' => '23', 'MM' => '24', 'MH' => '25', 'MS' => '26', 'NT' => '27', + 'OT' => '28', 'PH' => '29', 'SM' => '30', 'SJ' => '31', 'SB' => '32', 'SV' => '33', + 'TR' => '34', 'TM' => '35', 'TL' => '36', 'VS' => '37', 'VL' => '38', 'VN' => '39', + + 'B1' => '41', 'B2' => '42', 'B3' => '43', 'B4' => '44', 'B5' => '45', 'B6' => '46' + ); + + /** + * Personal Numerical Code (CNP) + * + * @link http://ro.wikipedia.org/wiki/Cod_numeric_personal + * @example 1111111111118 + * + * @param string $gender Valid values: m, f, 1, 2 + * @param integer $century Valid values: 1800, 1900, 2000, 1, 2, 3, 4, 5, 6 + * @param string $county Valid values: 2 letter ISO 3166-2:RO county codes and B1-B6 for Bucharest's 6 sectors + * @return string + * + */ + public function cnp($gender = null, $century = null, $county = null) + { + if (is_null($county) || !array_key_exists($county, static::$cnpCountyCodes)) { + $countyCode = static::randomElement(array_values(static::$cnpCountyCodes)); + } else { + $countyCode = static::$cnpCountyCodes[$county]; + } + + $cnp = (string) static::cnpFirstDigit($gender, $century) + . static::numerify('##') + . sprintf('%02d', $this->generator->month()) + . sprintf('%02d', $this->generator->dayOfMonth()) + . $countyCode + . static::numerify('##%') + ; + + $cnp = static::cnpAddChecksum($cnp); + + return $cnp; + } + + /** + * Calculates the first digit for the Personal Numerical Code (CNP) based on + * the gender and century + * + * @param string $gender Valid values: m, f, 1, 2 + * @param integer $century Valid values: 1800, 1900, 2000, 1, 2, 3, 4, 5, 6 + * @return integer + */ + protected static function cnpFirstDigit($gender = null, $century = null) + { + switch ($century) { + case 1800: + case 3: + case 4: + $centuryCode = 2; + break; + case 1900: + case 1: + case 2: + $centuryCode = 0; + break; + case 2000: + case 5: + case 6: + $centuryCode = 4; + break; + default: + $centuryCode = static::randomElement(array(0, 2, 4, 6, 9)); + } + + switch (strtolower($gender)) { + case 'm': + case 1: + $genderCode = 1; + break; + case 'f': + case 2: + $genderCode = 2; + break; + default: + $genderCode = static::randomElement(array(1, 2)); + } + + $firstDigit = $centuryCode + $genderCode; + + return ($firstDigit > 9) ? 9 : $firstDigit; + } + + /** + * Calculates a checksum for the Personal Numerical Code (CNP). + * + * @param string $cnp Randomly generated CNP + * @return string CNP with the last digit altered to a proper checksum + */ + protected static function cnpAddChecksum($cnp) + { + $checkNumber = 279146358279; + + $checksum = 0; + foreach (range(0, 11) as $digit) { + $checksum += substr($cnp, $digit, 1) * substr($checkNumber, $digit, 1); + } + $checksum = $checksum % 11; + + return substr($cnp, 0, 12) . ($checksum == 10 ? 1 : $checksum); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/PhoneNumber.php new file mode 100644 index 0000000..9e3c07f --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ro_RO/PhoneNumber.php @@ -0,0 +1,67 @@ + array( + '021#######', // Bucharest + '023#######', + '024#######', + '025#######', + '026#######', + '027#######', // non-geographic + '031#######', // Bucharest + '033#######', + '034#######', + '035#######', + '036#######', + '037#######', // non-geographic + ), + 'mobile' => array( + '07########', + ) + ); + + protected static $specialFormats = array( + 'toll-free' => array( + '0800######', + '0801######', // shared-cost numbers + '0802######', // personal numbering + '0806######', // virtual cards + '0807######', // pre-paid cards + '0870######', // internet dial-up + ), + 'premium-rate' => array( + '0900######', + '0903######', // financial information + '0906######', // adult entertainment + ) + ); + + /** + * @link http://en.wikipedia.org/wiki/Telephone_numbers_in_Romania#Last_years + */ + public static function phoneNumber() + { + $type = static::randomElement(array_keys(static::$normalFormats)); + $number = static::numerify(static::randomElement(static::$normalFormats[$type])); + + return $number; + } + + public static function tollFreePhoneNumber() + { + $number = static::numerify(static::randomElement(static::$specialFormats['toll-free'])); + + return $number; + } + + public static function premiumRatePhoneNumber() + { + $number = static::numerify(static::randomElement(static::$specialFormats['premium-rate'])); + + return $number; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Address.php new file mode 100644 index 0000000..d017813 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Address.php @@ -0,0 +1,156 @@ +generator->parse($format); + } + + public static function country() + { + return static::randomElement(static::$country); + } + + public static function postcode() + { + return static::toUpper(static::bothify(static::randomElement(static::$postcode))); + } + + public static function regionSuffix() + { + return static::randomElement(static::$regionSuffix); + } + + public static function region() + { + return static::randomElement(static::$region); + } + + public static function cityPrefix() + { + return static::randomElement(static::$cityPrefix); + } + + public function city() + { + return static::randomElement(static::$city); + } + + public static function streetPrefix() + { + return static::randomElement(static::$streetPrefix); + } + + public static function street() + { + return static::randomElement(static::$street); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Color.php b/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Color.php new file mode 100644 index 0000000..e1af033 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Color.php @@ -0,0 +1,23 @@ +generator->parse($format); + } + + public static function companyPrefix() + { + return static::randomElement(static::$companyPrefixes); + } + + public static function companyNameElement() + { + return static::randomElement(static::$companyElements); + } + + public static function companyNameSuffix() + { + return static::randomElement(static::$companyNameSuffixes); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Internet.php new file mode 100644 index 0000000..53870ee --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Internet.php @@ -0,0 +1,9 @@ +.*<' | \ + * sed -r 's/—//' | sed -r 's/[\<\>]//g' | sed -r "s/(^|$)/'/g" | sed -r 's/$/,/' | sed -r 's/\&(laquo|raquo);/"/g' | \ + * sed -r 's/\s+/ /g'" + */ + protected static $banks = array( + 'Новый Промышленный Банк', + 'Новый Символ', + 'Нокссбанк', + 'Ноосфера', + 'Нордеа Банк', + 'Нота-Банк', + 'НС Банк', + 'НСТ-Банк', + 'Нэклис-Банк', + 'Образование', + 'Объединенный Банк Промышленных Инвестиций', + 'Объединенный Банк Республики', + 'Объединенный Капитал', + 'Объединенный Кредитный Банк', + 'Объединенный Кредитный Банк Московский филиал', + 'Объединенный Национальный Банк', + 'Объединенный Резервный Банк', + 'Океан Банк', + 'ОЛМА-Банк', + 'Онего', + 'Оней Банк', + 'ОПМ-Банк', + 'Оргбанк', + 'Оренбург', + 'ОТП Банк', + 'ОФК Банк', + 'Охабанк', + 'Первобанк', + 'Первомайский', + 'Первоуральскбанк', + 'Первый Дортрансбанк', + 'Первый Инвестиционный банк', + 'Первый Клиентский Банк', + 'Первый Чешско-Российский Банк', + 'Пересвет', + 'Пермь', + 'Петербургский Социальный Коммерческий Банк', + 'Петрокоммерц', + 'ПИР Банк', + 'Платина', + 'Плато-Банк', + 'Плюс Банк', + 'Пойдем!', + 'Почтобанк', + 'Прайм Финанс', + 'Преодоление', + 'Приморье', + 'Примсоцбанк', + 'Примтеркомбанк', + 'Прио-Внешторгбанк', + 'Приобье', + 'Приполярный', + 'Приско Капитал Банк', + 'Пробизнесбанк', + 'Проинвестбанк', + 'Прокоммерцбанк', + 'Проминвестбанк', + 'Промрегионбанк', + 'Промсвязьбанк', + 'Промсвязьинвестбанк', + 'Промсельхозбанк', + 'Промтрансбанк', + 'Промышленно-Финансовое Сотрудничество', + 'Промэнергобанк', + 'Профессионал Банк', + 'Профит Банк', + 'Прохладный', + 'Пульс Столицы', + 'Радиотехбанк', + 'Развитие', + 'Развитие-Столица', + 'Райффайзенбанк', + 'Расчетно-Кредитный Банк', + 'Расчетный Дом', + 'РБА', + 'Региональный Банк Развития', + 'Региональный Банк Сбережений', + 'Региональный Коммерческий Банк', + 'Региональный Кредит', + 'Регионфинансбанк', + 'Регнум', + 'Резерв', + 'Ренессанс', + 'Ренессанс Кредит', + 'Рента-Банк', + 'РЕСО Кредит', + 'Республиканский Кредитный Альянс', + 'Ресурс-Траст', + 'Риабанк', + 'Риал-Кредит', + 'Ринвестбанк', + 'Ринвестбанк Московский офис', + 'РИТ-Банк', + 'РН Банк', + 'Росавтобанк', + 'Росбанк', + 'Росбизнесбанк', + 'Росгосстрах Банк', + 'Росдорбанк', + 'РосЕвроБанк', + 'РосинтерБанк', + 'Роспромбанк', + 'Россельхозбанк', + 'Российская Финансовая Корпорация', + 'Российский Капитал', + 'Российский Кредит', + 'Российский Национальный Коммерческий Банк', + 'Россита-Банк', + 'Россия', + 'Рост Банк', + 'Ростфинанс', + 'Росэксимбанк', + 'Росэнергобанк', + 'Роял Кредит Банк', + 'РСКБ', + 'РТС-Банк', + 'РУБанк', + 'Рублев', + 'Руна-Банк', + 'Рунэтбанк', + 'Рускобанк', + 'Руснарбанк', + 'Русский Банк Сбережений', + 'Русский Ипотечный Банк', + 'Русский Международный Банк', + 'Русский Национальный Банк', + 'Русский Стандарт', + 'Русский Торговый Банк', + 'Русский Трастовый Банк', + 'Русский Финансовый Альянс', + 'Русский Элитарный Банк', + 'Русславбанк', + 'Руссобанк', + 'Русстройбанк', + 'Русфинанс Банк', + 'Русь', + 'РусьРегионБанк', + 'Русьуниверсалбанк', + 'РусЮгбанк', + 'РФИ Банк', + 'Саммит Банк', + 'Санкт-Петербургский Банк Инвестиций', + 'Саратов', + 'Саровбизнесбанк', + 'Сбербанк России', + 'Связной Банк', + 'Связь-Банк', + 'СДМ-Банк', + 'Севастопольский Морской банк', + 'Северный Кредит', + 'Северный Народный Банк', + 'Северо-Восточный Альянс', + 'Северо-Западный 1 Альянс Банк', + 'Северстройбанк', + 'Севзапинвестпромбанк', + 'Сельмашбанк', + 'Сервис-Резерв', + 'Сетелем Банк', + 'СИАБ', + 'Сибирский Банк Реконструкции и Развития', + 'Сибнефтебанк', + 'Сибсоцбанк', + 'Сибэс', + 'Сибэс Московский офис', + 'Синергия', + 'Синко-Банк', + 'Система', + 'Сити Инвест Банк', + 'Ситибанк', + 'СКА-Банк', + 'СКБ-Банк', + 'Славия', + 'Славянбанк', + 'Славянский Кредит', + 'Смартбанк', + 'СМБ-Банк', + 'Смолевич', + 'СМП Банк', + 'Снежинский', + 'Собинбанк', + 'Соверен Банк', + 'Советский', + 'Совкомбанк', + 'Современные Стандарты Бизнеса', + 'Содружество', + 'Соколовский', + 'Солид Банк', + 'Солидарность (Москва)', + 'Солидарность (Самара)', + 'Социнвестбанк', + 'Социнвестбанк Московский филиал', + 'Социум-Банк', + 'Союз', + 'Союзный', + 'Спецстройбанк', + 'Спиритбанк', + 'Спурт Банк', + 'Спутник', + 'Ставропольпромстройбанк', + 'Сталь Банк', + 'Стандарт-Кредит', + 'Стар Альянс', + 'СтарБанк', + 'Старооскольский Агропромбанк', + 'Старый Кремль', + 'Стелла-Банк', + 'Столичный Кредит', + 'Стратегия', + 'Строительно-Коммерческий Банк', + 'Стройлесбанк', + 'Сумитомо Мицуи', + 'Сургутнефтегазбанк', + 'СЭБ Банк', + 'Таатта', + 'Таврический', + 'Таганрогбанк', + 'Тагилбанк', + 'Тайдон', + 'Тайм Банк', + 'Тальменка-Банк', + 'Тальменка-Банк Московский филиал', + 'Тамбовкредитпромбанк', + 'Татагропромбанк', + 'Татсоцбанк', + 'Татфондбанк', + 'Таурус Банк', + 'ТверьУниверсалБанк', + 'Тексбанк', + 'Темпбанк', + 'Тендер-Банк', + 'Терра', + 'Тетраполис', + 'Тимер Банк', + 'Тинькофф Банк', + 'Тихоокеанский Внешторгбанк', + 'Тойота Банк', + 'Тольяттихимбанк', + 'Томскпромстройбанк', + 'Торгово-Промышленный Банк Китая', + 'Торговый Городской Банк', + 'Торжокуниверсалбанк', + 'Транскапиталбанк', + 'Транснациональный Банк', + 'Транспортный', + 'Трансстройбанк', + 'Траст Капитал Банк', + 'Тройка-Д Банк', + 'Тульский Промышленник', + 'Тульский Промышленник Московский офис', + 'Тульский Расчетный Центр', + 'Турбобанк', + 'Тусар', + 'ТЭМБР-Банк', + 'ТЭСТ', + 'Углеметбанк', + 'Уздан', + 'Унифин', + 'Унифондбанк', + 'Уралкапиталбанк', + 'Уралприватбанк', + 'Уралпромбанк', + 'Уралсиб', + 'Уралтрансбанк', + 'Уралфинанс', + 'Уральский Банк Реконструкции и Развития', + 'Уральский Межрегиональный Банк', + 'Уральский Финансовый Дом', + 'Ури Банк', + 'Уссури', + 'ФДБ', + 'ФИА-Банк', + 'Финам Банк', + 'Финанс Бизнес Банк', + 'Финансово-Промышленный Капитал', + 'Финансовый Капитал', + 'Финансовый Стандарт', + 'Финарс Банк', + 'Финпромбанк (ФПБ Банк)', + 'Финтрастбанк', + 'ФК Открытие (бывш. НОМОС-Банк)', + 'Флора-Москва', + 'Фольксваген Банк Рус', + 'Фондсервисбанк', + 'Фора-Банк', + 'Форбанк', + 'Форус Банк', + 'Форштадт', + 'Фьючер', + 'Хакасский Муниципальный Банк', + 'Ханты-Мансийский банк Открытие', + 'Химик', + 'Хлынов', + 'Хованский', + 'Холдинвестбанк', + 'Холмск', + 'Хоум Кредит Банк', + 'Центр-инвест', + 'Центрально-Азиатский', + 'Центрально-Европейский Банк', + 'Центркомбанк', + 'ЦентроКредит', + 'Церих', + 'Чайна Констракшн', + 'Чайнасельхозбанк', + 'Челиндбанк', + 'Челябинвестбанк', + 'Черноморский банк развития и реконструкции', + 'Чувашкредитпромбанк', + 'Эйч-Эс-Би-Си Банк (HSBC)', + 'Эко-Инвест', + 'Экономбанк', + 'Экономикс-Банк', + 'Экси-Банк', + 'Эксперт Банк', + 'Экспобанк', + 'Экспресс-Волга', + 'Экспресс-Кредит', + 'Эл Банк', + 'Элита', + 'Эльбин', + 'Энергобанк', + 'Энергомашбанк', + 'Энерготрансбанк', + 'Эно', + 'Энтузиастбанк', + 'Эргобанк', + 'Ю Би Эс Банк', + 'ЮГ-Инвестбанк', + 'Югра', + 'Южный Региональный Банк', + 'ЮМК', + 'Юниаструм Банк', + 'ЮниКредит Банк', + 'Юнистрим', + 'Япы Креди Банк Москва', + 'ЯР-Банк', + 'Яринтербанк', + 'Ярославич', + 'K2 Банк', + 'АББ', + 'Абсолют Банк', + 'Авангард', + 'Аверс', + 'Автоградбанк', + 'АвтоКредитБанк', + 'Автоторгбанк', + 'Агроинкомбанк', + 'Агропромкредит', + 'Агророс', + 'Агросоюз', + 'Адамон Банк', + 'Адамон Банк Московский филиал', + 'Аделантбанк', + 'Адмиралтейский', + 'Азиатско-Тихоокеанский Банк', + 'Азимут', + 'Азия Банк', + 'Азия-Инвест Банк', + 'Ай-Си-Ай-Си-Ай Банк (ICICI)', + 'Айви Банк', + 'АйМаниБанк', + 'Ак Барс', + 'Акибанк', + 'Аккобанк', + 'Акрополь', + 'Аксонбанк', + 'Актив Банк', + 'АктивКапитал Банк', + 'АктивКапитал Банк Московский филиал', + 'АктивКапитал Банк Санкт-Петербургский филиал', + 'Акцент', + 'Акцепт', + 'Акция', + 'Алданзолотобанк', + 'Александровский', + 'Алеф-Банк', + 'Алжан', + 'Алмазэргиэнбанк', + 'АлтайБизнес-Банк', + 'Алтайкапиталбанк', + 'Алтынбанк', + 'Альба Альянс', + 'Альта-Банк', + 'Альтернатива', + 'Альфа-Банк', + 'АМБ Банк', + 'Америкэн Экспресс Банк', + 'Анелик РУ', + 'Анкор Банк', + 'Анталбанк', + 'Апабанк', + 'Аресбанк', + 'Арзамас', + 'Арксбанк', + 'Арсенал', + 'Аспект', + 'Ассоциация', + 'БайкалБанк', + 'БайкалИнвестБанк', + 'Байкалкредобанк', + 'Балаково-Банк', + 'Балтийский Банк', + 'Балтика', + 'Балтинвестбанк', + 'Банк "Акцент" Московский филиал', + 'Банк "МБА-Москва"', + 'Банк "Санкт-Петербург"', + 'Банк АВБ', + 'Банк БКФ', + 'Банк БФА', + 'Банк БЦК-Москва', + 'Банк Город', + 'Банк Жилищного Финансирования', + 'Банк Инноваций и Развития', + 'Банк Интеза', + 'Банк ИТБ', + 'Банк Казани', + 'Банк Китая (Элос)', + 'Банк Кредит Свисс', + 'Банк МБФИ', + 'Банк Москвы', + 'Банк на Красных Воротах', + 'Банк Оранжевый (бывш. Промсервисбанк)', + 'Банк оф Токио-Мицубиси', + 'Банк Премьер Кредит', + 'Банк ПСА Финанс Рус', + 'Банк Развития Технологий', + 'Банк Расчетов и Сбережений', + 'Банк Раунд', + 'Банк РСИ', + 'Банк Сберегательно-кредитного сервиса', + 'Банк СГБ', + 'Банк Торгового Финансирования', + 'Банк Финсервис', + 'Банк Экономический Союз', + 'Банкирский Дом', + 'Банкхаус Эрбе', + 'Башкомснаббанк', + 'Башпромбанк', + 'ББР Банк', + 'Белгородсоцбанк', + 'Бенифит-Банк', + 'Берейт', + 'Бест Эффортс Банк', + 'Бизнес для Бизнеса', + 'Бинбанк', + 'БИНБАНК кредитные карты', + 'Бинбанк Мурманск', + 'БКС Инвестиционный Банк', + 'БМВ Банк', + 'БНП Париба Банк', + 'Богородский', + 'Богородский Муниципальный Банк', + 'Братский АНКБ', + 'БСТ-Банк', + 'Булгар Банк', + 'Бум-Банк', + 'Бумеранг', + 'БФГ-Кредит', + 'БыстроБанк', + 'Вакобанк', + 'Вега-Банк', + 'Век', + 'Великие Луки Банк', + 'Венец', + 'Верхневолжский', + 'Верхневолжский Крымский филиал', + 'Верхневолжский Московский филиал', + 'Верхневолжский Невский филиал', + 'Верхневолжский Таврический филиал', + 'Верхневолжский Ярославский филиал', + 'Веста', + 'Вестинтербанк', + 'Взаимодействие', + 'Викинг', + 'Витабанк', + 'Витязь', + 'Вкабанк', + 'Владбизнесбанк', + 'Владпромбанк', + 'Внешпромбанк', + 'Внешфинбанк', + 'Внешэкономбанк', + 'Военно-Промышленный Банк', + 'Возрождение', + 'Вокбанк', + 'Вологдабанк', + 'Вологжанин', + 'Воронеж', + 'Восточно-Европейский Трастовый Банк', + 'Восточный Экспресс Банк', + 'ВостСибтранскомбанк', + 'ВРБ Москва', + 'Всероссийский Банк Развития Регионов', + 'ВТБ', + 'ВТБ 24', + 'ВУЗ-Банк', + 'Выборг-Банк', + 'Выборг-Банк Московский филиал', + 'Вэлтон Банк', + 'Вятич', + 'Вятка-Банк', + 'Гагаринский', + 'Газбанк', + 'Газнефтьбанк', + 'Газпромбанк', + 'Газстройбанк', + 'Газтрансбанк', + 'Газэнергобанк', + 'Ганзакомбанк', + 'Гарант-Инвест', + 'Гаранти Банк Москва', + 'Геленджик-Банк', + 'Генбанк', + 'Геобанк', + 'Гефест', + 'Глобус', + 'Глобэкс', + 'Голдман Сакс Банк', + 'Горбанк', + 'ГПБ-Ипотека', + 'Гранд Инвест Банк', + 'Гринкомбанк', + 'Гринфилдбанк', + 'Грис-Банк', + 'Гута-Банк', + 'Далена', + 'Далетбанк', + 'Далта-Банк', + 'Дальневосточный Банк', + 'Данске Банк', + 'Девон-Кредит', + 'ДельтаКредит', + 'Денизбанк Москва', + 'Держава', + 'Дж. П. Морган Банк', + 'Джаст Банк', + 'Джей энд Ти Банк', + 'Дил-Банк', + 'Динамичные Системы', + 'Дойче Банк', + 'Долинск', + 'Дом-Банк', + 'Дон-Тексбанк', + 'Донкомбанк', + 'Донхлеббанк', + 'Дорис Банк', + 'Дружба', + 'ЕАТП Банк', + 'Евразийский Банк', + 'Евроазиатский Инвестиционный Банк', + 'ЕвроАксис Банк', + 'Евроальянс', + 'Еврокапитал-Альянс', + 'Еврокоммерц', + 'Еврокредит', + 'Евромет', + 'Европейский Стандарт', + 'Европлан Банк', + 'ЕвроситиБанк', + 'Еврофинанс Моснарбанк', + 'Единственный', + 'Единый Строительный Банк', + 'Екатеринбург', + 'Екатерининский', + 'Енисей', + 'Енисейский Объединенный Банк', + 'Ермак', + 'Живаго-Банк', + 'Жилкредит', + 'Жилстройбанк', + 'Запсибкомбанк', + 'Заречье', + 'Заубер Банк', + 'Земкомбанк', + 'Земский Банк', + 'Зенит', + 'Зенит Сочи', + 'Зернобанк', + 'Зираат Банк', + 'Златкомбанк', + 'И.Д.Е.А. Банк', + 'Иваново', + 'Идеалбанк', + 'Ижкомбанк', + 'ИК Банк', + 'Икано Банк', + 'Инбанк', + 'Инвест-Экобанк', + 'Инвестиционный Банк Кубани', + 'Инвестиционный Республиканский Банк', + 'Инвестиционный Союз', + 'Инвесткапиталбанк', + 'Инвестсоцбанк', + 'Инвестторгбанк', + 'ИНГ Банк', + 'Индустриальный Сберегательный Банк', + 'Инкаробанк', + 'Интерактивный Банк', + 'Интеркоммерц Банк', + 'Интеркоопбанк', + 'Интеркредит', + 'Интернациональный Торговый Банк', + 'Интерпрогрессбанк', + 'Интерпромбанк', + 'Интехбанк', + 'Информпрогресс', + 'Ипозембанк', + 'ИпоТек Банк', + 'Иронбанк', + 'ИРС', + 'Итуруп', + 'Ишбанк', + 'Йошкар-Ола', + 'Калуга', + 'Камский Горизонт', + 'Камский Коммерческий Банк', + 'Камчаткомагропромбанк', + 'Канский', + 'Капитал', + 'Капиталбанк', + 'Кедр', + 'Кемсоцинбанк', + 'Кетовский Коммерческий Банк', + 'Киви Банк', + 'Классик Эконом Банк', + 'Клиентский', + 'Кольцо Урала', + 'Коммерцбанк (Евразия)', + 'Коммерческий Банк Развития', + 'Коммерческий Индо Банк', + 'Консервативный Коммерческий Банк', + 'Констанс-Банк', + 'Континенталь', + 'Конфидэнс Банк', + 'Кор', + 'Кореа Эксчендж Банк Рус', + 'Королевский Банк Шотландии', + 'Космос', + 'Костромаселькомбанк', + 'Кошелев-Банк', + 'Крайинвестбанк', + 'Кранбанк', + 'Креди Агриколь КИБ', + 'Кредит Европа Банк', + 'Кредит Урал Банк', + 'Кредит Экспресс', + 'Кредит-Москва', + 'Кредитинвест', + 'Кредо Финанс', + 'Кредпромбанк', + 'Кремлевский', + 'Крокус-Банк', + 'Крона-Банк', + 'Кросна-Банк', + 'Кроссинвестбанк', + 'Крыловский', + 'КС Банк', + 'Кубанский Универсальный Банк', + 'Кубань Кредит', + 'Кубаньторгбанк', + 'Кузбассхимбанк', + 'Кузнецкбизнесбанк', + 'Кузнецкий', + 'Кузнецкий Мост', + 'Курган', + 'Курскпромбанк', + 'Лада-Кредит', + 'Лайтбанк', + 'Ланта-Банк', + 'Левобережный', + 'Легион', + 'Леноблбанк', + 'Лесбанк', + 'Лето Банк', + 'Липецккомбанк', + 'Логос', + 'Локо-Банк', + 'Лэнд-Банк', + 'М2М Прайвет Банк', + 'Майкопбанк', + 'Майский', + 'МАК-Банк', + 'Максима', + 'Максимум', + 'МАСТ-Банк', + 'Мастер-Капитал', + 'МВС Банк', + 'МДМ Банк', + 'Мегаполис', + 'Международный Акционерный Банк', + 'Международный Банк Развития', + 'Международный Банк Санкт-Петербурга (МБСП)', + 'Международный Коммерческий Банк', + 'Международный Расчетный Банк', + 'Международный Строительный Банк', + 'Международный Финансовый Клуб', + 'Межотраслевая Банковская Корпорация', + 'Межрегиональный Банк Реконструкции', + 'Межрегиональный Клиринговый Банк', + 'Межрегиональный Почтовый Банк', + 'Межрегиональный промышленно-строительный банк', + 'Межрегионбанк', + 'Межтопэнергобанк', + 'Межтрастбанк', + 'Мерседес-Бенц Банк Рус', + 'Металлинвестбанк', + 'Металлург', + 'Меткомбанк (Каменск-Уральский)', + 'Меткомбанк (Череповец)', + 'Метробанк', + 'Метрополь', + 'Мидзухо Банк', + 'Мико-Банк', + 'Милбанк', + 'Миллениум Банк', + 'Мир Бизнес Банк', + 'Мираф-Банк', + 'Мираф-Банк Московский филиал', + 'Миръ', + 'Михайловский ПЖСБ', + 'Морган Стэнли Банк', + 'Морской Банк', + 'Мосводоканалбанк', + 'Москва', + 'Москва-Сити', + 'Московский Вексельный Банк', + 'Московский Индустриальный Банк', + 'Московский Коммерческий Банк', + 'Московский Кредитный Банк', + 'Московский Национальный Инвестиционный Банк', + 'Московский Нефтехимический Банк', + 'Московский Областной Банк', + 'Московско-Парижский Банк', + 'Московское Ипотечное Агентство', + 'Москоммерцбанк', + 'Мосстройэкономбанк (М Банк)', + 'Мострансбанк', + 'Мосуралбанк', + 'МС Банк Рус', + 'МСП Банк', + 'МТИ-Банк', + 'МТС Банк', + 'Муниципальный Камчатпрофитбанк', + 'Мурманский Социальный Коммерческий Банк', + 'МФБанк', + 'Н-Банк', + 'Нальчик', + 'Наратбанк', + 'Народный Банк', + 'Народный Банк Республики Тыва', + 'Народный Доверительный Банк', + 'Народный Земельно-Промышленный Банк', + 'Народный Инвестиционный Банк', + 'Натиксис Банк', + 'Нацинвестпромбанк', + 'Национальная Факторинговая Компания', + 'Национальный Банк "Траст"', + 'Национальный Банк Взаимного Кредита', + 'Национальный Банк Сбережений', + 'Национальный Залоговый Банк', + 'Национальный Клиринговый Банк', + 'Национальный Клиринговый Центр', + 'Национальный Корпоративный Банк', + 'Национальный Резервный Банк', + 'Национальный Стандарт', + 'Наш Дом', + 'НБД-Банк', + 'НБК-Банк', + 'Невастройинвест', + 'Невский Банк', + 'Нейва', + 'Нерюнгрибанк', + 'Нефтепромбанк', + 'Нефтяной Альянс', + 'Нижневолжский Коммерческий Банк', + 'Нико-Банк', + 'НК Банк', + 'НоваховКапиталБанк', + 'Новация', + 'Новикомбанк', + 'Новобанк', + 'Новое Время', + 'Новокиб', + 'Новопокровский', + 'Новый Век', + 'Новый Кредитный Союз', + 'Новый Московский Банк', + ); + + /** + * @example 'Новый Московский Банк' + */ + public static function bank() + { + return static::randomElement(static::$banks); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Person.php new file mode 100644 index 0000000..09a59f6 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/ru_RU/Person.php @@ -0,0 +1,135 @@ +generator->parse(static::randomElement(static::$lastNameFormat)); + } + + public static function lastNameMale() + { + return static::randomElement(static::$lastNameMale); + } + + public static function lastNameFemale() + { + return static::randomElement(static::$lastNameFemale); + } + + /** + * @example 'PhD' + */ + public static function suffix() + { + return static::randomElement(static::$suffix); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/PhoneNumber.php new file mode 100644 index 0000000..1baf7cc --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/sk_SK/PhoneNumber.php @@ -0,0 +1,15 @@ +format('ymd'); + + if ($gender && $gender == static::GENDER_MALE) { + $randomDigits = (string)static::numerify('##') . static::randomElement(array(1,3,5,7,9)); + } elseif ($gender && $gender == static::GENDER_FEMALE) { + $randomDigits = (string)static::numerify('##') . static::randomElement(array(0,2,4,6,8)); + } else { + $randomDigits = (string)static::numerify('###'); + } + + + $checksum = Luhn::computeCheckDigit($datePart . $randomDigits); + + return $datePart . '-' . $randomDigits . $checksum; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/sv_SE/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/sv_SE/PhoneNumber.php new file mode 100644 index 0000000..d15e5dd --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/sv_SE/PhoneNumber.php @@ -0,0 +1,37 @@ +format('a') === 'am' ? 'öö' : 'ös'; + } + + public static function dayOfWeek($max = 'now') + { + $map = array( + 'Sunday' => 'Pazar', + 'Monday' => 'Pazartesi', + 'Tuesday' => 'Salı', + 'Wednesday' => 'Çarşamba', + 'Thursday' => 'Perşembe', + 'Friday' => 'Cuma', + 'Saturday' => 'Cumartesi', + ); + $week = static::dateTime($max)->format('l'); + return isset($map[$week]) ? $map[$week] : $week; + } + + public static function monthName($max = 'now') + { + $map = array( + 'January' => 'Ocak', + 'February' => 'Şubat', + 'March' => 'Mart', + 'April' => 'Nisan', + 'May' => 'Mayıs', + 'June' => 'Haziran', + 'July' => 'Temmuz', + 'August' => 'Ağustos', + 'September' => 'Eylül', + 'October' => 'Ekim', + 'November' => 'Kasım', + 'December' => 'Aralık', + ); + $month = static::dateTime($max)->format('F'); + return isset($map[$month]) ? $map[$month] : $month; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/Internet.php new file mode 100644 index 0000000..ef907d4 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/tr_TR/Internet.php @@ -0,0 +1,9 @@ +generator->parse($format); + } + + public static function streetPrefix() + { + return static::randomElement(static::$streetPrefix); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Color.php b/vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Color.php new file mode 100644 index 0000000..197cc3b --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Color.php @@ -0,0 +1,23 @@ +generator->parse($format); + } + + public static function companyPrefix() + { + return static::randomElement(static::$companyPrefix); + } + + public static function companyName() + { + return static::randomElement(static::$companyName); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Internet.php new file mode 100644 index 0000000..33214d6 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/uk_UA/Internet.php @@ -0,0 +1,9 @@ +generator->parse($format)); + } + + public function hamletPrefix() + { + return static::randomElement(static::$hamletPrefix); + } + + public function wardName() + { + $format = static::randomElement(static::$wardNameFormats); + + return static::bothify($this->generator->parse($format)); + } + + public function wardPrefix() + { + return static::randomElement(static::$wardPrefix); + } + + public function districtName() + { + $format = static::randomElement(static::$districtNameFormats); + + return static::bothify($this->generator->parse($format)); + } + + public function districtPrefix() + { + return static::randomElement(static::$districtPrefix); + } + + /** + * @example 'Hà Nội' + */ + public function city() + { + return static::randomElement(static::$city); + } + + /** + * @example 'Bắc Giang' + */ + public static function province() + { + return static::randomElement(static::$province); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/Color.php b/vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/Color.php new file mode 100644 index 0000000..4deaa2f --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/Color.php @@ -0,0 +1,36 @@ +generator->parse(static::randomElement(static::$middleNameFormat)); + } + + public static function middleNameMale() + { + return static::randomElement(static::$middleNameMale); + } + + public static function middleNameFemale() + { + return static::randomElement(static::$middleNameFemale); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/PhoneNumber.php b/vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/PhoneNumber.php new file mode 100644 index 0000000..694e395 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/vi_VN/PhoneNumber.php @@ -0,0 +1,61 @@ + array( + '0[a] ### ####', + '(0[a]) ### ####', + '0[a]-###-####', + '(0[a])###-####', + '84-[a]-###-####', + '(84)([a])###-####', + '+84-[a]-###-####', + ), + '8' => array( + '0[a] #### ####', + '(0[a]) #### ####', + '0[a]-####-####', + '(0[a])####-####', + '84-[a]-####-####', + '(84)([a])####-####', + '+84-[a]-####-####', + ), + ); + + public static function phoneNumber() + { + $areaCode = static::randomElement(static::$areaCodes); + $areaCodeLength = strlen($areaCode); + $digits = 7; + + if ($areaCodeLength < 2) { + $digits = 8; + } + + return static::numerify(str_replace('[a]', $areaCode, static::randomElement(static::$formats[$digits]))); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Address.php b/vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Address.php new file mode 100644 index 0000000..f36a49a --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Address.php @@ -0,0 +1,43 @@ +city() . static::area(); + } + + public static function postcode() + { + $prefix = str_pad(mt_rand(1, 85), 2, 0, STR_PAD_LEFT); + $suffix = '00'; + + return $prefix . mt_rand(10, 88) . $suffix; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Company.php b/vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Company.php new file mode 100644 index 0000000..4a5a738 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/zh_CN/Company.php @@ -0,0 +1,26 @@ + array( + '板橋區', '三重區', '中和區', '永和區', + '新莊區', '新店區', '樹林區', '鶯歌區', + '三峽區', '淡水區', '汐止區', '瑞芳區', + '土城區', '蘆洲區', '五股區', '泰山區', + '林口區', '深坑區', '石碇區', '坪林區', + '三芝區', '石門區', '八里區', '平溪區', + '雙溪區', '貢寮區', '金山區', '萬里區', + '烏來區', + ), + '宜蘭縣' => array( + '宜蘭市', '羅東鎮', '蘇澳鎮', '頭城鎮', '礁溪鄉', + '壯圍鄉', '員山鄉', '冬山鄉', '五結鄉', '三星鄉', + '大同鄉', '南澳鄉', + ), + '桃園縣' => array( + '桃園市', '中壢市', '大溪鎮', '楊梅鎮', '蘆竹鄉', + '大園鄉', '龜山鄉', '八德市', '龍潭鄉', '平鎮市', + '新屋鄉', '觀音鄉', '復興鄉', + ), + '新竹縣' => array( + '竹北市', '竹東鎮', '新埔鎮', '關西鎮', '湖口鄉', + '新豐鄉', '芎林鄉', '橫山鄉', '北埔鄉', '寶山鄉', + '峨眉鄉', '尖石鄉', '五峰鄉', + ), + '苗栗縣' => array( + '苗栗市', '苑裡鎮', '通霄鎮', '竹南鎮', '頭份鎮', + '後龍鎮', '卓蘭鎮', '大湖鄉', '公館鄉', '銅鑼鄉', + '南庄鄉', '頭屋鄉', '三義鄉', '西湖鄉', '造橋鄉', + '三灣鄉', '獅潭鄉', '泰安鄉', + ), + '臺中市' => array( + '豐原區', '東勢區', '大甲區', '清水區', '沙鹿區', + '梧棲區', '后里區', '神岡區', '潭子區', '大雅區', + '新社區', '石岡區', '外埔區', '大安區', '烏日區', + '大肚區', '龍井區', '霧峰區', '太平區', '大里區', + '和平區', '中區', '東區', '南區', '西區', '北區', + '西屯區', '南屯區', '北屯區', + ), + '彰化縣' => array( + '彰化市', '鹿港鎮', '和美鎮', '線西鄉', '伸港鄉', + '福興鄉', '秀水鄉', '花壇鄉', '芬園鄉', '員林鎮', + '溪湖鎮', '田中鎮', '大村鄉', '埔鹽鄉', '埔心鄉', + '永靖鄉', '社頭鄉', '二水鄉', '北斗鎮', '二林鎮', + '田尾鄉', '埤頭鄉', '芳苑鄉', '大城鄉', '竹塘鄉', + '溪州鄉', + ), + '南投縣' => array( + '南投市', '埔里鎮', '草屯鎮', '竹山鎮', '集集鎮', + '名間鄉', '鹿谷鄉', '中寮鄉', '魚池鄉', '國姓鄉', + '水里鄉', '信義鄉', '仁愛鄉', + ), + '雲林縣' => array( + '斗六市', '斗南鎮', '虎尾鎮', '西螺鎮', '土庫鎮', + '北港鎮', '古坑鄉', '大埤鄉', '莿桐鄉', '林內鄉', + '二崙鄉', '崙背鄉', '麥寮鄉', '東勢鄉', '褒忠鄉', + '臺西鄉', '元長鄉', '四湖鄉', '口湖鄉', '水林鄉', + ), + '嘉義縣' => array( + '太保市', '朴子市', '布袋鎮', '大林鎮', '民雄鄉', + '溪口鄉', '新港鄉', '六腳鄉', '東石鄉', '義竹鄉', + '鹿草鄉', '水上鄉', '中埔鄉', '竹崎鄉', '梅山鄉', + '番路鄉', '大埔鄉', '阿里山鄉', + ), + '臺南市' => array( + '新營區', '鹽水區', '白河區', '柳營區', '後壁區', + '東山區', '麻豆區', '下營區', '六甲區', '官田區', + '大內區', '佳里區', '學甲區', '西港區', '七股區', + '將軍區', '北門區', '新化區', '善化區', '新市區', + '安定區', '山上區', '玉井區', '楠西區', '南化區', + '左鎮區', '仁德區', '歸仁區', '關廟區', '龍崎區', + '永康區', '東區', '南區', '西區', '北區', '中區', + '安南區', '安平區', + ), + '高雄市' => array( + '鳳山區', '林園區', '大寮區', '大樹區', '大社區', + '仁武區', '鳥松區', '岡山區', '橋頭區', '燕巢區', + '田寮區', '阿蓮區', '路竹區', '湖內區', '茄萣區', + '永安區', '彌陀區', '梓官區', '旗山區', '美濃區', + '六龜區', '甲仙區', '杉林區', '內門區', '茂林區', + '桃源區', '三民區', '鹽埕區', '鼓山區', '左營區', + '楠梓區', '三民區', '新興區', '前金區', '苓雅區', + '前鎮區', '旗津區', '小港區', + ), + '屏東縣' => array( + '屏東市', '潮州鎮', '東港鎮', '恆春鎮', '萬丹鄉', + '長治鄉', '麟洛鄉', '九如鄉', '里港鄉', '鹽埔鄉', + '高樹鄉', '萬巒鄉', '內埔鄉', '竹田鄉', '新埤鄉', + '枋寮鄉', '新園鄉', '崁頂鄉', '林邊鄉', '南州鄉', + '佳冬鄉', '琉球鄉', '車城鄉', '滿州鄉', '枋山鄉', + '三地門鄉', '霧臺鄉', '瑪家鄉', '泰武鄉', '來義鄉', + '春日鄉', '獅子鄉', '牡丹鄉', + ), + '臺東縣' => array( + '臺東市', '成功鎮', '關山鎮', '卑南鄉', '鹿野鄉', + '池上鄉', '東河鄉', '長濱鄉', '太麻里鄉', '大武鄉', + '綠島鄉', '海端鄉', '延平鄉', '金峰鄉', '達仁鄉', + '蘭嶼鄉', + ), + '花蓮縣' => array( + '花蓮市', '鳳林鎮', '玉里鎮', '新城鄉', '吉安鄉', + '壽豐鄉', '光復鄉', '豐濱鄉', '瑞穗鄉', '富里鄉', + '秀林鄉', '萬榮鄉', '卓溪鄉', + ), + '澎湖縣' => array( + '馬公市', '湖西鄉', '白沙鄉', '西嶼鄉', '望安鄉', + '七美鄉', + ), + '基隆市' => array( + '中正區', '七堵區', '暖暖區', '仁愛區', '中山區', + '安樂區', '信義區', + ), + '新竹市' => array( + '東區', '北區', '香山區', + ), + '嘉義市' => array( + '東區', '西區', + ), + '臺北市' => array( + '松山區', '信義區', '大安區', '中山區', '中正區', + '大同區', '萬華區', '文山區', '南港區', '內湖區', + '士林區', '北投區', + ), + '連江縣' => array( + '南竿鄉', '北竿鄉', '莒光鄉', '東引鄉', + ), + '金門縣' => array( + '金城鎮', '金沙鎮', '金湖鎮', '金寧鄉', '烈嶼鄉', '烏坵鄉', + ), + ); + + /** + * @link http://terms.naer.edu.tw/download/287/ + */ + protected static $country = array( + '不丹', '中非', '丹麥', '伊朗', '冰島', '剛果', + '加彭', '北韓', '南非', '卡達', '印尼', '印度', + '古巴', '哥德', '埃及', '多哥', '寮國', '尼日', + '巴曼', '巴林', '巴紐', '巴西', '希臘', '帛琉', + '德國', '挪威', '捷克', '教廷', '斐濟', '日本', + '智利', '東加', '查德', '汶萊', '法國', '波蘭', + '波赫', '泰國', '海地', '瑞典', '瑞士', '祕魯', + '秘魯', '約旦', '紐埃', '緬甸', '美國', '聖尼', + '聖普', '肯亞', '芬蘭', '英國', '荷蘭', '葉門', + '蘇丹', '諾魯', '貝南', '越南', '迦彭', + '迦納', '阿曼', '阿聯', '韓國', '馬利', + '以色列', '以色利', '伊拉克', '俄羅斯', + '利比亞', '加拿大', '匈牙利', '南極洲', + '南蘇丹', '厄瓜多', '吉布地', '吐瓦魯', + '哈撒克', '哈薩克', '喀麥隆', '喬治亞', + '土庫曼', '土耳其', '塔吉克', '塞席爾', + '墨西哥', '大西洋', '奧地利', '孟加拉', + '安哥拉', '安地卡', '安道爾', '尚比亞', + '尼伯爾', '尼泊爾', '巴哈馬', '巴拉圭', + '巴拿馬', '巴貝多', '幾內亞', '愛爾蘭', + '所在國', '摩洛哥', '摩納哥', '敍利亞', + '敘利亞', '新加坡', '東帝汶', '柬埔寨', + '比利時', '波扎那', '波札那', '烏克蘭', + '烏干達', '烏拉圭', '牙買加', '獅子山', + '甘比亞', '盧安達', '盧森堡', '科威特', + '科索夫', '科索沃', '立陶宛', '紐西蘭', + '維德角', '義大利', '聖文森', '艾塞亞', + '菲律賓', '萬那杜', '葡萄牙', '蒲隆地', + '蓋亞納', '薩摩亞', '蘇利南', '西班牙', + '貝里斯', '賴索托', '辛巴威', '阿富汗', + '阿根廷', '馬其頓', '馬拉威', '馬爾他', + '黎巴嫩', '亞塞拜然', '亞美尼亞', '保加利亞', + '南斯拉夫', '厄利垂亞', '史瓦濟蘭', '吉爾吉斯', + '吉里巴斯', '哥倫比亞', '坦尚尼亞', '塞內加爾', + '塞内加爾', '塞爾維亞', '多明尼加', '多米尼克', + '奈及利亞', '委內瑞拉', '宏都拉斯', '尼加拉瓜', + '巴基斯坦', '庫克群島', '愛沙尼亞', '拉脫維亞', + '摩爾多瓦', '摩里西斯', '斯洛伐克', '斯里蘭卡', + '格瑞那達', '模里西斯', '波多黎各', '澳大利亞', + '烏茲別克', '玻利維亞', '瓜地馬拉', '白俄羅斯', + '突尼西亞', '納米比亞', '索馬利亞', '索馬尼亞', + '羅馬尼亞', '聖露西亞', '聖馬利諾', '莫三比克', + '莫三鼻克', '葛摩聯盟', '薩爾瓦多', '衣索比亞', + '西薩摩亞', '象牙海岸', '賴比瑞亞', '賽普勒斯', + '馬來西亞', '馬爾地夫', '克羅埃西亞', + '列支敦斯登', '哥斯大黎加', '布吉納法索', + '布吉那法索', '幾內亞比索', '幾內亞比紹', + '斯洛維尼亞', '索羅門群島', '茅利塔尼亞', + '蒙特內哥羅', '赤道幾內亞', '阿爾及利亞', + '阿爾及尼亞', '阿爾巴尼亞', '馬紹爾群島', + '馬達加斯加', '密克羅尼西亞', '沙烏地阿拉伯', + '千里達及托巴哥', + ); + + protected static $postcode = array('###-##', '###'); + + public function street() + { + return static::randomElement(static::$street); + } + + public static function randomChineseNumber() + { + $digits = array( + '', '一', '二', '三', '四', '五', '六', '七', '八', '九', + ); + return $digits[static::randomDigitNotNull()]; + } + + public static function randomNumber2() + { + return static::randomNumber(2) + 1; + } + + public static function randomNumber3() + { + return static::randomNumber(3) + 1; + } + + public static function localLatitude() + { + return number_format(mt_rand(22000000, 25000000)/1000000, 6); + } + + public static function localLongitude() + { + return number_format(mt_rand(120000000, 122000000)/1000000, 6); + } + + public function city() + { + $county = static::randomElement(array_keys(static::$city)); + $city = static::randomElement(static::$city[$county]); + return $county.$city; + } + + public function state() + { + return '臺灣省'; + } + + public static function stateAbbr() + { + return '臺'; + } + + public static function cityPrefix() + { + return ''; + } + + public static function citySuffix() + { + return ''; + } + + public static function secondaryAddress() + { + return (static::randomNumber(2)+1).static::randomElement(static::$secondaryAddressSuffix); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Color.php b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Color.php new file mode 100644 index 0000000..7be5953 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Color.php @@ -0,0 +1,66 @@ +generator->parse($format); + } + + public static function companyModifier() + { + return static::randomElement(static::$companyModifier); + } + + public static function companyPrefix() + { + return static::randomElement(static::$companyPrefix); + } + + public function catchPhrase() + { + return static::randomElement(static::$catchPhrase); + } + + public function bs() + { + $result = ''; + foreach (static::$bsWords as &$word) { + $result .= static::randomElement($word); + } + return $result; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/DateTime.php b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/DateTime.php new file mode 100644 index 0000000..6df5e92 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/DateTime.php @@ -0,0 +1,46 @@ +format('a') === 'am' ? '上午' : '下午'; + } + + public static function dayOfWeek($max = 'now') + { + $map = array( + 'Sunday' => '星期日', + 'Monday' => '星期一', + 'Tuesday' => '星期二', + 'Wednesday' => '星期三', + 'Thursday' => '星期四', + 'Friday' => '星期五', + 'Saturday' => '星期六', + ); + $week = static::dateTime($max)->format('l'); + return isset($map[$week]) ? $map[$week] : $week; + } + + public static function monthName($max = 'now') + { + $map = array( + 'January' => '一月', + 'February' => '二月', + 'March' => '三月', + 'April' => '四月', + 'May' => '五月', + 'June' => '六月', + 'July' => '七月', + 'August' => '八月', + 'September' => '九月', + 'October' => '十月', + 'November' => '十一月', + 'December' => '十二月', + ); + $month = static::dateTime($max)->format('F'); + return isset($map[$month]) ? $map[$month] : $month; + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Internet.php b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Internet.php new file mode 100644 index 0000000..4035ea8 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Internet.php @@ -0,0 +1,16 @@ +userName(); + } + + public function domainWord() + { + return \Faker\Factory::create('en_US')->domainWord(); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Payment.php b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Payment.php new file mode 100644 index 0000000..6b1a582 --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Payment.php @@ -0,0 +1,11 @@ +creditCardDetails($valid); + } +} diff --git a/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Person.php b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Person.php new file mode 100644 index 0000000..71f248b --- /dev/null +++ b/vendor/fzaninotto/faker/src/Faker/Provider/zh_TW/Person.php @@ -0,0 +1,132 @@ +unique() + */ +class UniqueGenerator +{ + protected $generator; + protected $maxRetries; + protected $uniques = array(); + + public function __construct(Generator $generator, $maxRetries) + { + $this->generator = $generator; + $this->maxRetries = $maxRetries; + } + + /** + * Catch and proxy all generator calls but return only unique values + */ + public function __get($attribute) + { + return $this->__call($attribute, array()); + } + + /** + * Catch and proxy all generator calls with arguments but return only unique values + */ + 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($res, $this->uniques[$name])); + $this->uniques[$name][$res]= null; + + return $res; + } +} diff --git a/vendor/fzaninotto/faker/src/autoload.php b/vendor/fzaninotto/faker/src/autoload.php new file mode 100644 index 0000000..69324ba --- /dev/null +++ b/vendor/fzaninotto/faker/src/autoload.php @@ -0,0 +1,27 @@ +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), + ); + } + + /** + * @dataProvider validatorProvider + */ + public function testIsValid($number, $isValid) + { + $this->assertEquals($isValid, Luhn::isValid($number)); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/DefaultGeneratorTest.php b/vendor/fzaninotto/faker/test/Faker/DefaultGeneratorTest.php new file mode 100644 index 0000000..262243d --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/DefaultGeneratorTest.php @@ -0,0 +1,27 @@ +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()); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/GeneratorTest.php b/vendor/fzaninotto/faker/test/Faker/GeneratorTest.php new file mode 100644 index 0000000..9fea4f8 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/GeneratorTest.php @@ -0,0 +1,144 @@ +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')); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testGetFormatterThrowsExceptionOnIncorrectProvider() + { + $generator = new Generator; + $generator->getFormatter('fooFormatter'); + } + + /** + * @expectedException InvalidArgumentException + */ + 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.'); + } +} + +class FooProvider +{ + public function fooFormatter() + { + return 'foobar'; + } + + public function fooFormatterWithArguments($value = '') + { + return 'baz' . $value; + } +} + +class BarProvider +{ + public function fooFormatter() + { + return 'barfoo'; + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/AddressTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/AddressTest.php new file mode 100644 index 0000000..cbabce5 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/AddressTest.php @@ -0,0 +1,34 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/BarcodeTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/BarcodeTest.php new file mode 100644 index 0000000..a7ee6d9 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/BarcodeTest.php @@ -0,0 +1,45 @@ +addProvider(new Barcode($faker)); + $faker->seed(0); + $this->faker = $faker; + } + + public function testEan8() + { + $code = $this->faker->ean8(); + $this->assertRegExp('/^\d{8}$/i', $code); + $codeWitoutChecksum = substr($code, 0, -1); + $checksum = substr($code, -1); + $this->assertEquals(TestableBarcode::eanChecksum($codeWitoutChecksum), $checksum); + } + + public function testEan13() + { + $code = $this->faker->ean13(); + $this->assertRegExp('/^\d{13}$/i', $code); + $codeWitoutChecksum = substr($code, 0, -1); + $checksum = substr($code, -1); + $this->assertEquals(TestableBarcode::eanChecksum($codeWitoutChecksum), $checksum); + } +} + +class TestableBarcode extends Barcode +{ + public static function eanChecksum($input) + { + return parent::eanChecksum($input); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/BaseTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/BaseTest.php new file mode 100644 index 0000000..95e694a --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/BaseTest.php @@ -0,0 +1,446 @@ +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); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testRandomNumberThrowsExceptionWhenCalledWithAMax() + { + BaseProvider::randomNumber(5, 200); + } + + /** + * @expectedException \InvalidArgumentException + */ + 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))); + } + + /** + * @expectedException \InvalidArgumentException + */ + 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); // definitely larger than PHP_INT_MAX on all systems + $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 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') + ); + } + + /** + * @dataProvider regexifyBasicDataProvider + */ + 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') + ); + } + + /** + * @dataProvider regexifyDataProvider + */ + 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(1)->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))); // hack because method_exists forbids stubs + $this->assertEquals(1, $faker->optional(1)->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))); // hack because method_exists forbids stubs + $this->assertEquals(1, $faker->optional(1)->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); + } + + public function testUniqueAllowsChainingPropertyAccess() + { + $faker = new \Faker\Generator(); + $faker->addProvider(new \Faker\Provider\Base($faker)); + $faker->addProvider(new \ArrayObject(array(1))); // hack because method_exists forbids stubs + $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))); // hack because method_exists forbids stubs + $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); + } + + /** + * @expectedException OverflowException + */ + 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); + } + + /** + * @expectedException LengthException + * @expectedExceptionMessage Cannot get 2 elements, only 1 in array + */ + 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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/BiasedTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/BiasedTest.php new file mode 100644 index 0000000..1f7a99a --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/BiasedTest.php @@ -0,0 +1,73 @@ +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')); + + // assert that all numbers are near the expected unbiased value + foreach ($this->results as $number => $amount) { + // integral + $assumed = (1 / self::MAX * $number) - (1 / self::MAX * ($number - 1)); + // calculate the fraction of the whole area + $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) { + // integral + $assumed = 0.5 * pow(1 / self::MAX * $number, 2) - 0.5 * pow(1 / self::MAX * ($number - 1), 2); + // calculate the fraction of the whole area + $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) { + // integral + $assumed = -0.5 * pow(1 / self::MAX * $number, 2) - -0.5 * pow(1 / self::MAX * ($number - 1), 2); + // shift the graph up + $assumed += 1 / self::MAX; + // calculate the fraction of the whole area + $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"); + } + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/ColorTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/ColorTest.php new file mode 100644 index 0000000..cdb4ab1 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/ColorTest.php @@ -0,0 +1,46 @@ +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 testSafeColorName() + { + $this->assertRegExp('/^[\w]+$/', Color::safeColorName()); + } + + public function testColorName() + { + $this->assertRegExp('/^[\w]+$/', Color::colorName()); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/DateTimeTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/DateTimeTest.php new file mode 100644 index 0000000..60310bd --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/DateTimeTest.php @@ -0,0 +1,122 @@ +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); + } + + 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); + } + + 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); + } + + /** + * + * @dataProvider providerDateTimeBetween + */ + 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); + } + + public function providerDateTimeBetween() + { + return array( + array('-1 year', false), + array('-1 year', null), + array('-1 day', '-1 hour'), + array('-1 day', 'now'), + ); + } + + 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(); + + //regenerate Random Date with same seed and same maximum end timestamp + 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(); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/ImageTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/ImageTest.php new file mode 100644 index 0000000..0535d4d --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/ImageTest.php @@ -0,0 +1,62 @@ +assertRegExp('#^http://lorempixel.com/640/480/#', Image::imageUrl()); + } + + public function testImageUrlAcceptsCustomWidthAndHeight() + { + $this->assertRegExp('#^http://lorempixel.com/800/400/#', Image::imageUrl(800, 400)); + } + + public function testImageUrlAcceptsCustomCategory() + { + $this->assertRegExp('#^http://lorempixel.com/800/400/nature/#', Image::imageUrl(800, 400, 'nature')); + } + + public function testImageUrlAcceptsCustomText() + { + $this->assertRegExp('#^http://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]); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testUrlWithDimensionsAndBadCategory() + { + Image::imageUrl(800, 400, 'bullhonky'); + } + + public function testDownloadWithDefaults() + { + $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); + } + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/InternetTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/InternetTest.php new file mode 100644 index 0000000..fcd750b --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/InternetTest.php @@ -0,0 +1,120 @@ +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; + } + + /** + * @link http://stackoverflow.com/questions/12026842/how-to-validate-an-email-address-in-php + * + * @requires PHP 5.4 + * @dataProvider localeDataProvider + */ + public function testEmailIsValid($locale) + { + $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); + } + + /** + * @requires PHP 5.4 + * @dataProvider localeDataProvider + */ + public function testUsernameIsValid($locale) + { + $this->loadLocalProviders($locale); + $pattern = '/^[A-Za-z0-9._]+$/'; + $username = $this->faker->username(); + $this->assertRegExp($pattern, $username); + } + + 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 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()); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/LocalizationTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/LocalizationTest.php new file mode 100644 index 0000000..347b135 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/LocalizationTest.php @@ -0,0 +1,26 @@ +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'); + } + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/LoremTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/LoremTest.php new file mode 100644 index 0000000..62785d4 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/LoremTest.php @@ -0,0 +1,108 @@ +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.'; + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/MiscellaneousTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/MiscellaneousTest.php new file mode 100644 index 0000000..6a4c559 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/MiscellaneousTest.php @@ -0,0 +1,54 @@ +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()); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/PaymentTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/PaymentTest.php new file mode 100644 index 0000000..0f20d91 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/PaymentTest.php @@ -0,0 +1,68 @@ +addProvider(new BaseProvider($faker)); + $faker->addProvider(new DateTimeProvider($faker)); + $faker->addProvider(new PersonProvider($faker)); + $faker->addProvider(new PaymentProvider($faker)); + $this->faker = $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]\d{14}$/') + ); + } + + /** + * @dataProvider creditCardNumberProvider + */ + 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)); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/PersonTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/PersonTest.php new file mode 100644 index 0000000..a8d1c0f --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/PersonTest.php @@ -0,0 +1,86 @@ +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')); + } + + /** + * @dataProvider titleProvider + */ + 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')); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/ProviderOverrideTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/ProviderOverrideTest.php new file mode 100644 index 0000000..68f75ae --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/ProviderOverrideTest.php @@ -0,0 +1,189 @@ + + */ + +namespace Faker\Test\Provider; + +use Faker; + +/** + * Class ProviderOverrideTest + * + * @package Faker\Test\Provider + * + * This class tests a large portion of all locale specific providers. It does not test the entire stack, because each + * locale specific provider (can) has specific implementations. The goal of this test is to test the common denominator + * and to try to catch possible invalid multi-byte sequences. + */ +class ProviderOverrideTest extends \PHPUnit_Framework_TestCase +{ + /** + * Constants with regular expression patterns for testing the output. + * + * Regular expressions are sensitive for malformed strings (e.g.: strings with incorrect encodings) so by using + * PCRE for the tests, even though they seem fairly pointless, we test for incorrect encodings also. + */ + const TEST_STRING_REGEX = '/.+/u'; + + /** + * Slightly more specific for e-mail, the point isn't to properly validate e-mails. + */ + const TEST_EMAIL_REGEX = '/^(.+)@(.+)$/ui'; + + /** + * @dataProvider localeDataProvider + * @param string $locale + */ + 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); + } + + + /** + * @dataProvider localeDataProvider + * @param string $locale + */ + public function testCompany($locale = null) + { + $faker = Faker\Factory::create($locale); + + $this->assertRegExp(static::TEST_STRING_REGEX, $faker->company); + } + + + /** + * @dataProvider localeDataProvider + * @param string $locale + */ + 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); + } + + + /** + * @dataProvider localeDataProvider + * @param string $locale + */ + public function testInternet($locale = null) + { + $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); + } + + + /** + * @dataProvider localeDataProvider + * @param string $locale + */ + 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); + } + + + /** + * @dataProvider localeDataProvider + * @param string $locale + */ + public function testPhoneNumber($locale = null) + { + $faker = Faker\Factory::create($locale); + + $this->assertRegExp(static::TEST_STRING_REGEX, $faker->phoneNumber); + } + + + /** + * @dataProvider localeDataProvider + * @param string $locale + */ + public function testUserAgent($locale = null) + { + $faker = Faker\Factory::create($locale); + + $this->assertRegExp(static::TEST_STRING_REGEX, $faker->userAgent); + } + + + /** + * @dataProvider localeDataProvider + * + * @param null $locale + * @param string $locale + */ + public function testUuid($locale = null) + { + $faker = Faker\Factory::create($locale); + + $this->assertRegExp(static::TEST_STRING_REGEX, $faker->uuid); + } + + + /** + * @return array + */ + public function localeDataProvider() + { + $locales = $this->getAllLocales(); + $data = array(); + + foreach ($locales as $locale) { + $data[] = array( + $locale + ); + } + + return $data; + } + + + /** + * Returns all locales as array values + * + * @return array + */ + private function getAllLocales() + { + static $locales = array(); + + if ( ! empty($locales)) { + return $locales; + } + + // Finding all PHP files in the xx_XX directories + $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; + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/TextTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/TextTest.php new file mode 100644 index 0000000..3baf49f --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/TextTest.php @@ -0,0 +1,54 @@ +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)); + } + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testTextMaxIndex() + { + $generator = new Generator(); + $generator->addProvider(new Text($generator)); + $generator->seed(0); + $generator->realText(200, 11); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testTextMinIndex() + { + $generator = new Generator(); + $generator->addProvider(new Text($generator)); + $generator->seed(0); + $generator->realText(200, 0); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testTextMinLength() + { + $generator = new Generator(); + $generator->addProvider(new Text($generator)); + $generator->seed(0); + $generator->realText(9); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/UserAgentTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/UserAgentTest.php new file mode 100644 index 0000000..b45b9f8 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/UserAgentTest.php @@ -0,0 +1,38 @@ +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()); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/UuidTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/UuidTest.php new file mode 100644 index 0000000..fceb8df --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/UuidTest.php @@ -0,0 +1,26 @@ +assertTrue($this->isUuid($uuid)); + } + + public function testUuidExpectedSeed() + { + mt_srand(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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/at_AT/PaymentTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/at_AT/PaymentTest.php new file mode 100644 index 0000000..afc8c27 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/at_AT/PaymentTest.php @@ -0,0 +1,30 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/be_BE/PaymentTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/be_BE/PaymentTest.php new file mode 100644 index 0000000..d253b05 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/be_BE/PaymentTest.php @@ -0,0 +1,30 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/bg_BG/PaymentTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/bg_BG/PaymentTest.php new file mode 100644 index 0000000..31c6325 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/bg_BG/PaymentTest.php @@ -0,0 +1,30 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/de_AT/InternetTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/de_AT/InternetTest.php new file mode 100644 index 0000000..91ce5ca --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/de_AT/InternetTest.php @@ -0,0 +1,32 @@ +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)); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/de_AT/PhoneNumberTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/de_AT/PhoneNumberTest.php new file mode 100644 index 0000000..2d61ad5 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/de_AT/PhoneNumberTest.php @@ -0,0 +1,28 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/fr_FR/CompanyTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/fr_FR/CompanyTest.php new file mode 100644 index 0000000..5486cf9 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/fr_FR/CompanyTest.php @@ -0,0 +1,74 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/id_ID/PersonTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/id_ID/PersonTest.php new file mode 100644 index 0000000..abd039f --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/id_ID/PersonTest.php @@ -0,0 +1,40 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/ja_JP/PersonTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/ja_JP/PersonTest.php new file mode 100755 index 0000000..97fc566 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/ja_JP/PersonTest.php @@ -0,0 +1,36 @@ +addProvider(new Person($faker)); + $faker->seed(1); + + $this->assertEquals('アオタ ミノル', $faker->kanaName); + } + + public function testFirstKanaNameReturnsHaruka() + { + $faker = new Generator(); + $faker->addProvider(new Person($faker)); + $faker->seed(1); + + $this->assertEquals('ハルカ', $faker->firstKanaName); + } + + public function testLastKanaNameReturnsNakajima() + { + $faker = new Generator(); + $faker->addProvider(new Person($faker)); + $faker->seed(1); + + $this->assertEquals('ナカジマ', $faker->lastKanaName); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/CompanyTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/CompanyTest.php new file mode 100644 index 0000000..f59142b --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/CompanyTest.php @@ -0,0 +1,25 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/PersonTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/PersonTest.php new file mode 100644 index 0000000..767c188 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/pt_BR/PersonTest.php @@ -0,0 +1,33 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/AddressTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/AddressTest.php new file mode 100644 index 0000000..d2adc15 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/AddressTest.php @@ -0,0 +1,30 @@ +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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PersonTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PersonTest.php new file mode 100644 index 0000000..9bfb7a2 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PersonTest.php @@ -0,0 +1,52 @@ +addProvider(new Person($faker)); + $this->faker = $faker; + } + + public function testTaxpayerIdentificationNumberIsValid() + { + $tin = $this->faker->taxpayerIdentificationNumber(); + $this->assertTrue($this->isValidTin($tin), $tin); + } + + /** + * + * @link http://pt.wikipedia.org/wiki/N%C3%BAmero_de_identifica%C3%A7%C3%A3o_fiscal + * + * @param type $tin + * + * @return boolean + */ + 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 - Control Digit + $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; + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PhoneNumberTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PhoneNumberTest.php new file mode 100644 index 0000000..04b2f63 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/pt_PT/PhoneNumberTest.php @@ -0,0 +1,25 @@ +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()); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PersonTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PersonTest.php new file mode 100644 index 0000000..5816b63 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PersonTest.php @@ -0,0 +1,95 @@ +seed(1); + $faker->addProvider(new DateTime($faker)); + $faker->addProvider(new Person($faker)); + $this->faker = $faker; + } + + public function testCnpReturnsValidCnp() + { + $cnp = $this->faker->cnp; + $this->assertTrue($this->isValidCnp($cnp)); + } + + public function testCnpReturnsMaleCnp() + { + $cnp = $this->faker->cnp('m'); + $this->assertRegExp('/^[1357]\d{12}$/', $cnp); + } + + public function testCnpReturnsFemaleCnp() + { + $cnp = $this->faker->cnp('f'); + $this->assertRegExp('/^[2468]\d{12}$/', $cnp); + } + + public function testCnpReturns1800sCnp() + { + $cnp = $this->faker->cnp(null, 1800); + $this->assertRegExp('/^[34]\d{12}$/', $cnp); + } + + public function testCnpReturns1900sCnp() + { + $cnp = $this->faker->cnp(null, 1900); + $this->assertRegExp('/^[12]\d{12}$/', $cnp); + } + + public function testCnpReturns2000sCnp() + { + $cnp = $this->faker->cnp(null, 2000); + $this->assertRegExp('/^[56]\d{12}$/', $cnp); + } + + public function testCnpReturnsBrasovCnp() + { + $cnp = $this->faker->cnp(null, null, 'BV'); + $this->assertRegExp('/^\d{7}08\d{4}$/', $cnp); + } + + public function testCnpReturns2000sClujFemaleCnp() + { + $cnp = $this->faker->cnp('f', 2000, 'CJ'); + $this->assertRegExp('/^6\d{6}12\d{4}$/', $cnp); + } + + protected function isValidCnp($cnp) + { + if ( + is_string($cnp) + && (bool) preg_match(static::TEST_CNP_REGEX, $cnp) + && checkdate(substr($cnp, 3, 2), substr($cnp, 5, 2), substr($cnp, 1, 2)) + ){ + $checkNumber = 279146358279; + + $checksum = 0; + foreach (range(0, 11) as $digit) { + $checksum += substr($cnp, $digit, 1) * substr($checkNumber, $digit, 1); + } + $checksum = $checksum % 11; + + if ( + ($checksum < 10 && $checksum == substr($cnp, -1)) + || ($checksum == 10 && substr($cnp, -1) == 1) + ){ + return true; + } + } + + return false; + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PhoneNumberTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PhoneNumberTest.php new file mode 100644 index 0000000..97314d5 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/ro_RO/PhoneNumberTest.php @@ -0,0 +1,31 @@ +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[1267]|70)\d{6}$/', $this->faker->tollFreePhoneNumber()); + } + + public function testPremiumRatePhoneNumberReturnsPremiumRatePhoneNumber() + { + $this->assertRegExp('/^090[036]\d{6}$/', $this->faker->premiumRatePhoneNumber()); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/sv_SE/PersonTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/sv_SE/PersonTest.php new file mode 100644 index 0000000..623723a --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/sv_SE/PersonTest.php @@ -0,0 +1,60 @@ +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') + ); + } + + /** + * @dataProvider provideSeedAndExpectedReturn + */ + 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); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/AddressTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/AddressTest.php new file mode 100644 index 0000000..a3e38d7 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/AddressTest.php @@ -0,0 +1,80 @@ +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!' + ); + } +} diff --git a/vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/PhoneNumberTest.php b/vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/PhoneNumberTest.php new file mode 100644 index 0000000..13620c7 --- /dev/null +++ b/vendor/fzaninotto/faker/test/Faker/Provider/uk_UA/PhoneNumberTest.php @@ -0,0 +1,35 @@ +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!' + ); + + } + +} diff --git a/vendor/fzaninotto/faker/test/documentor.php b/vendor/fzaninotto/faker/test/documentor.php new file mode 100644 index 0000000..1051ea2 --- /dev/null +++ b/vendor/fzaninotto/faker/test/documentor.php @@ -0,0 +1,16 @@ +seed(1); +$documentor = new Faker\Documentor($generator); +?> +getFormatters() as $provider => $formatters): ?> + +### `` + + $example): ?> + // + + +seed(5); + +echo ''; +?> + + + + +boolean(25)): ?> + + +
+ streetAddress ?> + city ?> + postcode ?> + state ?> +
+ +boolean(33)): ?> + bs ?> + +boolean(33)): ?> + + + +boolean(15)): ?> +
+text(400) ?> +]]> +
+ +
+ +
diff --git a/vendor/illuminate/auth/Access/Gate.php b/vendor/illuminate/auth/Access/Gate.php new file mode 100644 index 0000000..0671b4d --- /dev/null +++ b/vendor/illuminate/auth/Access/Gate.php @@ -0,0 +1,447 @@ +policies = $policies; + $this->container = $container; + $this->abilities = $abilities; + $this->userResolver = $userResolver; + $this->afterCallbacks = $afterCallbacks; + $this->beforeCallbacks = $beforeCallbacks; + } + + /** + * Determine if a given ability has been defined. + * + * @param string $ability + * @return bool + */ + public function has($ability) + { + return isset($this->abilities[$ability]); + } + + /** + * Define a new ability. + * + * @param string $ability + * @param callable|string $callback + * @return $this + * + * @throws \InvalidArgumentException + */ + public function define($ability, $callback) + { + if (is_callable($callback)) { + $this->abilities[$ability] = $callback; + } elseif (is_string($callback) && str_contains($callback, '@')) { + $this->abilities[$ability] = $this->buildAbilityCallback($callback); + } else { + throw new InvalidArgumentException("Callback must be a callable or a 'Class@method' string."); + } + + return $this; + } + + /** + * Create the ability callback for a callback string. + * + * @param string $callback + * @return \Closure + */ + protected function buildAbilityCallback($callback) + { + return function () use ($callback) { + list($class, $method) = explode('@', $callback); + + return call_user_func_array([$this->resolvePolicy($class), $method], func_get_args()); + }; + } + + /** + * Define a policy class for a given class type. + * + * @param string $class + * @param string $policy + * @return $this + */ + public function policy($class, $policy) + { + $this->policies[$class] = $policy; + + return $this; + } + + /** + * Register a callback to run before all Gate checks. + * + * @param callable $callback + * @return $this + */ + public function before(callable $callback) + { + $this->beforeCallbacks[] = $callback; + + return $this; + } + + /** + * Register a callback to run after all Gate checks. + * + * @param callable $callback + * @return $this + */ + public function after(callable $callback) + { + $this->afterCallbacks[] = $callback; + + return $this; + } + + /** + * Determine if the given ability should be granted for the current user. + * + * @param string $ability + * @param array|mixed $arguments + * @return bool + */ + public function allows($ability, $arguments = []) + { + return $this->check($ability, $arguments); + } + + /** + * Determine if the given ability should be denied for the current user. + * + * @param string $ability + * @param array|mixed $arguments + * @return bool + */ + public function denies($ability, $arguments = []) + { + return ! $this->allows($ability, $arguments); + } + + /** + * Determine if the given ability should be granted for the current user. + * + * @param string $ability + * @param array|mixed $arguments + * @return bool + */ + public function check($ability, $arguments = []) + { + try { + $result = $this->raw($ability, $arguments); + } catch (UnauthorizedException $e) { + return false; + } + + return (bool) $result; + } + + /** + * Determine if the given ability should be granted for the current user. + * + * @param string $ability + * @param array|mixed $arguments + * @return \Illuminate\Auth\Access\Response + * + * @throws \Illuminate\Auth\Access\UnauthorizedException + */ + public function authorize($ability, $arguments = []) + { + $result = $this->raw($ability, $arguments); + + if ($result instanceof Response) { + return $result; + } + + return $result ? $this->allow() : $this->deny(); + } + + /** + * Get the raw result for the given ability for the current user. + * + * @param string $ability + * @param array|mixed $arguments + * @return mixed + */ + protected function raw($ability, $arguments = []) + { + if (! $user = $this->resolveUser()) { + return false; + } + + $arguments = is_array($arguments) ? $arguments : [$arguments]; + + if (is_null($result = $this->callBeforeCallbacks($user, $ability, $arguments))) { + $result = $this->callAuthCallback($user, $ability, $arguments); + } + + $this->callAfterCallbacks( + $user, $ability, $arguments, $result + ); + + return $result; + } + + /** + * Resolve and call the appropriate authorization callback. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string $ability + * @param array $arguments + * @return bool + */ + protected function callAuthCallback($user, $ability, array $arguments) + { + $callback = $this->resolveAuthCallback( + $user, $ability, $arguments + ); + + return call_user_func_array( + $callback, array_merge([$user], $arguments) + ); + } + + /** + * Call all of the before callbacks and return if a result is given. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string $ability + * @param array $arguments + * @return bool|null + */ + protected function callBeforeCallbacks($user, $ability, array $arguments) + { + $arguments = array_merge([$user, $ability], $arguments); + + foreach ($this->beforeCallbacks as $before) { + if (! is_null($result = call_user_func_array($before, $arguments))) { + return $result; + } + } + } + + /** + * Call all of the after callbacks with check result. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string $ability + * @param array $arguments + * @param bool $result + * @return void + */ + protected function callAfterCallbacks($user, $ability, array $arguments, $result) + { + $arguments = array_merge([$user, $ability, $result], $arguments); + + foreach ($this->afterCallbacks as $after) { + call_user_func_array($after, $arguments); + } + } + + /** + * Resolve the callable for the given ability and arguments. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string $ability + * @param array $arguments + * @return callable + */ + protected function resolveAuthCallback($user, $ability, array $arguments) + { + if ($this->firstArgumentCorrespondsToPolicy($arguments)) { + return $this->resolvePolicyCallback($user, $ability, $arguments); + } elseif (isset($this->abilities[$ability])) { + return $this->abilities[$ability]; + } else { + return function () { return false; }; + } + } + + /** + * Determine if the first argument in the array corresponds to a policy. + * + * @param array $arguments + * @return bool + */ + protected function firstArgumentCorrespondsToPolicy(array $arguments) + { + if (! isset($arguments[0])) { + return false; + } + + if (is_object($arguments[0])) { + return isset($this->policies[get_class($arguments[0])]); + } + + return is_string($arguments[0]) && isset($this->policies[$arguments[0]]); + } + + /** + * Resolve the callback for a policy check. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string $ability + * @param array $arguments + * @return callable + */ + protected function resolvePolicyCallback($user, $ability, array $arguments) + { + return function () use ($user, $ability, $arguments) { + $instance = $this->getPolicyFor($arguments[0]); + + if (method_exists($instance, 'before')) { + // We will prepend the user and ability onto the arguments so that the before + // callback can determine which ability is being called. Then we will call + // into the policy before methods with the arguments and get the result. + $beforeArguments = array_merge([$user, $ability], $arguments); + + $result = call_user_func_array( + [$instance, 'before'], $beforeArguments + ); + + // If we recieved a non-null result from the before method, we will return it + // as the result of a check. This allows developers to override the checks + // in the policy and return a result for all rules defined in the class. + if (! is_null($result)) { + return $result; + } + } + + if (strpos($ability, '-') !== false) { + $ability = Str::camel($ability); + } + + if (! is_callable([$instance, $ability])) { + return false; + } + + return call_user_func_array( + [$instance, $ability], array_merge([$user], $arguments) + ); + }; + } + + /** + * Get a policy instance for a given class. + * + * @param object|string $class + * @return mixed + * + * @throws \InvalidArgumentException + */ + public function getPolicyFor($class) + { + if (is_object($class)) { + $class = get_class($class); + } + + if (! isset($this->policies[$class])) { + throw new InvalidArgumentException("Policy not defined for [{$class}]."); + } + + return $this->resolvePolicy($this->policies[$class]); + } + + /** + * Build a policy class instance of the given type. + * + * @param object|string $class + * @return mixed + */ + public function resolvePolicy($class) + { + return $this->container->make($class); + } + + /** + * Get a guard instance for the given user. + * + * @param \Illuminate\Contracts\Auth\Authenticatable|mixed $user + * @return static + */ + public function forUser($user) + { + return new static( + $this->container, function () use ($user) { return $user; }, $this->abilities, + $this->policies, $this->beforeCallbacks, $this->afterCallbacks + ); + } + + /** + * Resolve the user from the user resolver. + * + * @return mixed + */ + protected function resolveUser() + { + return call_user_func($this->userResolver); + } +} diff --git a/vendor/illuminate/auth/Access/HandlesAuthorization.php b/vendor/illuminate/auth/Access/HandlesAuthorization.php new file mode 100644 index 0000000..148b584 --- /dev/null +++ b/vendor/illuminate/auth/Access/HandlesAuthorization.php @@ -0,0 +1,30 @@ +message = $message; + } + + /** + * Get the response message. + * + * @return string|null + */ + public function message() + { + return $this->message; + } + + /** + * Get the string representation of the message. + * + * @return string + */ + public function __toString() + { + return $this->message(); + } +} diff --git a/vendor/illuminate/auth/Access/UnauthorizedException.php b/vendor/illuminate/auth/Access/UnauthorizedException.php new file mode 100644 index 0000000..7488c5b --- /dev/null +++ b/vendor/illuminate/auth/Access/UnauthorizedException.php @@ -0,0 +1,10 @@ +setCookieJar($this->app['cookie']); + } + + if (method_exists($guard, 'setDispatcher')) { + $guard->setDispatcher($this->app['events']); + } + + if (method_exists($guard, 'setRequest')) { + $guard->setRequest($this->app->refresh('request', $guard, 'setRequest')); + } + + return $guard; + } + + /** + * Call a custom driver creator. + * + * @param string $driver + * @return \Illuminate\Contracts\Auth\Guard + */ + protected function callCustomCreator($driver) + { + $custom = parent::callCustomCreator($driver); + + if ($custom instanceof GuardContract) { + return $custom; + } + + return new Guard($custom, $this->app['session.store']); + } + + /** + * Create an instance of the database driver. + * + * @return \Illuminate\Auth\Guard + */ + public function createDatabaseDriver() + { + $provider = $this->createDatabaseProvider(); + + return new Guard($provider, $this->app['session.store']); + } + + /** + * Create an instance of the database user provider. + * + * @return \Illuminate\Auth\DatabaseUserProvider + */ + protected function createDatabaseProvider() + { + $connection = $this->app['db']->connection(); + + // When using the basic database user provider, we need to inject the table we + // want to use, since this is not an Eloquent model we will have no way to + // know without telling the provider, so we'll inject the config value. + $table = $this->app['config']['auth.table']; + + return new DatabaseUserProvider($connection, $this->app['hash'], $table); + } + + /** + * Create an instance of the Eloquent driver. + * + * @return \Illuminate\Auth\Guard + */ + public function createEloquentDriver() + { + $provider = $this->createEloquentProvider(); + + return new Guard($provider, $this->app['session.store']); + } + + /** + * Create an instance of the Eloquent user provider. + * + * @return \Illuminate\Auth\EloquentUserProvider + */ + protected function createEloquentProvider() + { + $model = $this->app['config']['auth.model']; + + return new EloquentUserProvider($this->app['hash'], $model); + } + + /** + * Get the default authentication driver name. + * + * @return string + */ + public function getDefaultDriver() + { + return $this->app['config']['auth.driver']; + } + + /** + * Set the default authentication driver name. + * + * @param string $name + * @return void + */ + public function setDefaultDriver($name) + { + $this->app['config']['auth.driver'] = $name; + } +} diff --git a/vendor/illuminate/auth/AuthServiceProvider.php b/vendor/illuminate/auth/AuthServiceProvider.php new file mode 100755 index 0000000..0200475 --- /dev/null +++ b/vendor/illuminate/auth/AuthServiceProvider.php @@ -0,0 +1,85 @@ +registerAuthenticator(); + + $this->registerUserResolver(); + + $this->registerAccessGate(); + + $this->registerRequestRebindHandler(); + } + + /** + * Register the authenticator services. + * + * @return void + */ + protected function registerAuthenticator() + { + $this->app->singleton('auth', function ($app) { + // Once the authentication service has actually been requested by the developer + // we will set a variable in the application indicating such. This helps us + // know that we need to set any queued cookies in the after event later. + $app['auth.loaded'] = true; + + return new AuthManager($app); + }); + + $this->app->singleton('auth.driver', function ($app) { + return $app['auth']->driver(); + }); + } + + /** + * Register a resolver for the authenticated user. + * + * @return void + */ + protected function registerUserResolver() + { + $this->app->bind('Illuminate\Contracts\Auth\Authenticatable', function ($app) { + return $app['auth']->user(); + }); + } + + /** + * Register the access gate service. + * + * @return void + */ + protected function registerAccessGate() + { + $this->app->singleton(GateContract::class, function ($app) { + return new Gate($app, function () use ($app) { return $app['auth']->user(); }); + }); + } + + /** + * Register a resolver for the authenticated user. + * + * @return void + */ + protected function registerRequestRebindHandler() + { + $this->app->rebinding('request', function ($app, $request) { + $request->setUserResolver(function () use ($app) { + return $app['auth']->user(); + }); + }); + } +} diff --git a/vendor/illuminate/auth/Authenticatable.php b/vendor/illuminate/auth/Authenticatable.php new file mode 100644 index 0000000..46101d2 --- /dev/null +++ b/vendor/illuminate/auth/Authenticatable.php @@ -0,0 +1,57 @@ +getKey(); + } + + /** + * Get the password for the user. + * + * @return string + */ + public function getAuthPassword() + { + return $this->password; + } + + /** + * Get the token value for the "remember me" session. + * + * @return string + */ + public function getRememberToken() + { + return $this->{$this->getRememberTokenName()}; + } + + /** + * Set the token value for the "remember me" session. + * + * @param string $value + * @return void + */ + public function setRememberToken($value) + { + $this->{$this->getRememberTokenName()} = $value; + } + + /** + * Get the column name for the "remember me" token. + * + * @return string + */ + public function getRememberTokenName() + { + return 'remember_token'; + } +} diff --git a/vendor/illuminate/auth/Console/ClearResetsCommand.php b/vendor/illuminate/auth/Console/ClearResetsCommand.php new file mode 100644 index 0000000..88dcb8c --- /dev/null +++ b/vendor/illuminate/auth/Console/ClearResetsCommand.php @@ -0,0 +1,34 @@ +laravel['auth.password.tokens']->deleteExpired(); + + $this->info('Expired reset tokens cleared!'); + } +} diff --git a/vendor/illuminate/auth/DatabaseUserProvider.php b/vendor/illuminate/auth/DatabaseUserProvider.php new file mode 100755 index 0000000..e23a63f --- /dev/null +++ b/vendor/illuminate/auth/DatabaseUserProvider.php @@ -0,0 +1,146 @@ +conn = $conn; + $this->table = $table; + $this->hasher = $hasher; + } + + /** + * Retrieve a user by their unique identifier. + * + * @param mixed $identifier + * @return \Illuminate\Contracts\Auth\Authenticatable|null + */ + public function retrieveById($identifier) + { + $user = $this->conn->table($this->table)->find($identifier); + + return $this->getGenericUser($user); + } + + /** + * Retrieve a user by their unique identifier and "remember me" token. + * + * @param mixed $identifier + * @param string $token + * @return \Illuminate\Contracts\Auth\Authenticatable|null + */ + public function retrieveByToken($identifier, $token) + { + $user = $this->conn->table($this->table) + ->where('id', $identifier) + ->where('remember_token', $token) + ->first(); + + return $this->getGenericUser($user); + } + + /** + * Update the "remember me" token for the given user in storage. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string $token + * @return void + */ + public function updateRememberToken(UserContract $user, $token) + { + $this->conn->table($this->table) + ->where('id', $user->getAuthIdentifier()) + ->update(['remember_token' => $token]); + } + + /** + * Retrieve a user by the given credentials. + * + * @param array $credentials + * @return \Illuminate\Contracts\Auth\Authenticatable|null + */ + public function retrieveByCredentials(array $credentials) + { + // First we will add each credential element to the query as a where clause. + // Then we can execute the query and, if we found a user, return it in a + // generic "user" object that will be utilized by the Guard instances. + $query = $this->conn->table($this->table); + + foreach ($credentials as $key => $value) { + if (! Str::contains($key, 'password')) { + $query->where($key, $value); + } + } + + // Now we are ready to execute the query to see if we have an user matching + // the given credentials. If not, we will just return nulls and indicate + // that there are no matching users for these given credential arrays. + $user = $query->first(); + + return $this->getGenericUser($user); + } + + /** + * Get the generic user. + * + * @param mixed $user + * @return \Illuminate\Auth\GenericUser|null + */ + protected function getGenericUser($user) + { + if ($user !== null) { + return new GenericUser((array) $user); + } + } + + /** + * Validate a user against the given credentials. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param array $credentials + * @return bool + */ + public function validateCredentials(UserContract $user, array $credentials) + { + $plain = $credentials['password']; + + return $this->hasher->check($plain, $user->getAuthPassword()); + } +} diff --git a/vendor/illuminate/auth/EloquentUserProvider.php b/vendor/illuminate/auth/EloquentUserProvider.php new file mode 100755 index 0000000..e2b6dc7 --- /dev/null +++ b/vendor/illuminate/auth/EloquentUserProvider.php @@ -0,0 +1,174 @@ +model = $model; + $this->hasher = $hasher; + } + + /** + * Retrieve a user by their unique identifier. + * + * @param mixed $identifier + * @return \Illuminate\Contracts\Auth\Authenticatable|null + */ + public function retrieveById($identifier) + { + return $this->createModel()->newQuery()->find($identifier); + } + + /** + * Retrieve a user by their unique identifier and "remember me" token. + * + * @param mixed $identifier + * @param string $token + * @return \Illuminate\Contracts\Auth\Authenticatable|null + */ + public function retrieveByToken($identifier, $token) + { + $model = $this->createModel(); + + return $model->newQuery() + ->where($model->getKeyName(), $identifier) + ->where($model->getRememberTokenName(), $token) + ->first(); + } + + /** + * Update the "remember me" token for the given user in storage. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string $token + * @return void + */ + public function updateRememberToken(UserContract $user, $token) + { + $user->setRememberToken($token); + + $user->save(); + } + + /** + * Retrieve a user by the given credentials. + * + * @param array $credentials + * @return \Illuminate\Contracts\Auth\Authenticatable|null + */ + public function retrieveByCredentials(array $credentials) + { + // First we will add each credential element to the query as a where clause. + // Then we can execute the query and, if we found a user, return it in a + // Eloquent User "model" that will be utilized by the Guard instances. + $query = $this->createModel()->newQuery(); + + foreach ($credentials as $key => $value) { + if (! Str::contains($key, 'password')) { + $query->where($key, $value); + } + } + + return $query->first(); + } + + /** + * Validate a user against the given credentials. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param array $credentials + * @return bool + */ + public function validateCredentials(UserContract $user, array $credentials) + { + $plain = $credentials['password']; + + return $this->hasher->check($plain, $user->getAuthPassword()); + } + + /** + * Create a new instance of the model. + * + * @return \Illuminate\Database\Eloquent\Model + */ + public function createModel() + { + $class = '\\'.ltrim($this->model, '\\'); + + return new $class; + } + + /** + * Gets the hasher implementation. + * + * @return \Illuminate\Contracts\Hashing\Hasher + */ + public function getHasher() + { + return $this->hasher; + } + + /** + * Sets the hasher implementation. + * + * @param \Illuminate\Contracts\Hashing\Hasher $hasher + * @return $this + */ + public function setHasher(HasherContract $hasher) + { + $this->hasher = $hasher; + + return $this; + } + + /** + * Gets the name of the Eloquent user model. + * + * @return string + */ + public function getModel() + { + return $this->model; + } + + /** + * Sets the name of the Eloquent user model. + * + * @param string $model + * @return $this + */ + public function setModel($model) + { + $this->model = $model; + + return $this; + } +} diff --git a/vendor/illuminate/auth/GeneratorServiceProvider.php b/vendor/illuminate/auth/GeneratorServiceProvider.php new file mode 100644 index 0000000..1b9ce10 --- /dev/null +++ b/vendor/illuminate/auth/GeneratorServiceProvider.php @@ -0,0 +1,65 @@ +commands as $command) { + $this->{"register{$command}Command"}(); + } + + $this->commands( + 'command.auth.resets.clear' + ); + } + + /** + * Register the command. + * + * @return void + */ + protected function registerClearResetsCommand() + { + $this->app->singleton('command.auth.resets.clear', function () { + return new ClearResetsCommand; + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'command.auth.resets.clear', + ]; + } +} diff --git a/vendor/illuminate/auth/GenericUser.php b/vendor/illuminate/auth/GenericUser.php new file mode 100755 index 0000000..d349d49 --- /dev/null +++ b/vendor/illuminate/auth/GenericUser.php @@ -0,0 +1,122 @@ +attributes = $attributes; + } + + /** + * Get the unique identifier for the user. + * + * @return mixed + */ + public function getAuthIdentifier() + { + return $this->attributes['id']; + } + + /** + * Get the password for the user. + * + * @return string + */ + public function getAuthPassword() + { + return $this->attributes['password']; + } + + /** + * Get the "remember me" token value. + * + * @return string + */ + public function getRememberToken() + { + return $this->attributes[$this->getRememberTokenName()]; + } + + /** + * Set the "remember me" token value. + * + * @param string $value + * @return void + */ + public function setRememberToken($value) + { + $this->attributes[$this->getRememberTokenName()] = $value; + } + + /** + * Get the column name for the "remember me" token. + * + * @return string + */ + public function getRememberTokenName() + { + return 'remember_token'; + } + + /** + * Dynamically access the user's attributes. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + return $this->attributes[$key]; + } + + /** + * Dynamically set an attribute on the user. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function __set($key, $value) + { + $this->attributes[$key] = $value; + } + + /** + * Dynamically check if a value is set on the user. + * + * @param string $key + * @return bool + */ + public function __isset($key) + { + return isset($this->attributes[$key]); + } + + /** + * Dynamically unset a value on the user. + * + * @param string $key + * @return void + */ + public function __unset($key) + { + unset($this->attributes[$key]); + } +} diff --git a/vendor/illuminate/auth/Guard.php b/vendor/illuminate/auth/Guard.php new file mode 100755 index 0000000..5caec98 --- /dev/null +++ b/vendor/illuminate/auth/Guard.php @@ -0,0 +1,769 @@ +session = $session; + $this->request = $request; + $this->provider = $provider; + } + + /** + * Determine if the current user is authenticated. + * + * @return bool + */ + public function check() + { + return ! is_null($this->user()); + } + + /** + * Determine if the current user is a guest. + * + * @return bool + */ + public function guest() + { + return ! $this->check(); + } + + /** + * Get the currently authenticated user. + * + * @return \Illuminate\Contracts\Auth\Authenticatable|null + */ + public function user() + { + if ($this->loggedOut) { + return; + } + + // If we've already retrieved the user for the current request we can just + // return it back immediately. We do not want to fetch the user data on + // every call to this method because that would be tremendously slow. + if (! is_null($this->user)) { + return $this->user; + } + + $id = $this->session->get($this->getName()); + + // First we will try to load the user using the identifier in the session if + // one exists. Otherwise we will check for a "remember me" cookie in this + // request, and if one exists, attempt to retrieve the user using that. + $user = null; + + if (! is_null($id)) { + $user = $this->provider->retrieveById($id); + } + + // If the user is null, but we decrypt a "recaller" cookie we can attempt to + // pull the user data on that cookie which serves as a remember cookie on + // the application. Once we have a user we can return it to the caller. + $recaller = $this->getRecaller(); + + if (is_null($user) && ! is_null($recaller)) { + $user = $this->getUserByRecaller($recaller); + + if ($user) { + $this->updateSession($user->getAuthIdentifier()); + + $this->fireLoginEvent($user, true); + } + } + + return $this->user = $user; + } + + /** + * Get the ID for the currently authenticated user. + * + * @return int|null + */ + public function id() + { + if ($this->loggedOut) { + return; + } + + $id = $this->session->get($this->getName(), $this->getRecallerId()); + + if (is_null($id) && $this->user()) { + $id = $this->user()->getAuthIdentifier(); + } + + return $id; + } + + /** + * Pull a user from the repository by its recaller ID. + * + * @param string $recaller + * @return mixed + */ + protected function getUserByRecaller($recaller) + { + if ($this->validRecaller($recaller) && ! $this->tokenRetrievalAttempted) { + $this->tokenRetrievalAttempted = true; + + list($id, $token) = explode('|', $recaller, 2); + + $this->viaRemember = ! is_null($user = $this->provider->retrieveByToken($id, $token)); + + return $user; + } + } + + /** + * Get the decrypted recaller cookie for the request. + * + * @return string|null + */ + protected function getRecaller() + { + return $this->request->cookies->get($this->getRecallerName()); + } + + /** + * Get the user ID from the recaller cookie. + * + * @return string|null + */ + protected function getRecallerId() + { + if ($this->validRecaller($recaller = $this->getRecaller())) { + return head(explode('|', $recaller)); + } + } + + /** + * Determine if the recaller cookie is in a valid format. + * + * @param string $recaller + * @return bool + */ + protected function validRecaller($recaller) + { + if (! is_string($recaller) || ! Str::contains($recaller, '|')) { + return false; + } + + $segments = explode('|', $recaller); + + return count($segments) == 2 && trim($segments[0]) !== '' && trim($segments[1]) !== ''; + } + + /** + * Log a user into the application without sessions or cookies. + * + * @param array $credentials + * @return bool + */ + public function once(array $credentials = []) + { + if ($this->validate($credentials)) { + $this->setUser($this->lastAttempted); + + return true; + } + + return false; + } + + /** + * Validate a user's credentials. + * + * @param array $credentials + * @return bool + */ + public function validate(array $credentials = []) + { + return $this->attempt($credentials, false, false); + } + + /** + * Attempt to authenticate using HTTP Basic Auth. + * + * @param string $field + * @return \Symfony\Component\HttpFoundation\Response|null + */ + public function basic($field = 'email') + { + if ($this->check()) { + return; + } + + // If a username is set on the HTTP basic request, we will return out without + // interrupting the request lifecycle. Otherwise, we'll need to generate a + // request indicating that the given credentials were invalid for login. + if ($this->attemptBasic($this->getRequest(), $field)) { + return; + } + + return $this->getBasicResponse(); + } + + /** + * Perform a stateless HTTP Basic login attempt. + * + * @param string $field + * @return \Symfony\Component\HttpFoundation\Response|null + */ + public function onceBasic($field = 'email') + { + if (! $this->once($this->getBasicCredentials($this->getRequest(), $field))) { + return $this->getBasicResponse(); + } + } + + /** + * Attempt to authenticate using basic authentication. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * @param string $field + * @return bool + */ + protected function attemptBasic(Request $request, $field) + { + if (! $request->getUser()) { + return false; + } + + return $this->attempt($this->getBasicCredentials($request, $field)); + } + + /** + * Get the credential array for a HTTP Basic request. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * @param string $field + * @return array + */ + protected function getBasicCredentials(Request $request, $field) + { + return [$field => $request->getUser(), 'password' => $request->getPassword()]; + } + + /** + * Get the response for basic authentication. + * + * @return \Symfony\Component\HttpFoundation\Response + */ + protected function getBasicResponse() + { + $headers = ['WWW-Authenticate' => 'Basic']; + + return new Response('Invalid credentials.', 401, $headers); + } + + /** + * Attempt to authenticate a user using the given credentials. + * + * @param array $credentials + * @param bool $remember + * @param bool $login + * @return bool + */ + public function attempt(array $credentials = [], $remember = false, $login = true) + { + $this->fireAttemptEvent($credentials, $remember, $login); + + $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials); + + // If an implementation of UserInterface was returned, we'll ask the provider + // to validate the user against the given credentials, and if they are in + // fact valid we'll log the users into the application and return true. + if ($this->hasValidCredentials($user, $credentials)) { + if ($login) { + $this->login($user, $remember); + } + + return true; + } + + return false; + } + + /** + * Determine if the user matches the credentials. + * + * @param mixed $user + * @param array $credentials + * @return bool + */ + protected function hasValidCredentials($user, $credentials) + { + return ! is_null($user) && $this->provider->validateCredentials($user, $credentials); + } + + /** + * Fire the attempt event with the arguments. + * + * @param array $credentials + * @param bool $remember + * @param bool $login + * @return void + */ + protected function fireAttemptEvent(array $credentials, $remember, $login) + { + if ($this->events) { + $payload = [$credentials, $remember, $login]; + + $this->events->fire('auth.attempt', $payload); + } + } + + /** + * Register an authentication attempt event listener. + * + * @param mixed $callback + * @return void + */ + public function attempting($callback) + { + if ($this->events) { + $this->events->listen('auth.attempt', $callback); + } + } + + /** + * Log a user into the application. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param bool $remember + * @return void + */ + public function login(UserContract $user, $remember = false) + { + $this->updateSession($user->getAuthIdentifier()); + + // If the user should be permanently "remembered" by the application we will + // queue a permanent cookie that contains the encrypted copy of the user + // identifier. We will then decrypt this later to retrieve the users. + if ($remember) { + $this->createRememberTokenIfDoesntExist($user); + + $this->queueRecallerCookie($user); + } + + // If we have an event dispatcher instance set we will fire an event so that + // any listeners will hook into the authentication events and run actions + // based on the login and logout events fired from the guard instances. + $this->fireLoginEvent($user, $remember); + + $this->setUser($user); + } + + /** + * Fire the login event if the dispatcher is set. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param bool $remember + * @return void + */ + protected function fireLoginEvent($user, $remember = false) + { + if (isset($this->events)) { + $this->events->fire('auth.login', [$user, $remember]); + } + } + + /** + * Update the session with the given ID. + * + * @param string $id + * @return void + */ + protected function updateSession($id) + { + $this->session->set($this->getName(), $id); + + $this->session->migrate(true); + } + + /** + * Log the given user ID into the application. + * + * @param mixed $id + * @param bool $remember + * @return \Illuminate\Contracts\Auth\Authenticatable + */ + public function loginUsingId($id, $remember = false) + { + $this->session->set($this->getName(), $id); + + $this->login($user = $this->provider->retrieveById($id), $remember); + + return $user; + } + + /** + * Log the given user ID into the application without sessions or cookies. + * + * @param mixed $id + * @return bool + */ + public function onceUsingId($id) + { + if (! is_null($user = $this->provider->retrieveById($id))) { + $this->setUser($user); + + return true; + } + + return false; + } + + /** + * Queue the recaller cookie into the cookie jar. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @return void + */ + protected function queueRecallerCookie(UserContract $user) + { + $value = $user->getAuthIdentifier().'|'.$user->getRememberToken(); + + $this->getCookieJar()->queue($this->createRecaller($value)); + } + + /** + * Create a "remember me" cookie for a given ID. + * + * @param string $value + * @return \Symfony\Component\HttpFoundation\Cookie + */ + protected function createRecaller($value) + { + return $this->getCookieJar()->forever($this->getRecallerName(), $value); + } + + /** + * Log the user out of the application. + * + * @return void + */ + public function logout() + { + $user = $this->user(); + + // If we have an event dispatcher instance, we can fire off the logout event + // so any further processing can be done. This allows the developer to be + // listening for anytime a user signs out of this application manually. + $this->clearUserDataFromStorage(); + + if (! is_null($this->user)) { + $this->refreshRememberToken($user); + } + + if (isset($this->events)) { + $this->events->fire('auth.logout', [$user]); + } + + // Once we have fired the logout event we will clear the users out of memory + // so they are no longer available as the user is no longer considered as + // being signed into this application and should not be available here. + $this->user = null; + + $this->loggedOut = true; + } + + /** + * Remove the user data from the session and cookies. + * + * @return void + */ + protected function clearUserDataFromStorage() + { + $this->session->remove($this->getName()); + + $recaller = $this->getRecallerName(); + + $this->getCookieJar()->queue($this->getCookieJar()->forget($recaller)); + } + + /** + * Refresh the "remember me" token for the user. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @return void + */ + protected function refreshRememberToken(UserContract $user) + { + $user->setRememberToken($token = Str::random(60)); + + $this->provider->updateRememberToken($user, $token); + } + + /** + * Create a new "remember me" token for the user if one doesn't already exist. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @return void + */ + protected function createRememberTokenIfDoesntExist(UserContract $user) + { + if (empty($user->getRememberToken())) { + $this->refreshRememberToken($user); + } + } + + /** + * Get the cookie creator instance used by the guard. + * + * @return \Illuminate\Contracts\Cookie\QueueingFactory + * + * @throws \RuntimeException + */ + public function getCookieJar() + { + if (! isset($this->cookie)) { + throw new RuntimeException('Cookie jar has not been set.'); + } + + return $this->cookie; + } + + /** + * Set the cookie creator instance used by the guard. + * + * @param \Illuminate\Contracts\Cookie\QueueingFactory $cookie + * @return void + */ + public function setCookieJar(CookieJar $cookie) + { + $this->cookie = $cookie; + } + + /** + * Get the event dispatcher instance. + * + * @return \Illuminate\Contracts\Events\Dispatcher + */ + public function getDispatcher() + { + return $this->events; + } + + /** + * Set the event dispatcher instance. + * + * @param \Illuminate\Contracts\Events\Dispatcher $events + * @return void + */ + public function setDispatcher(Dispatcher $events) + { + $this->events = $events; + } + + /** + * Get the session store used by the guard. + * + * @return \Illuminate\Session\Store + */ + public function getSession() + { + return $this->session; + } + + /** + * Get the user provider used by the guard. + * + * @return \Illuminate\Contracts\Auth\UserProvider + */ + public function getProvider() + { + return $this->provider; + } + + /** + * Set the user provider used by the guard. + * + * @param \Illuminate\Contracts\Auth\UserProvider $provider + * @return void + */ + public function setProvider(UserProvider $provider) + { + $this->provider = $provider; + } + + /** + * Return the currently cached user. + * + * @return \Illuminate\Contracts\Auth\Authenticatable|null + */ + public function getUser() + { + return $this->user; + } + + /** + * Set the current user. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @return void + */ + public function setUser(UserContract $user) + { + $this->user = $user; + + $this->loggedOut = false; + } + + /** + * Get the current request instance. + * + * @return \Symfony\Component\HttpFoundation\Request + */ + public function getRequest() + { + return $this->request ?: Request::createFromGlobals(); + } + + /** + * Set the current request instance. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * @return $this + */ + public function setRequest(Request $request) + { + $this->request = $request; + + return $this; + } + + /** + * Get the last user we attempted to authenticate. + * + * @return \Illuminate\Contracts\Auth\Authenticatable + */ + public function getLastAttempted() + { + return $this->lastAttempted; + } + + /** + * Get a unique identifier for the auth session value. + * + * @return string + */ + public function getName() + { + return 'login_'.md5(get_class($this)); + } + + /** + * Get the name of the cookie used to store the "recaller". + * + * @return string + */ + public function getRecallerName() + { + return 'remember_'.md5(get_class($this)); + } + + /** + * Determine if the user was authenticated via "remember me" cookie. + * + * @return bool + */ + public function viaRemember() + { + return $this->viaRemember; + } +} diff --git a/vendor/illuminate/auth/Middleware/AuthenticateWithBasicAuth.php b/vendor/illuminate/auth/Middleware/AuthenticateWithBasicAuth.php new file mode 100644 index 0000000..a2418b3 --- /dev/null +++ b/vendor/illuminate/auth/Middleware/AuthenticateWithBasicAuth.php @@ -0,0 +1,39 @@ +auth = $auth; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + return $this->auth->basic() ?: $next($request); + } +} diff --git a/vendor/illuminate/auth/Passwords/CanResetPassword.php b/vendor/illuminate/auth/Passwords/CanResetPassword.php new file mode 100644 index 0000000..d5d8e16 --- /dev/null +++ b/vendor/illuminate/auth/Passwords/CanResetPassword.php @@ -0,0 +1,16 @@ +email; + } +} diff --git a/vendor/illuminate/auth/Passwords/DatabaseTokenRepository.php b/vendor/illuminate/auth/Passwords/DatabaseTokenRepository.php new file mode 100755 index 0000000..db93cf9 --- /dev/null +++ b/vendor/illuminate/auth/Passwords/DatabaseTokenRepository.php @@ -0,0 +1,193 @@ +table = $table; + $this->hashKey = $hashKey; + $this->expires = $expires * 60; + $this->connection = $connection; + } + + /** + * Create a new token record. + * + * @param \Illuminate\Contracts\Auth\CanResetPassword $user + * @return string + */ + public function create(CanResetPasswordContract $user) + { + $email = $user->getEmailForPasswordReset(); + + $this->deleteExisting($user); + + // We will create a new, random token for the user so that we can e-mail them + // a safe link to the password reset form. Then we will insert a record in + // the database so that we can verify the token within the actual reset. + $token = $this->createNewToken(); + + $this->getTable()->insert($this->getPayload($email, $token)); + + return $token; + } + + /** + * Delete all existing reset tokens from the database. + * + * @param \Illuminate\Contracts\Auth\CanResetPassword $user + * @return int + */ + protected function deleteExisting(CanResetPasswordContract $user) + { + return $this->getTable()->where('email', $user->getEmailForPasswordReset())->delete(); + } + + /** + * Build the record payload for the table. + * + * @param string $email + * @param string $token + * @return array + */ + protected function getPayload($email, $token) + { + return ['email' => $email, 'token' => $token, 'created_at' => new Carbon]; + } + + /** + * Determine if a token record exists and is valid. + * + * @param \Illuminate\Contracts\Auth\CanResetPassword $user + * @param string $token + * @return bool + */ + public function exists(CanResetPasswordContract $user, $token) + { + $email = $user->getEmailForPasswordReset(); + + $token = (array) $this->getTable()->where('email', $email)->where('token', $token)->first(); + + return $token && ! $this->tokenExpired($token); + } + + /** + * Determine if the token has expired. + * + * @param array $token + * @return bool + */ + protected function tokenExpired($token) + { + $expirationTime = strtotime($token['created_at']) + $this->expires; + + return $expirationTime < $this->getCurrentTime(); + } + + /** + * Get the current UNIX timestamp. + * + * @return int + */ + protected function getCurrentTime() + { + return time(); + } + + /** + * Delete a token record by token. + * + * @param string $token + * @return void + */ + public function delete($token) + { + $this->getTable()->where('token', $token)->delete(); + } + + /** + * Delete expired tokens. + * + * @return void + */ + public function deleteExpired() + { + $expiredAt = Carbon::now()->subSeconds($this->expires); + + $this->getTable()->where('created_at', '<', $expiredAt)->delete(); + } + + /** + * Create a new token for the user. + * + * @return string + */ + public function createNewToken() + { + return hash_hmac('sha256', Str::random(40), $this->hashKey); + } + + /** + * Begin a new database query against the table. + * + * @return \Illuminate\Database\Query\Builder + */ + protected function getTable() + { + return $this->connection->table($this->table); + } + + /** + * Get the database connection instance. + * + * @return \Illuminate\Database\ConnectionInterface + */ + public function getConnection() + { + return $this->connection; + } +} diff --git a/vendor/illuminate/auth/Passwords/PasswordBroker.php b/vendor/illuminate/auth/Passwords/PasswordBroker.php new file mode 100755 index 0000000..9fe8e76 --- /dev/null +++ b/vendor/illuminate/auth/Passwords/PasswordBroker.php @@ -0,0 +1,252 @@ +users = $users; + $this->mailer = $mailer; + $this->tokens = $tokens; + $this->emailView = $emailView; + } + + /** + * Send a password reset link to a user. + * + * @param array $credentials + * @param \Closure|null $callback + * @return string + */ + public function sendResetLink(array $credentials, Closure $callback = null) + { + // First we will check to see if we found a user at the given credentials and + // if we did not we will redirect back to this current URI with a piece of + // "flash" data in the session to indicate to the developers the errors. + $user = $this->getUser($credentials); + + if (is_null($user)) { + return PasswordBrokerContract::INVALID_USER; + } + + // Once we have the reset token, we are ready to send the message out to this + // user with a link to reset their password. We will then redirect back to + // the current URI having nothing set in the session to indicate errors. + $token = $this->tokens->create($user); + + $this->emailResetLink($user, $token, $callback); + + return PasswordBrokerContract::RESET_LINK_SENT; + } + + /** + * Send the password reset link via e-mail. + * + * @param \Illuminate\Contracts\Auth\CanResetPassword $user + * @param string $token + * @param \Closure|null $callback + * @return int + */ + public function emailResetLink(CanResetPasswordContract $user, $token, Closure $callback = null) + { + // We will use the reminder view that was given to the broker to display the + // password reminder e-mail. We'll pass a "token" variable into the views + // so that it may be displayed for an user to click for password reset. + $view = $this->emailView; + + return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) { + $m->to($user->getEmailForPasswordReset()); + + if (! is_null($callback)) { + call_user_func($callback, $m, $user, $token); + } + }); + } + + /** + * Reset the password for the given token. + * + * @param array $credentials + * @param \Closure $callback + * @return mixed + */ + public function reset(array $credentials, Closure $callback) + { + // If the responses from the validate method is not a user instance, we will + // assume that it is a redirect and simply return it from this method and + // the user is properly redirected having an error message on the post. + $user = $this->validateReset($credentials); + + if (! $user instanceof CanResetPasswordContract) { + return $user; + } + + $pass = $credentials['password']; + + // Once we have called this callback, we will remove this token row from the + // table and return the response from this callback so the user gets sent + // to the destination given by the developers from the callback return. + call_user_func($callback, $user, $pass); + + $this->tokens->delete($credentials['token']); + + return PasswordBrokerContract::PASSWORD_RESET; + } + + /** + * Validate a password reset for the given credentials. + * + * @param array $credentials + * @return \Illuminate\Contracts\Auth\CanResetPassword + */ + protected function validateReset(array $credentials) + { + if (is_null($user = $this->getUser($credentials))) { + return PasswordBrokerContract::INVALID_USER; + } + + if (! $this->validateNewPassword($credentials)) { + return PasswordBrokerContract::INVALID_PASSWORD; + } + + if (! $this->tokens->exists($user, $credentials['token'])) { + return PasswordBrokerContract::INVALID_TOKEN; + } + + return $user; + } + + /** + * Set a custom password validator. + * + * @param \Closure $callback + * @return void + */ + public function validator(Closure $callback) + { + $this->passwordValidator = $callback; + } + + /** + * Determine if the passwords match for the request. + * + * @param array $credentials + * @return bool + */ + public function validateNewPassword(array $credentials) + { + list($password, $confirm) = [ + $credentials['password'], + $credentials['password_confirmation'], + ]; + + if (isset($this->passwordValidator)) { + return call_user_func( + $this->passwordValidator, $credentials) && $password === $confirm; + } + + return $this->validatePasswordWithDefaults($credentials); + } + + /** + * Determine if the passwords are valid for the request. + * + * @param array $credentials + * @return bool + */ + protected function validatePasswordWithDefaults(array $credentials) + { + list($password, $confirm) = [ + $credentials['password'], + $credentials['password_confirmation'], + ]; + + return $password === $confirm && mb_strlen($password) >= 6; + } + + /** + * Get the user for the given credentials. + * + * @param array $credentials + * @return \Illuminate\Contracts\Auth\CanResetPassword + * + * @throws \UnexpectedValueException + */ + public function getUser(array $credentials) + { + $credentials = array_except($credentials, ['token']); + + $user = $this->users->retrieveByCredentials($credentials); + + if ($user && ! $user instanceof CanResetPasswordContract) { + throw new UnexpectedValueException('User must implement CanResetPassword interface.'); + } + + return $user; + } + + /** + * Get the password reset token repository implementation. + * + * @return \Illuminate\Auth\Passwords\TokenRepositoryInterface + */ + protected function getRepository() + { + return $this->tokens; + } +} diff --git a/vendor/illuminate/auth/Passwords/PasswordResetServiceProvider.php b/vendor/illuminate/auth/Passwords/PasswordResetServiceProvider.php new file mode 100755 index 0000000..2da8f7d --- /dev/null +++ b/vendor/illuminate/auth/Passwords/PasswordResetServiceProvider.php @@ -0,0 +1,87 @@ +registerPasswordBroker(); + + $this->registerTokenRepository(); + } + + /** + * Register the password broker instance. + * + * @return void + */ + protected function registerPasswordBroker() + { + $this->app->singleton('auth.password', function ($app) { + // The password token repository is responsible for storing the email addresses + // and password reset tokens. It will be used to verify the tokens are valid + // for the given e-mail addresses. We will resolve an implementation here. + $tokens = $app['auth.password.tokens']; + + $users = $app['auth']->driver()->getProvider(); + + $view = $app['config']['auth.password.email']; + + // The password broker uses a token repository to validate tokens and send user + // password e-mails, as well as validating that password reset process as an + // aggregate service of sorts providing a convenient interface for resets. + return new PasswordBroker( + $tokens, $users, $app['mailer'], $view + ); + }); + } + + /** + * Register the token repository implementation. + * + * @return void + */ + protected function registerTokenRepository() + { + $this->app->singleton('auth.password.tokens', function ($app) { + $connection = $app['db']->connection(); + + // The database token repository is an implementation of the token repository + // interface, and is responsible for the actual storing of auth tokens and + // their e-mail addresses. We will inject this table and hash key to it. + $table = $app['config']['auth.password.table']; + + $key = $app['config']['app.key']; + + $expire = $app['config']->get('auth.password.expire', 60); + + return new DbRepository($connection, $table, $key, $expire); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return ['auth.password', 'auth.password.tokens']; + } +} diff --git a/vendor/illuminate/auth/Passwords/TokenRepositoryInterface.php b/vendor/illuminate/auth/Passwords/TokenRepositoryInterface.php new file mode 100755 index 0000000..0570773 --- /dev/null +++ b/vendor/illuminate/auth/Passwords/TokenRepositoryInterface.php @@ -0,0 +1,40 @@ +=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/http": "5.1.*", + "illuminate/session": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19" + }, + "autoload": { + "psr-4": { + "Illuminate\\Auth\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "illuminate/console": "Required to use the auth:clear-resets command (5.1.*)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/broadcasting/BroadcastEvent.php b/vendor/illuminate/broadcasting/BroadcastEvent.php new file mode 100644 index 0000000..1b6bad9 --- /dev/null +++ b/vendor/illuminate/broadcasting/BroadcastEvent.php @@ -0,0 +1,87 @@ +broadcaster = $broadcaster; + } + + /** + * Handle the queued job. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @param array $data + * @return void + */ + public function fire(Job $job, array $data) + { + $event = unserialize($data['event']); + + $name = method_exists($event, 'broadcastAs') + ? $event->broadcastAs() : get_class($event); + + $this->broadcaster->broadcast( + $event->broadcastOn(), $name, $this->getPayloadFromEvent($event) + ); + + $job->delete(); + } + + /** + * Get the payload for the given event. + * + * @param mixed $event + * @return array + */ + protected function getPayloadFromEvent($event) + { + if (method_exists($event, 'broadcastWith')) { + return $event->broadcastWith(); + } + + $payload = []; + + foreach ((new ReflectionClass($event))->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { + $payload[$property->getName()] = $this->formatProperty($property->getValue($event)); + } + + return $payload; + } + + /** + * Format the given value for a property. + * + * @param mixed $value + * @return mixed + */ + protected function formatProperty($value) + { + if ($value instanceof Arrayable) { + return $value->toArray(); + } + + return $value; + } +} diff --git a/vendor/illuminate/broadcasting/BroadcastManager.php b/vendor/illuminate/broadcasting/BroadcastManager.php new file mode 100644 index 0000000..8f81d58 --- /dev/null +++ b/vendor/illuminate/broadcasting/BroadcastManager.php @@ -0,0 +1,211 @@ +app = $app; + } + + /** + * Get a driver instance. + * + * @param string $driver + * @return mixed + */ + public function connection($driver = null) + { + return $this->driver($driver); + } + + /** + * Get a driver instance. + * + * @param string $name + * @return mixed + */ + public function driver($name = null) + { + $name = $name ?: $this->getDefaultDriver(); + + return $this->drivers[$name] = $this->get($name); + } + + /** + * Attempt to get the connection from the local cache. + * + * @param string $name + * @return \Illuminate\Contracts\Broadcasting\Broadcaster + */ + protected function get($name) + { + return isset($this->drivers[$name]) ? $this->drivers[$name] : $this->resolve($name); + } + + /** + * Resolve the given store. + * + * @param string $name + * @return \Illuminate\Contracts\Broadcasting\Broadcaster + */ + protected function resolve($name) + { + $config = $this->getConfig($name); + + if (is_null($config)) { + throw new InvalidArgumentException("Broadcaster [{$name}] is not defined."); + } + + if (isset($this->customCreators[$config['driver']])) { + return $this->callCustomCreator($config); + } else { + return $this->{'create'.ucfirst($config['driver']).'Driver'}($config); + } + } + + /** + * Call a custom driver creator. + * + * @param array $config + * @return mixed + */ + protected function callCustomCreator(array $config) + { + return $this->customCreators[$config['driver']]($this->app, $config); + } + + /** + * Create an instance of the driver. + * + * @param array $config + * @return \Illuminate\Contracts\Broadcasting\Broadcaster + */ + protected function createPusherDriver(array $config) + { + return new PusherBroadcaster( + new Pusher($config['key'], $config['secret'], $config['app_id'], array_get($config, 'options', [])) + ); + } + + /** + * Create an instance of the driver. + * + * @param array $config + * @return \Illuminate\Contracts\Broadcasting\Broadcaster + */ + protected function createRedisDriver(array $config) + { + return new RedisBroadcaster( + $this->app->make('redis'), Arr::get($config, 'connection') + ); + } + + /** + * Create an instance of the driver. + * + * @param array $config + * @return \Illuminate\Contracts\Broadcasting\Broadcaster + */ + protected function createLogDriver(array $config) + { + return new LogBroadcaster( + $this->app->make('Psr\Log\LoggerInterface') + ); + } + + /** + * Get the connection configuration. + * + * @param string $name + * @return array + */ + protected function getConfig($name) + { + return $this->app['config']["broadcasting.connections.{$name}"]; + } + + /** + * Get the default driver name. + * + * @return string + */ + public function getDefaultDriver() + { + return $this->app['config']['broadcasting.default']; + } + + /** + * Set the default driver name. + * + * @param string $name + * @return void + */ + public function setDefaultDriver($name) + { + $this->app['config']['broadcasting.default'] = $name; + } + + /** + * Register a custom driver creator Closure. + * + * @param string $driver + * @param \Closure $callback + * @return $this + */ + public function extend($driver, Closure $callback) + { + $this->customCreators[$driver] = $callback; + + return $this; + } + + /** + * Dynamically call the default driver instance. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->driver(), $method], $parameters); + } +} diff --git a/vendor/illuminate/broadcasting/BroadcastServiceProvider.php b/vendor/illuminate/broadcasting/BroadcastServiceProvider.php new file mode 100644 index 0000000..c6f14fe --- /dev/null +++ b/vendor/illuminate/broadcasting/BroadcastServiceProvider.php @@ -0,0 +1,49 @@ +app->singleton('Illuminate\Broadcasting\BroadcastManager', function ($app) { + return new BroadcastManager($app); + }); + + $this->app->singleton('Illuminate\Contracts\Broadcasting\Broadcaster', function ($app) { + return $app->make('Illuminate\Broadcasting\BroadcastManager')->connection(); + }); + + $this->app->alias( + 'Illuminate\Broadcasting\BroadcastManager', 'Illuminate\Contracts\Broadcasting\Factory' + ); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'Illuminate\Broadcasting\BroadcastManager', + 'Illuminate\Contracts\Broadcasting\Factory', + 'Illuminate\Contracts\Broadcasting\Broadcaster', + ]; + } +} diff --git a/vendor/illuminate/broadcasting/Broadcasters/LogBroadcaster.php b/vendor/illuminate/broadcasting/Broadcasters/LogBroadcaster.php new file mode 100644 index 0000000..6b90492 --- /dev/null +++ b/vendor/illuminate/broadcasting/Broadcasters/LogBroadcaster.php @@ -0,0 +1,39 @@ +logger = $logger; + } + + /** + * {@inheritdoc} + */ + public function broadcast(array $channels, $event, array $payload = []) + { + $channels = implode(', ', $channels); + + $payload = json_encode($payload, JSON_PRETTY_PRINT); + + $this->logger->info('Broadcasting ['.$event.'] on channels ['.$channels.'] with payload:'.PHP_EOL.$payload); + } +} diff --git a/vendor/illuminate/broadcasting/Broadcasters/PusherBroadcaster.php b/vendor/illuminate/broadcasting/Broadcasters/PusherBroadcaster.php new file mode 100644 index 0000000..5ce83de --- /dev/null +++ b/vendor/illuminate/broadcasting/Broadcasters/PusherBroadcaster.php @@ -0,0 +1,35 @@ +pusher = $pusher; + } + + /** + * {@inheritdoc} + */ + public function broadcast(array $channels, $event, array $payload = []) + { + $this->pusher->trigger($channels, $event, $payload); + } +} diff --git a/vendor/illuminate/broadcasting/Broadcasters/RedisBroadcaster.php b/vendor/illuminate/broadcasting/Broadcasters/RedisBroadcaster.php new file mode 100644 index 0000000..91c7c61 --- /dev/null +++ b/vendor/illuminate/broadcasting/Broadcasters/RedisBroadcaster.php @@ -0,0 +1,50 @@ +redis = $redis; + $this->connection = $connection; + } + + /** + * {@inheritdoc} + */ + public function broadcast(array $channels, $event, array $payload = []) + { + $connection = $this->redis->connection($this->connection); + + $payload = json_encode(['event' => $event, 'data' => $payload]); + + foreach ($channels as $channel) { + $connection->publish($channel, $payload); + } + } +} diff --git a/vendor/illuminate/broadcasting/composer.json b/vendor/illuminate/broadcasting/composer.json new file mode 100644 index 0000000..c3e89d1 --- /dev/null +++ b/vendor/illuminate/broadcasting/composer.json @@ -0,0 +1,35 @@ +{ + "name": "illuminate/broadcasting", + "description": "The Illuminate Broadcasting package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Broadcasting\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/bus/BusServiceProvider.php b/vendor/illuminate/bus/BusServiceProvider.php new file mode 100644 index 0000000..55eeb2a --- /dev/null +++ b/vendor/illuminate/bus/BusServiceProvider.php @@ -0,0 +1,51 @@ +app->singleton('Illuminate\Bus\Dispatcher', function ($app) { + return new Dispatcher($app, function () use ($app) { + return $app['Illuminate\Contracts\Queue\Queue']; + }); + }); + + $this->app->alias( + 'Illuminate\Bus\Dispatcher', 'Illuminate\Contracts\Bus\Dispatcher' + ); + + $this->app->alias( + 'Illuminate\Bus\Dispatcher', 'Illuminate\Contracts\Bus\QueueingDispatcher' + ); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'Illuminate\Bus\Dispatcher', + 'Illuminate\Contracts\Bus\Dispatcher', + 'Illuminate\Contracts\Bus\QueueingDispatcher', + ]; + } +} diff --git a/vendor/illuminate/bus/Dispatcher.php b/vendor/illuminate/bus/Dispatcher.php new file mode 100644 index 0000000..2e10d72 --- /dev/null +++ b/vendor/illuminate/bus/Dispatcher.php @@ -0,0 +1,410 @@ +container = $container; + $this->queueResolver = $queueResolver; + $this->pipeline = new Pipeline($container); + } + + /** + * Marshal a command and dispatch it to its appropriate handler. + * + * @param mixed $command + * @param array $array + * @return mixed + */ + public function dispatchFromArray($command, array $array) + { + return $this->dispatch($this->marshalFromArray($command, $array)); + } + + /** + * Marshal a command and dispatch it to its appropriate handler. + * + * @param mixed $command + * @param \ArrayAccess $source + * @param array $extras + * @return mixed + */ + public function dispatchFrom($command, ArrayAccess $source, array $extras = []) + { + return $this->dispatch($this->marshal($command, $source, $extras)); + } + + /** + * Marshal a command from the given array. + * + * @param string $command + * @param array $array + * @return mixed + */ + protected function marshalFromArray($command, array $array) + { + return $this->marshal($command, new Collection, $array); + } + + /** + * Marshal a command from the given array accessible object. + * + * @param string $command + * @param \ArrayAccess $source + * @param array $extras + * @return mixed + */ + protected function marshal($command, ArrayAccess $source, array $extras = []) + { + $injected = []; + + $reflection = new ReflectionClass($command); + + if ($constructor = $reflection->getConstructor()) { + $injected = array_map(function ($parameter) use ($command, $source, $extras) { + return $this->getParameterValueForCommand($command, $source, $parameter, $extras); + }, $constructor->getParameters()); + } + + return $reflection->newInstanceArgs($injected); + } + + /** + * Get a parameter value for a marshaled command. + * + * @param string $command + * @param \ArrayAccess $source + * @param \ReflectionParameter $parameter + * @param array $extras + * @return mixed + */ + protected function getParameterValueForCommand($command, ArrayAccess $source, + ReflectionParameter $parameter, array $extras = []) + { + if (array_key_exists($parameter->name, $extras)) { + return $extras[$parameter->name]; + } + + if (isset($source[$parameter->name])) { + return $source[$parameter->name]; + } + + if ($parameter->isDefaultValueAvailable()) { + return $parameter->getDefaultValue(); + } + + MarshalException::whileMapping($command, $parameter); + } + + /** + * Dispatch a command to its appropriate handler. + * + * @param mixed $command + * @param \Closure|null $afterResolving + * @return mixed + */ + public function dispatch($command, Closure $afterResolving = null) + { + if ($this->queueResolver && $this->commandShouldBeQueued($command)) { + return $this->dispatchToQueue($command); + } else { + return $this->dispatchNow($command, $afterResolving); + } + } + + /** + * Dispatch a command to its appropriate handler in the current process. + * + * @param mixed $command + * @param \Closure|null $afterResolving + * @return mixed + */ + public function dispatchNow($command, Closure $afterResolving = null) + { + return $this->pipeline->send($command)->through($this->pipes)->then(function ($command) use ($afterResolving) { + if ($command instanceof SelfHandling) { + return $this->container->call([$command, 'handle']); + } + + $handler = $this->resolveHandler($command); + + if ($afterResolving) { + call_user_func($afterResolving, $handler); + } + + return call_user_func( + [$handler, $this->getHandlerMethod($command)], $command + ); + }); + } + + /** + * Determine if the given command should be queued. + * + * @param mixed $command + * @return bool + */ + protected function commandShouldBeQueued($command) + { + if ($command instanceof ShouldQueue) { + return true; + } + + return (new ReflectionClass($this->getHandlerClass($command)))->implementsInterface( + 'Illuminate\Contracts\Queue\ShouldQueue' + ); + } + + /** + * Dispatch a command to its appropriate handler behind a queue. + * + * @param mixed $command + * @return mixed + * + * @throws \RuntimeException + */ + public function dispatchToQueue($command) + { + $queue = call_user_func($this->queueResolver); + + if (! $queue instanceof Queue) { + throw new RuntimeException('Queue resolver did not return a Queue implementation.'); + } + + if (method_exists($command, 'queue')) { + return $command->queue($queue, $command); + } else { + return $this->pushCommandToQueue($queue, $command); + } + } + + /** + * Push the command onto the given queue instance. + * + * @param \Illuminate\Contracts\Queue\Queue $queue + * @param mixed $command + * @return mixed + */ + protected function pushCommandToQueue($queue, $command) + { + if (isset($command->queue) && isset($command->delay)) { + return $queue->laterOn($command->queue, $command->delay, $command); + } + + if (isset($command->queue)) { + return $queue->pushOn($command->queue, $command); + } + + if (isset($command->delay)) { + return $queue->later($command->delay, $command); + } + + return $queue->push($command); + } + + /** + * Get the handler instance for the given command. + * + * @param mixed $command + * @return mixed + */ + public function resolveHandler($command) + { + if ($command instanceof SelfHandling) { + return $command; + } + + return $this->container->make($this->getHandlerClass($command)); + } + + /** + * Get the handler class for the given command. + * + * @param mixed $command + * @return string + */ + public function getHandlerClass($command) + { + if ($command instanceof SelfHandling) { + return get_class($command); + } + + return $this->inflectSegment($command, 0); + } + + /** + * Get the handler method for the given command. + * + * @param mixed $command + * @return string + */ + public function getHandlerMethod($command) + { + if ($command instanceof SelfHandling) { + return 'handle'; + } + + return $this->inflectSegment($command, 1); + } + + /** + * Get the given handler segment for the given command. + * + * @param mixed $command + * @param int $segment + * @return string + */ + protected function inflectSegment($command, $segment) + { + $className = get_class($command); + + if (isset($this->mappings[$className])) { + return $this->getMappingSegment($className, $segment); + } elseif ($this->mapper) { + return $this->getMapperSegment($command, $segment); + } + + throw new InvalidArgumentException("No handler registered for command [{$className}]"); + } + + /** + * Get the given segment from a given class handler. + * + * @param string $className + * @param int $segment + * @return string + */ + protected function getMappingSegment($className, $segment) + { + return explode('@', $this->mappings[$className])[$segment]; + } + + /** + * Get the given segment from a given class handler using the custom mapper. + * + * @param mixed $command + * @param int $segment + * @return string + */ + protected function getMapperSegment($command, $segment) + { + return explode('@', call_user_func($this->mapper, $command))[$segment]; + } + + /** + * Register command-to-handler mappings. + * + * @param array $commands + * @return void + */ + public function maps(array $commands) + { + $this->mappings = array_merge($this->mappings, $commands); + } + + /** + * Register a fallback mapper callback. + * + * @param \Closure $mapper + * @return void + */ + public function mapUsing(Closure $mapper) + { + $this->mapper = $mapper; + } + + /** + * Map the command to a handler within a given root namespace. + * + * @param mixed $command + * @param string $commandNamespace + * @param string $handlerNamespace + * @return string + */ + public static function simpleMapping($command, $commandNamespace, $handlerNamespace) + { + $command = str_replace($commandNamespace, '', get_class($command)); + + return $handlerNamespace.'\\'.trim($command, '\\').'Handler@handle'; + } + + /** + * Set the pipes through which commands should be piped before dispatching. + * + * @param array $pipes + * @return $this + */ + public function pipeThrough(array $pipes) + { + $this->pipes = $pipes; + + return $this; + } +} diff --git a/vendor/illuminate/bus/MarshalException.php b/vendor/illuminate/bus/MarshalException.php new file mode 100644 index 0000000..49c7674 --- /dev/null +++ b/vendor/illuminate/bus/MarshalException.php @@ -0,0 +1,23 @@ +name}] to command [{$command}]"); + } +} diff --git a/vendor/illuminate/bus/Queueable.php b/vendor/illuminate/bus/Queueable.php new file mode 100644 index 0000000..42d1ca5 --- /dev/null +++ b/vendor/illuminate/bus/Queueable.php @@ -0,0 +1,46 @@ +queue = $queue; + + return $this; + } + + /** + * Set the desired delay for the job. + * + * @param int $delay + * @return $this + */ + public function delay($delay) + { + $this->delay = $delay; + + return $this; + } +} diff --git a/vendor/illuminate/bus/composer.json b/vendor/illuminate/bus/composer.json new file mode 100644 index 0000000..16982e6 --- /dev/null +++ b/vendor/illuminate/bus/composer.json @@ -0,0 +1,33 @@ +{ + "name": "illuminate/bus", + "description": "The Illuminate Bus package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/pipeline": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Bus\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/cache/ApcStore.php b/vendor/illuminate/cache/ApcStore.php new file mode 100755 index 0000000..625482e --- /dev/null +++ b/vendor/illuminate/cache/ApcStore.php @@ -0,0 +1,130 @@ +apc = $apc; + $this->prefix = $prefix; + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + $value = $this->apc->get($this->prefix.$key); + + if ($value !== false) { + return $value; + } + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + $this->apc->put($this->prefix.$key, $value, $minutes * 60); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int|bool + */ + public function increment($key, $value = 1) + { + return $this->apc->increment($this->prefix.$key, $value); + } + + /** + * Decrement the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int|bool + */ + public function decrement($key, $value = 1) + { + return $this->apc->decrement($this->prefix.$key, $value); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return array|bool + */ + public function forever($key, $value) + { + return $this->put($key, $value, 0); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + return $this->apc->delete($this->prefix.$key); + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + $this->apc->flush(); + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } +} diff --git a/vendor/illuminate/cache/ApcWrapper.php b/vendor/illuminate/cache/ApcWrapper.php new file mode 100755 index 0000000..9fdf293 --- /dev/null +++ b/vendor/illuminate/cache/ApcWrapper.php @@ -0,0 +1,92 @@ +apcu = function_exists('apcu_fetch'); + } + + /** + * Get an item from the cache. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + return $this->apcu ? apcu_fetch($key) : apc_fetch($key); + } + + /** + * Store an item in the cache. + * + * @param string $key + * @param mixed $value + * @param int $seconds + * @return array|bool + */ + public function put($key, $value, $seconds) + { + return $this->apcu ? apcu_store($key, $value, $seconds) : apc_store($key, $value, $seconds); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int|bool + */ + public function increment($key, $value) + { + return $this->apcu ? apcu_inc($key, $value) : apc_inc($key, $value); + } + + /** + * Decrement the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int|bool + */ + public function decrement($key, $value) + { + return $this->apcu ? apcu_dec($key, $value) : apc_dec($key, $value); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function delete($key) + { + return $this->apcu ? apcu_delete($key) : apc_delete($key); + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + $this->apcu ? apcu_clear_cache() : apc_clear_cache('user'); + } +} diff --git a/vendor/illuminate/cache/ArrayStore.php b/vendor/illuminate/cache/ArrayStore.php new file mode 100755 index 0000000..c55b3c5 --- /dev/null +++ b/vendor/illuminate/cache/ArrayStore.php @@ -0,0 +1,112 @@ +storage)) { + return $this->storage[$key]; + } + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + $this->storage[$key] = $value; + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function increment($key, $value = 1) + { + $this->storage[$key] = $this->storage[$key] + $value; + + return $this->storage[$key]; + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function decrement($key, $value = 1) + { + return $this->increment($key, $value * -1); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + $this->put($key, $value, 0); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + unset($this->storage[$key]); + + return true; + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + $this->storage = []; + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return ''; + } +} diff --git a/vendor/illuminate/cache/CacheManager.php b/vendor/illuminate/cache/CacheManager.php new file mode 100755 index 0000000..81681c1 --- /dev/null +++ b/vendor/illuminate/cache/CacheManager.php @@ -0,0 +1,312 @@ +app = $app; + } + + /** + * Get a cache store instance by name. + * + * @param string|null $name + * @return mixed + */ + public function store($name = null) + { + $name = $name ?: $this->getDefaultDriver(); + + return $this->stores[$name] = $this->get($name); + } + + /** + * Get a cache driver instance. + * + * @param string $driver + * @return mixed + */ + public function driver($driver = null) + { + return $this->store($driver); + } + + /** + * Attempt to get the store from the local cache. + * + * @param string $name + * @return \Illuminate\Contracts\Cache\Repository + */ + protected function get($name) + { + return isset($this->stores[$name]) ? $this->stores[$name] : $this->resolve($name); + } + + /** + * Resolve the given store. + * + * @param string $name + * @return \Illuminate\Contracts\Cache\Repository + */ + protected function resolve($name) + { + $config = $this->getConfig($name); + + if (is_null($config)) { + throw new InvalidArgumentException("Cache store [{$name}] is not defined."); + } + + if (isset($this->customCreators[$config['driver']])) { + return $this->callCustomCreator($config); + } else { + return $this->{'create'.ucfirst($config['driver']).'Driver'}($config); + } + } + + /** + * Call a custom driver creator. + * + * @param array $config + * @return mixed + */ + protected function callCustomCreator(array $config) + { + return $this->customCreators[$config['driver']]($this->app, $config); + } + + /** + * Create an instance of the APC cache driver. + * + * @param array $config + * @return \Illuminate\Cache\ApcStore + */ + protected function createApcDriver(array $config) + { + $prefix = $this->getPrefix($config); + + return $this->repository(new ApcStore(new ApcWrapper, $prefix)); + } + + /** + * Create an instance of the array cache driver. + * + * @return \Illuminate\Cache\ArrayStore + */ + protected function createArrayDriver() + { + return $this->repository(new ArrayStore); + } + + /** + * Create an instance of the file cache driver. + * + * @param array $config + * @return \Illuminate\Cache\FileStore + */ + protected function createFileDriver(array $config) + { + return $this->repository(new FileStore($this->app['files'], $config['path'])); + } + + /** + * Create an instance of the Memcached cache driver. + * + * @param array $config + * @return \Illuminate\Cache\MemcachedStore + */ + protected function createMemcachedDriver(array $config) + { + $prefix = $this->getPrefix($config); + + $memcached = $this->app['memcached.connector']->connect($config['servers']); + + return $this->repository(new MemcachedStore($memcached, $prefix)); + } + + /** + * Create an instance of the Null cache driver. + * + * @return \Illuminate\Cache\NullStore + */ + protected function createNullDriver() + { + return $this->repository(new NullStore); + } + + /** + * Create an instance of the WinCache cache driver. + * + * @param array $config + * @return \Illuminate\Cache\WinCacheStore + */ + protected function createWincacheDriver(array $config) + { + return $this->repository(new WinCacheStore($this->getPrefix($config))); + } + + /** + * Create an instance of the XCache cache driver. + * + * @param array $config + * @return \Illuminate\Cache\WinCacheStore + */ + protected function createXcacheDriver(array $config) + { + return $this->repository(new XCacheStore($this->getPrefix($config))); + } + + /** + * Create an instance of the Redis cache driver. + * + * @param array $config + * @return \Illuminate\Cache\RedisStore + */ + protected function createRedisDriver(array $config) + { + $redis = $this->app['redis']; + + $connection = Arr::get($config, 'connection', 'default') ?: 'default'; + + return $this->repository(new RedisStore($redis, $this->getPrefix($config), $connection)); + } + + /** + * Create an instance of the database cache driver. + * + * @param array $config + * @return \Illuminate\Cache\DatabaseStore + */ + protected function createDatabaseDriver(array $config) + { + $connection = $this->app['db']->connection(Arr::get($config, 'connection')); + + return $this->repository( + new DatabaseStore( + $connection, $this->app['encrypter'], $config['table'], $this->getPrefix($config) + ) + ); + } + + /** + * Create a new cache repository with the given implementation. + * + * @param \Illuminate\Contracts\Cache\Store $store + * @return \Illuminate\Cache\Repository + */ + public function repository(Store $store) + { + $repository = new Repository($store); + + if ($this->app->bound('Illuminate\Contracts\Events\Dispatcher')) { + $repository->setEventDispatcher( + $this->app['Illuminate\Contracts\Events\Dispatcher'] + ); + } + + return $repository; + } + + /** + * Get the cache prefix. + * + * @param array $config + * @return string + */ + protected function getPrefix(array $config) + { + return Arr::get($config, 'prefix') ?: $this->app['config']['cache.prefix']; + } + + /** + * Get the cache connection configuration. + * + * @param string $name + * @return array + */ + protected function getConfig($name) + { + return $this->app['config']["cache.stores.{$name}"]; + } + + /** + * Get the default cache driver name. + * + * @return string + */ + public function getDefaultDriver() + { + return $this->app['config']['cache.default']; + } + + /** + * Set the default cache driver name. + * + * @param string $name + * @return void + */ + public function setDefaultDriver($name) + { + $this->app['config']['cache.default'] = $name; + } + + /** + * Register a custom driver creator Closure. + * + * @param string $driver + * @param \Closure $callback + * @return $this + */ + public function extend($driver, Closure $callback) + { + $this->customCreators[$driver] = $callback; + + return $this; + } + + /** + * Dynamically call the default driver instance. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->store(), $method], $parameters); + } +} diff --git a/vendor/illuminate/cache/CacheServiceProvider.php b/vendor/illuminate/cache/CacheServiceProvider.php new file mode 100755 index 0000000..fe4801e --- /dev/null +++ b/vendor/illuminate/cache/CacheServiceProvider.php @@ -0,0 +1,69 @@ +app->singleton('cache', function ($app) { + return new CacheManager($app); + }); + + $this->app->singleton('cache.store', function ($app) { + return $app['cache']->driver(); + }); + + $this->app->singleton('memcached.connector', function () { + return new MemcachedConnector; + }); + + $this->registerCommands(); + } + + /** + * Register the cache related console commands. + * + * @return void + */ + public function registerCommands() + { + $this->app->singleton('command.cache.clear', function ($app) { + return new ClearCommand($app['cache']); + }); + + $this->app->singleton('command.cache.table', function ($app) { + return new CacheTableCommand($app['files'], $app['composer']); + }); + + $this->commands('command.cache.clear', 'command.cache.table'); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'cache', 'cache.store', 'memcached.connector', 'command.cache.clear', 'command.cache.table', + ]; + } +} diff --git a/vendor/illuminate/cache/Console/CacheTableCommand.php b/vendor/illuminate/cache/Console/CacheTableCommand.php new file mode 100644 index 0000000..d2cbf63 --- /dev/null +++ b/vendor/illuminate/cache/Console/CacheTableCommand.php @@ -0,0 +1,81 @@ +files = $files; + $this->composer = $composer; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $fullPath = $this->createBaseMigration(); + + $this->files->put($fullPath, $this->files->get(__DIR__.'/stubs/cache.stub')); + + $this->info('Migration created successfully!'); + + $this->composer->dumpAutoloads(); + } + + /** + * Create a base migration file for the table. + * + * @return string + */ + protected function createBaseMigration() + { + $name = 'create_cache_table'; + + $path = $this->laravel->databasePath().'/migrations'; + + return $this->laravel['migration.creator']->create($name, $path); + } +} diff --git a/vendor/illuminate/cache/Console/ClearCommand.php b/vendor/illuminate/cache/Console/ClearCommand.php new file mode 100755 index 0000000..02ea032 --- /dev/null +++ b/vendor/illuminate/cache/Console/ClearCommand.php @@ -0,0 +1,74 @@ +cache = $cache; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $storeName = $this->argument('store'); + + $this->laravel['events']->fire('cache:clearing', [$storeName]); + + $this->cache->store($storeName)->flush(); + + $this->laravel['events']->fire('cache:cleared', [$storeName]); + + $this->info('Application cache cleared!'); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['store', InputArgument::OPTIONAL, 'The name of the store you would like to clear.'], + ]; + } +} diff --git a/vendor/illuminate/cache/Console/stubs/cache.stub b/vendor/illuminate/cache/Console/stubs/cache.stub new file mode 100644 index 0000000..c972a4f --- /dev/null +++ b/vendor/illuminate/cache/Console/stubs/cache.stub @@ -0,0 +1,31 @@ +string('key')->unique(); + $table->text('value'); + $table->integer('expiration'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('cache'); + } +} diff --git a/vendor/illuminate/cache/DatabaseStore.php b/vendor/illuminate/cache/DatabaseStore.php new file mode 100755 index 0000000..2f7bebf --- /dev/null +++ b/vendor/illuminate/cache/DatabaseStore.php @@ -0,0 +1,255 @@ +table = $table; + $this->prefix = $prefix; + $this->encrypter = $encrypter; + $this->connection = $connection; + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + $prefixed = $this->prefix.$key; + + $cache = $this->table()->where('key', '=', $prefixed)->first(); + + // If we have a cache record we will check the expiration time against current + // time on the system and see if the record has expired. If it has, we will + // remove the records from the database table so it isn't returned again. + if (! is_null($cache)) { + if (is_array($cache)) { + $cache = (object) $cache; + } + + if (time() >= $cache->expiration) { + $this->forget($key); + + return; + } + + return $this->encrypter->decrypt($cache->value); + } + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + $key = $this->prefix.$key; + + // All of the cached values in the database are encrypted in case this is used + // as a session data store by the consumer. We'll also calculate the expire + // time and place that on the table so we will check it on our retrieval. + $value = $this->encrypter->encrypt($value); + + $expiration = $this->getTime() + ($minutes * 60); + + try { + $this->table()->insert(compact('key', 'value', 'expiration')); + } catch (Exception $e) { + $this->table()->where('key', '=', $key)->update(compact('value', 'expiration')); + } + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function increment($key, $value = 1) + { + $this->connection->transaction(function () use ($key, $value) { + return $this->incrementOrDecrement($key, $value, function ($current) use ($value) { + return $current + $value; + }); + }); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function decrement($key, $value = 1) + { + $this->connection->transaction(function () use ($key, $value) { + return $this->incrementOrDecrement($key, $value, function ($current) use ($value) { + return $current - $value; + }); + }); + } + + /** + * Increment or decrement an item in the cache. + * + * @param string $key + * @param mixed $value + * @param \Closure $callback + * @return void + */ + protected function incrementOrDecrement($key, $value, Closure $callback) + { + $prefixed = $this->prefix.$key; + + $cache = $this->table()->where('key', $prefixed)->lockForUpdate()->first(); + + if (! is_null($cache)) { + $current = $this->encrypter->decrypt($cache->value); + + if (is_numeric($current)) { + $this->table()->where('key', $prefixed)->update([ + 'value' => $this->encrypter->encrypt($callback($current)), + ]); + } + } + } + + /** + * Get the current system time. + * + * @return int + */ + protected function getTime() + { + return time(); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + $this->put($key, $value, 5256000); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + $this->table()->where('key', '=', $this->prefix.$key)->delete(); + + return true; + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + $this->table()->delete(); + } + + /** + * Get a query builder for the cache table. + * + * @return \Illuminate\Database\Query\Builder + */ + protected function table() + { + return $this->connection->table($this->table); + } + + /** + * Get the underlying database connection. + * + * @return \Illuminate\Database\ConnectionInterface + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Get the encrypter instance. + * + * @return \Illuminate\Contracts\Encryption\Encrypter + */ + public function getEncrypter() + { + return $this->encrypter; + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } +} diff --git a/vendor/illuminate/cache/FileStore.php b/vendor/illuminate/cache/FileStore.php new file mode 100755 index 0000000..6bef4cd --- /dev/null +++ b/vendor/illuminate/cache/FileStore.php @@ -0,0 +1,248 @@ +files = $files; + $this->directory = $directory; + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + return Arr::get($this->getPayload($key), 'data'); + } + + /** + * Retrieve an item and expiry time from the cache by key. + * + * @param string $key + * @return array + */ + protected function getPayload($key) + { + $path = $this->path($key); + + // If the file doesn't exists, we obviously can't return the cache so we will + // just return null. Otherwise, we'll get the contents of the file and get + // the expiration UNIX timestamps from the start of the file's contents. + try { + $expire = substr($contents = $this->files->get($path), 0, 10); + } catch (Exception $e) { + return ['data' => null, 'time' => null]; + } + + // If the current time is greater than expiration timestamps we will delete + // the file and return null. This helps clean up the old files and keeps + // this directory much cleaner for us as old files aren't hanging out. + if (time() >= $expire) { + $this->forget($key); + + return ['data' => null, 'time' => null]; + } + + $data = unserialize(substr($contents, 10)); + + // Next, we'll extract the number of minutes that are remaining for a cache + // so that we can properly retain the time for things like the increment + // operation that may be performed on the cache. We'll round this out. + $time = ceil(($expire - time()) / 60); + + return compact('data', 'time'); + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + $value = $this->expiration($minutes).serialize($value); + + $this->createCacheDirectory($path = $this->path($key)); + + $this->files->put($path, $value); + } + + /** + * Create the file cache directory if necessary. + * + * @param string $path + * @return void + */ + protected function createCacheDirectory($path) + { + if (! $this->files->exists(dirname($path))) { + $this->files->makeDirectory(dirname($path), 0777, true, true); + } + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function increment($key, $value = 1) + { + $raw = $this->getPayload($key); + + $int = ((int) $raw['data']) + $value; + + $this->put($key, $int, (int) $raw['time']); + + return $int; + } + + /** + * Decrement the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function decrement($key, $value = 1) + { + return $this->increment($key, $value * -1); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + $this->put($key, $value, 0); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + $file = $this->path($key); + + if ($this->files->exists($file)) { + return $this->files->delete($file); + } + + return false; + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + if ($this->files->isDirectory($this->directory)) { + foreach ($this->files->directories($this->directory) as $directory) { + $this->files->deleteDirectory($directory); + } + } + } + + /** + * Get the full path for the given cache key. + * + * @param string $key + * @return string + */ + protected function path($key) + { + $parts = array_slice(str_split($hash = md5($key), 2), 0, 2); + + return $this->directory.'/'.implode('/', $parts).'/'.$hash; + } + + /** + * Get the expiration time based on the given minutes. + * + * @param int $minutes + * @return int + */ + protected function expiration($minutes) + { + if ($minutes === 0) { + return 9999999999; + } + + return time() + ($minutes * 60); + } + + /** + * Get the Filesystem instance. + * + * @return \Illuminate\Filesystem\Filesystem + */ + public function getFilesystem() + { + return $this->files; + } + + /** + * Get the working directory of the cache. + * + * @return string + */ + public function getDirectory() + { + return $this->directory; + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return ''; + } +} diff --git a/vendor/illuminate/cache/MemcachedConnector.php b/vendor/illuminate/cache/MemcachedConnector.php new file mode 100755 index 0000000..49f5cd8 --- /dev/null +++ b/vendor/illuminate/cache/MemcachedConnector.php @@ -0,0 +1,53 @@ +getMemcached(); + + // For each server in the array, we'll just extract the configuration and add + // the server to the Memcached connection. Once we have added all of these + // servers we'll verify the connection is successful and return it back. + foreach ($servers as $server) { + $memcached->addServer( + $server['host'], $server['port'], $server['weight'] + ); + } + + $memcachedStatus = $memcached->getVersion(); + + if (! is_array($memcachedStatus)) { + throw new RuntimeException('No Memcached servers added.'); + } + + if (in_array('255.255.255', $memcachedStatus) && count(array_unique($memcachedStatus)) === 1) { + throw new RuntimeException('Could not establish Memcached connection.'); + } + + return $memcached; + } + + /** + * Get a new Memcached instance. + * + * @return \Memcached + */ + protected function getMemcached() + { + return new Memcached; + } +} diff --git a/vendor/illuminate/cache/MemcachedStore.php b/vendor/illuminate/cache/MemcachedStore.php new file mode 100755 index 0000000..2c2aee0 --- /dev/null +++ b/vendor/illuminate/cache/MemcachedStore.php @@ -0,0 +1,164 @@ +setPrefix($prefix); + $this->memcached = $memcached; + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + $value = $this->memcached->get($this->prefix.$key); + + if ($this->memcached->getResultCode() == 0) { + return $value; + } + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + $this->memcached->set($this->prefix.$key, $value, $minutes * 60); + } + + /** + * Store an item in the cache if the key doesn't exist. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return bool + */ + public function add($key, $value, $minutes) + { + return $this->memcached->add($this->prefix.$key, $value, $minutes * 60); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int|bool + */ + public function increment($key, $value = 1) + { + return $this->memcached->increment($this->prefix.$key, $value); + } + + /** + * Decrement the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int|bool + */ + public function decrement($key, $value = 1) + { + return $this->memcached->decrement($this->prefix.$key, $value); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + $this->put($key, $value, 0); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + return $this->memcached->delete($this->prefix.$key); + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + $this->memcached->flush(); + } + + /** + * Get the underlying Memcached connection. + * + * @return \Memcached + */ + public function getMemcached() + { + return $this->memcached; + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * Set the cache key prefix. + * + * @param string $prefix + * @return void + */ + public function setPrefix($prefix) + { + $this->prefix = ! empty($prefix) ? $prefix.':' : ''; + } +} diff --git a/vendor/illuminate/cache/NullStore.php b/vendor/illuminate/cache/NullStore.php new file mode 100755 index 0000000..46aed16 --- /dev/null +++ b/vendor/illuminate/cache/NullStore.php @@ -0,0 +1,106 @@ +cache = $cache; + } + + /** + * Determine if the given key has been "accessed" too many times. + * + * @param string $key + * @param int $maxAttempts + * @param int $decayMinutes + * @return bool + */ + public function tooManyAttempts($key, $maxAttempts, $decayMinutes = 1) + { + $lockedOut = $this->cache->has($key.':lockout'); + + if ($this->attempts($key) > $maxAttempts || $lockedOut) { + if (! $lockedOut) { + $this->cache->add($key.':lockout', time() + ($decayMinutes * 60), $decayMinutes); + } + + return true; + } + + return false; + } + + /** + * Increment the counter for a given key for a given decay time. + * + * @param string $key + * @param int $decayMinutes + * @return int + */ + public function hit($key, $decayMinutes = 1) + { + $this->cache->add($key, 1, $decayMinutes); + + return (int) $this->cache->increment($key); + } + + /** + * Get the number of attempts for the given key. + * + * @param string $key + * @return mixed + */ + public function attempts($key) + { + return $this->cache->get($key, 0); + } + + /** + * Clear the hits and lockout for the given key. + * + * @param string $key + * @return void + */ + public function clear($key) + { + $this->cache->forget($key); + + $this->cache->forget($key.':lockout'); + } + + /** + * Get the number of seconds until the "key" is accessible again. + * + * @param string $key + * @return int + */ + public function availableIn($key) + { + return $this->cache->get($key.':lockout') - time(); + } +} diff --git a/vendor/illuminate/cache/RedisStore.php b/vendor/illuminate/cache/RedisStore.php new file mode 100755 index 0000000..aeea3f4 --- /dev/null +++ b/vendor/illuminate/cache/RedisStore.php @@ -0,0 +1,197 @@ +redis = $redis; + $this->setPrefix($prefix); + $this->connection = $connection; + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + if (! is_null($value = $this->connection()->get($this->prefix.$key))) { + return is_numeric($value) ? $value : unserialize($value); + } + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + $value = is_numeric($value) ? $value : serialize($value); + + $minutes = max(1, $minutes); + + $this->connection()->setex($this->prefix.$key, $minutes * 60, $value); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function increment($key, $value = 1) + { + return $this->connection()->incrby($this->prefix.$key, $value); + } + + /** + * Decrement the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function decrement($key, $value = 1) + { + return $this->connection()->decrby($this->prefix.$key, $value); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + $value = is_numeric($value) ? $value : serialize($value); + + $this->connection()->set($this->prefix.$key, $value); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + return (bool) $this->connection()->del($this->prefix.$key); + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + $this->connection()->flushdb(); + } + + /** + * Begin executing a new tags operation. + * + * @param array|mixed $names + * @return \Illuminate\Cache\RedisTaggedCache + */ + public function tags($names) + { + return new RedisTaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args())); + } + + /** + * Get the Redis connection instance. + * + * @return \Predis\ClientInterface + */ + public function connection() + { + return $this->redis->connection($this->connection); + } + + /** + * Set the connection name to be used. + * + * @param string $connection + * @return void + */ + public function setConnection($connection) + { + $this->connection = $connection; + } + + /** + * Get the Redis database instance. + * + * @return \Illuminate\Redis\Database + */ + public function getRedis() + { + return $this->redis; + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * Set the cache key prefix. + * + * @param string $prefix + * @return void + */ + public function setPrefix($prefix) + { + $this->prefix = ! empty($prefix) ? $prefix.':' : ''; + } +} diff --git a/vendor/illuminate/cache/RedisTaggedCache.php b/vendor/illuminate/cache/RedisTaggedCache.php new file mode 100644 index 0000000..5b9a53b --- /dev/null +++ b/vendor/illuminate/cache/RedisTaggedCache.php @@ -0,0 +1,88 @@ +pushForeverKeys($namespace = $this->tags->getNamespace(), $key); + + $this->store->forever(sha1($namespace).':'.$key, $value); + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + $this->deleteForeverKeys(); + + parent::flush(); + } + + /** + * Store a copy of the full key for each namespace segment. + * + * @param string $namespace + * @param string $key + * @return void + */ + protected function pushForeverKeys($namespace, $key) + { + $fullKey = $this->getPrefix().sha1($namespace).':'.$key; + + foreach (explode('|', $namespace) as $segment) { + $this->store->connection()->lpush($this->foreverKey($segment), $fullKey); + } + } + + /** + * Delete all of the items that were stored forever. + * + * @return void + */ + protected function deleteForeverKeys() + { + foreach (explode('|', $this->tags->getNamespace()) as $segment) { + $this->deleteForeverValues($segment = $this->foreverKey($segment)); + + $this->store->connection()->del($segment); + } + } + + /** + * Delete all of the keys that have been stored forever. + * + * @param string $foreverKey + * @return void + */ + protected function deleteForeverValues($foreverKey) + { + $forever = array_unique($this->store->connection()->lrange($foreverKey, 0, -1)); + + if (count($forever) > 0) { + call_user_func_array([$this->store->connection(), 'del'], $forever); + } + } + + /** + * Get the forever reference key for the segment. + * + * @param string $segment + * @return string + */ + protected function foreverKey($segment) + { + return $this->getPrefix().$segment.':forever'; + } +} diff --git a/vendor/illuminate/cache/Repository.php b/vendor/illuminate/cache/Repository.php new file mode 100755 index 0000000..e27c71e --- /dev/null +++ b/vendor/illuminate/cache/Repository.php @@ -0,0 +1,376 @@ +store = $store; + } + + /** + * Set the event dispatcher instance. + * + * @param \Illuminate\Contracts\Events\Dispatcher $events + * @return void + */ + public function setEventDispatcher(Dispatcher $events) + { + $this->events = $events; + } + + /** + * Fire an event for this cache instance. + * + * @param string $event + * @param array $payload + * @return void + */ + protected function fireCacheEvent($event, $payload) + { + if (isset($this->events)) { + $this->events->fire('cache.'.$event, $payload); + } + } + + /** + * Determine if an item exists in the cache. + * + * @param string $key + * @return bool + */ + public function has($key) + { + return ! is_null($this->get($key)); + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function get($key, $default = null) + { + $value = $this->store->get($key); + + if (is_null($value)) { + $this->fireCacheEvent('missed', [$key]); + + $value = value($default); + } else { + $this->fireCacheEvent('hit', [$key, $value]); + } + + return $value; + } + + /** + * Retrieve an item from the cache and delete it. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function pull($key, $default = null) + { + $value = $this->get($key, $default); + + $this->forget($key); + + return $value; + } + + /** + * Store an item in the cache. + * + * @param string $key + * @param mixed $value + * @param \DateTime|int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + $minutes = $this->getMinutes($minutes); + + if (! is_null($minutes)) { + $this->store->put($key, $value, $minutes); + + $this->fireCacheEvent('write', [$key, $value, $minutes]); + } + } + + /** + * Store an item in the cache if the key does not exist. + * + * @param string $key + * @param mixed $value + * @param \DateTime|int $minutes + * @return bool + */ + public function add($key, $value, $minutes) + { + $minutes = $this->getMinutes($minutes); + + if (is_null($minutes)) { + return false; + } + + if (method_exists($this->store, 'add')) { + return $this->store->add($key, $value, $minutes); + } + + if (is_null($this->get($key))) { + $this->put($key, $value, $minutes); + + return true; + } + + return false; + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + $this->store->forever($key, $value); + + $this->fireCacheEvent('write', [$key, $value, 0]); + } + + /** + * Get an item from the cache, or store the default value. + * + * @param string $key + * @param \DateTime|int $minutes + * @param \Closure $callback + * @return mixed + */ + public function remember($key, $minutes, Closure $callback) + { + // If the item exists in the cache we will just return this immediately + // otherwise we will execute the given Closure and cache the result + // of that execution for the given number of minutes in storage. + if (! is_null($value = $this->get($key))) { + return $value; + } + + $this->put($key, $value = $callback(), $minutes); + + return $value; + } + + /** + * Get an item from the cache, or store the default value forever. + * + * @param string $key + * @param \Closure $callback + * @return mixed + */ + public function sear($key, Closure $callback) + { + return $this->rememberForever($key, $callback); + } + + /** + * Get an item from the cache, or store the default value forever. + * + * @param string $key + * @param \Closure $callback + * @return mixed + */ + public function rememberForever($key, Closure $callback) + { + // If the item exists in the cache we will just return this immediately + // otherwise we will execute the given Closure and cache the result + // of that execution for the given number of minutes. It's easy. + if (! is_null($value = $this->get($key))) { + return $value; + } + + $this->forever($key, $value = $callback()); + + return $value; + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + $success = $this->store->forget($key); + + $this->fireCacheEvent('delete', [$key]); + + return $success; + } + + /** + * Get the default cache time. + * + * @return int + */ + public function getDefaultCacheTime() + { + return $this->default; + } + + /** + * Set the default cache time in minutes. + * + * @param int $minutes + * @return void + */ + public function setDefaultCacheTime($minutes) + { + $this->default = $minutes; + } + + /** + * Get the cache store implementation. + * + * @return \Illuminate\Contracts\Cache\Store + */ + public function getStore() + { + return $this->store; + } + + /** + * Determine if a cached value exists. + * + * @param string $key + * @return bool + */ + public function offsetExists($key) + { + return $this->has($key); + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @return mixed + */ + public function offsetGet($key) + { + return $this->get($key); + } + + /** + * Store an item in the cache for the default time. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + $this->put($key, $value, $this->default); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return void + */ + public function offsetUnset($key) + { + $this->forget($key); + } + + /** + * Calculate the number of minutes with the given duration. + * + * @param \DateTime|int $duration + * @return int|null + */ + protected function getMinutes($duration) + { + if ($duration instanceof DateTime) { + $fromNow = Carbon::now()->diffInMinutes(Carbon::instance($duration), false); + + return $fromNow > 0 ? $fromNow : null; + } + + return is_string($duration) ? (int) $duration : $duration; + } + + /** + * Handle dynamic calls into macros or pass missing methods to the store. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if (static::hasMacro($method)) { + return $this->macroCall($method, $parameters); + } + + return call_user_func_array([$this->store, $method], $parameters); + } + + /** + * Clone cache repository instance. + * + * @return void + */ + public function __clone() + { + $this->store = clone $this->store; + } +} diff --git a/vendor/illuminate/cache/TagSet.php b/vendor/illuminate/cache/TagSet.php new file mode 100644 index 0000000..61ca972 --- /dev/null +++ b/vendor/illuminate/cache/TagSet.php @@ -0,0 +1,100 @@ +store = $store; + $this->names = $names; + } + + /** + * Reset all tags in the set. + * + * @return void + */ + public function reset() + { + array_walk($this->names, [$this, 'resetTag']); + } + + /** + * Get the unique tag identifier for a given tag. + * + * @param string $name + * @return string + */ + public function tagId($name) + { + return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name); + } + + /** + * Get an array of tag identifiers for all of the tags in the set. + * + * @return array + */ + protected function tagIds() + { + return array_map([$this, 'tagId'], $this->names); + } + + /** + * Get a unique namespace that changes when any of the tags are flushed. + * + * @return string + */ + public function getNamespace() + { + return implode('|', $this->tagIds()); + } + + /** + * Reset the tag and return the new tag identifier. + * + * @param string $name + * @return string + */ + public function resetTag($name) + { + $this->store->forever($this->tagKey($name), $id = str_replace('.', '', uniqid('', true))); + + return $id; + } + + /** + * Get the tag identifier key for a given tag. + * + * @param string $name + * @return string + */ + public function tagKey($name) + { + return 'tag:'.$name.':key'; + } +} diff --git a/vendor/illuminate/cache/TaggableStore.php b/vendor/illuminate/cache/TaggableStore.php new file mode 100644 index 0000000..4479fcc --- /dev/null +++ b/vendor/illuminate/cache/TaggableStore.php @@ -0,0 +1,30 @@ +tags($name); + } + + /** + * Begin executing a new tags operation. + * + * @param array|mixed $names + * @return \Illuminate\Cache\TaggedCache + */ + public function tags($names) + { + return new TaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args())); + } +} diff --git a/vendor/illuminate/cache/TaggedCache.php b/vendor/illuminate/cache/TaggedCache.php new file mode 100644 index 0000000..4c3f7ee --- /dev/null +++ b/vendor/illuminate/cache/TaggedCache.php @@ -0,0 +1,249 @@ +tags = $tags; + $this->store = $store; + } + + /** + * Determine if an item exists in the cache. + * + * @param string $key + * @return bool + */ + public function has($key) + { + return ! is_null($this->get($key)); + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function get($key, $default = null) + { + $value = $this->store->get($this->taggedItemKey($key)); + + return ! is_null($value) ? $value : value($default); + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param \DateTime|int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + $minutes = $this->getMinutes($minutes); + + if (! is_null($minutes)) { + $this->store->put($this->taggedItemKey($key), $value, $minutes); + } + } + + /** + * Store an item in the cache if the key does not exist. + * + * @param string $key + * @param mixed $value + * @param \DateTime|int $minutes + * @return bool + */ + public function add($key, $value, $minutes) + { + if (is_null($this->get($key))) { + $this->put($key, $value, $minutes); + + return true; + } + + return false; + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function increment($key, $value = 1) + { + $this->store->increment($this->taggedItemKey($key), $value); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function decrement($key, $value = 1) + { + $this->store->decrement($this->taggedItemKey($key), $value); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + $this->store->forever($this->taggedItemKey($key), $value); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + return $this->store->forget($this->taggedItemKey($key)); + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + $this->tags->reset(); + } + + /** + * Get an item from the cache, or store the default value. + * + * @param string $key + * @param \DateTime|int $minutes + * @param \Closure $callback + * @return mixed + */ + public function remember($key, $minutes, Closure $callback) + { + // If the item exists in the cache we will just return this immediately + // otherwise we will execute the given Closure and cache the result + // of that execution for the given number of minutes in storage. + if (! is_null($value = $this->get($key))) { + return $value; + } + + $this->put($key, $value = $callback(), $minutes); + + return $value; + } + + /** + * Get an item from the cache, or store the default value forever. + * + * @param string $key + * @param \Closure $callback + * @return mixed + */ + public function sear($key, Closure $callback) + { + return $this->rememberForever($key, $callback); + } + + /** + * Get an item from the cache, or store the default value forever. + * + * @param string $key + * @param \Closure $callback + * @return mixed + */ + public function rememberForever($key, Closure $callback) + { + // If the item exists in the cache we will just return this immediately + // otherwise we will execute the given Closure and cache the result + // of that execution for an indefinite amount of time. It's easy. + if (! is_null($value = $this->get($key))) { + return $value; + } + + $this->forever($key, $value = $callback()); + + return $value; + } + + /** + * Get a fully qualified key for a tagged item. + * + * @param string $key + * @return string + */ + public function taggedItemKey($key) + { + return sha1($this->tags->getNamespace()).':'.$key; + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->store->getPrefix(); + } + + /** + * Calculate the number of minutes with the given duration. + * + * @param \DateTime|int $duration + * @return int|null + */ + protected function getMinutes($duration) + { + if ($duration instanceof DateTime) { + $fromNow = Carbon::now()->diffInMinutes(Carbon::instance($duration), false); + + return $fromNow > 0 ? $fromNow : null; + } + + return is_string($duration) ? (int) $duration : $duration; + } +} diff --git a/vendor/illuminate/cache/WinCacheStore.php b/vendor/illuminate/cache/WinCacheStore.php new file mode 100755 index 0000000..6dc3fc7 --- /dev/null +++ b/vendor/illuminate/cache/WinCacheStore.php @@ -0,0 +1,121 @@ +prefix = $prefix; + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + $value = wincache_ucache_get($this->prefix.$key); + + if ($value !== false) { + return $value; + } + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + wincache_ucache_set($this->prefix.$key, $value, $minutes * 60); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int|bool + */ + public function increment($key, $value = 1) + { + return wincache_ucache_inc($this->prefix.$key, $value); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int|bool + */ + public function decrement($key, $value = 1) + { + return wincache_ucache_dec($this->prefix.$key, $value); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + $this->put($key, $value, 0); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + return wincache_ucache_delete($this->prefix.$key); + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + wincache_ucache_clear(); + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } +} diff --git a/vendor/illuminate/cache/XCacheStore.php b/vendor/illuminate/cache/XCacheStore.php new file mode 100755 index 0000000..7ef64cf --- /dev/null +++ b/vendor/illuminate/cache/XCacheStore.php @@ -0,0 +1,121 @@ +prefix = $prefix; + } + + /** + * Retrieve an item from the cache by key. + * + * @param string $key + * @return mixed + */ + public function get($key) + { + $value = xcache_get($this->prefix.$key); + + if (isset($value)) { + return $value; + } + } + + /** + * Store an item in the cache for a given number of minutes. + * + * @param string $key + * @param mixed $value + * @param int $minutes + * @return void + */ + public function put($key, $value, $minutes) + { + xcache_set($this->prefix.$key, $value, $minutes * 60); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function increment($key, $value = 1) + { + return xcache_inc($this->prefix.$key, $value); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function decrement($key, $value = 1) + { + return xcache_dec($this->prefix.$key, $value); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function forever($key, $value) + { + return $this->put($key, $value, 0); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) + { + return xcache_unset($this->prefix.$key); + } + + /** + * Remove all items from the cache. + * + * @return void + */ + public function flush() + { + xcache_clear_cache(XC_TYPE_VAR); + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } +} diff --git a/vendor/illuminate/cache/composer.json b/vendor/illuminate/cache/composer.json new file mode 100755 index 0000000..51ee8ac --- /dev/null +++ b/vendor/illuminate/cache/composer.json @@ -0,0 +1,38 @@ +{ + "name": "illuminate/cache", + "description": "The Illuminate Cache package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19" + }, + "autoload": { + "psr-4": { + "Illuminate\\Cache\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "illuminate/database": "Required to use the database cache driver (5.1.*).", + "illuminate/filesystem": "Required to use the file cache driver (5.1.*).", + "illuminate/redis": "Required to use the redis cache driver (5.1.*)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/config/Repository.php b/vendor/illuminate/config/Repository.php new file mode 100644 index 0000000..184a04a --- /dev/null +++ b/vendor/illuminate/config/Repository.php @@ -0,0 +1,156 @@ +items = $items; + } + + /** + * Determine if the given configuration value exists. + * + * @param string $key + * @return bool + */ + public function has($key) + { + return Arr::has($this->items, $key); + } + + /** + * Get the specified configuration value. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function get($key, $default = null) + { + return Arr::get($this->items, $key, $default); + } + + /** + * Set a given configuration value. + * + * @param array|string $key + * @param mixed $value + * @return void + */ + public function set($key, $value = null) + { + if (is_array($key)) { + foreach ($key as $innerKey => $innerValue) { + Arr::set($this->items, $innerKey, $innerValue); + } + } else { + Arr::set($this->items, $key, $value); + } + } + + /** + * Prepend a value onto an array configuration value. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function prepend($key, $value) + { + $array = $this->get($key); + + array_unshift($array, $value); + + $this->set($key, $array); + } + + /** + * Push a value onto an array configuration value. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function push($key, $value) + { + $array = $this->get($key); + + $array[] = $value; + + $this->set($key, $array); + } + + /** + * Get all of the configuration items for the application. + * + * @return array + */ + public function all() + { + return $this->items; + } + + /** + * Determine if the given configuration option exists. + * + * @param string $key + * @return bool + */ + public function offsetExists($key) + { + return $this->has($key); + } + + /** + * Get a configuration option. + * + * @param string $key + * @return mixed + */ + public function offsetGet($key) + { + return $this->get($key); + } + + /** + * Set a configuration option. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + $this->set($key, $value); + } + + /** + * Unset a configuration option. + * + * @param string $key + * @return void + */ + public function offsetUnset($key) + { + $this->set($key, null); + } +} diff --git a/vendor/illuminate/config/composer.json b/vendor/illuminate/config/composer.json new file mode 100755 index 0000000..b4c4f23 --- /dev/null +++ b/vendor/illuminate/config/composer.json @@ -0,0 +1,33 @@ +{ + "name": "illuminate/config", + "description": "The Illuminate Config package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/filesystem": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Config\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/console/AppNamespaceDetectorTrait.php b/vendor/illuminate/console/AppNamespaceDetectorTrait.php new file mode 100644 index 0000000..4feede9 --- /dev/null +++ b/vendor/illuminate/console/AppNamespaceDetectorTrait.php @@ -0,0 +1,18 @@ +getNamespace(); + } +} diff --git a/vendor/illuminate/console/Application.php b/vendor/illuminate/console/Application.php new file mode 100755 index 0000000..4c1ed4f --- /dev/null +++ b/vendor/illuminate/console/Application.php @@ -0,0 +1,166 @@ +laravel = $laravel; + $this->setAutoExit(false); + $this->setCatchExceptions(false); + + $events->fire('artisan.start', [$this]); + } + + /** + * Run an Artisan console command by name. + * + * @param string $command + * @param array $parameters + * @return int + */ + public function call($command, array $parameters = []) + { + $parameters['command'] = $command; + + $this->lastOutput = new BufferedOutput; + + return $this->find($command)->run(new ArrayInput($parameters), $this->lastOutput); + } + + /** + * Get the output for the last run command. + * + * @return string + */ + public function output() + { + return $this->lastOutput ? $this->lastOutput->fetch() : ''; + } + + /** + * Add a command to the console. + * + * @param \Symfony\Component\Console\Command\Command $command + * @return \Symfony\Component\Console\Command\Command + */ + public function add(SymfonyCommand $command) + { + if ($command instanceof Command) { + $command->setLaravel($this->laravel); + } + + return $this->addToParent($command); + } + + /** + * Add the command to the parent instance. + * + * @param \Symfony\Component\Console\Command\Command $command + * @return \Symfony\Component\Console\Command\Command + */ + protected function addToParent(SymfonyCommand $command) + { + return parent::add($command); + } + + /** + * Add a command, resolving through the application. + * + * @param string $command + * @return \Symfony\Component\Console\Command\Command + */ + public function resolve($command) + { + return $this->add($this->laravel->make($command)); + } + + /** + * Resolve an array of commands through the application. + * + * @param array|mixed $commands + * @return $this + */ + public function resolveCommands($commands) + { + $commands = is_array($commands) ? $commands : func_get_args(); + + foreach ($commands as $command) { + $this->resolve($command); + } + + return $this; + } + + /** + * Get the default input definitions for the applications. + * + * This is used to add the --env option to every available command. + * + * @return \Symfony\Component\Console\Input\InputDefinition + */ + protected function getDefaultInputDefinition() + { + $definition = parent::getDefaultInputDefinition(); + + $definition->addOption($this->getEnvironmentOption()); + + return $definition; + } + + /** + * Get the global environment option for the definition. + * + * @return \Symfony\Component\Console\Input\InputOption + */ + protected function getEnvironmentOption() + { + $message = 'The environment the command should run under.'; + + return new InputOption('--env', null, InputOption::VALUE_OPTIONAL, $message); + } + + /** + * Get the Laravel application instance. + * + * @return \Illuminate\Contracts\Foundation\Application + */ + public function getLaravel() + { + return $this->laravel; + } +} diff --git a/vendor/illuminate/console/Command.php b/vendor/illuminate/console/Command.php new file mode 100755 index 0000000..217f1b5 --- /dev/null +++ b/vendor/illuminate/console/Command.php @@ -0,0 +1,443 @@ +signature)) { + $this->configureUsingFluentDefinition(); + } else { + parent::__construct($this->name); + } + + $this->setDescription($this->description); + + if (! isset($this->signature)) { + $this->specifyParameters(); + } + } + + /** + * Configure the console command using a fluent definition. + * + * @return void + */ + protected function configureUsingFluentDefinition() + { + list($name, $arguments, $options) = Parser::parse($this->signature); + + parent::__construct($name); + + foreach ($arguments as $argument) { + $this->getDefinition()->addArgument($argument); + } + + foreach ($options as $option) { + $this->getDefinition()->addOption($option); + } + } + + /** + * Specify the arguments and options on the command. + * + * @return void + */ + protected function specifyParameters() + { + // We will loop through all of the arguments and options for the command and + // set them all on the base command instance. This specifies what can get + // passed into these commands as "parameters" to control the execution. + foreach ($this->getArguments() as $arguments) { + call_user_func_array([$this, 'addArgument'], $arguments); + } + + foreach ($this->getOptions() as $options) { + call_user_func_array([$this, 'addOption'], $options); + } + } + + /** + * Run the console command. + * + * @param \Symfony\Component\Console\Input\InputInterface $input + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @return int + */ + public function run(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + + $this->output = new OutputStyle($input, $output); + + return parent::run($input, $output); + } + + /** + * Execute the console command. + * + * @param \Symfony\Component\Console\Input\InputInterface $input + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @return mixed + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $method = method_exists($this, 'handle') ? 'handle' : 'fire'; + + return $this->laravel->call([$this, $method]); + } + + /** + * Call another console command. + * + * @param string $command + * @param array $arguments + * @return int + */ + public function call($command, array $arguments = []) + { + $instance = $this->getApplication()->find($command); + + $arguments['command'] = $command; + + return $instance->run(new ArrayInput($arguments), $this->output); + } + + /** + * Call another console command silently. + * + * @param string $command + * @param array $arguments + * @return int + */ + public function callSilent($command, array $arguments = []) + { + $instance = $this->getApplication()->find($command); + + $arguments['command'] = $command; + + return $instance->run(new ArrayInput($arguments), new NullOutput); + } + + /** + * Get the value of a command argument. + * + * @param string $key + * @return string|array + */ + public function argument($key = null) + { + if (is_null($key)) { + return $this->input->getArguments(); + } + + return $this->input->getArgument($key); + } + + /** + * Get the value of a command option. + * + * @param string $key + * @return string|array + */ + public function option($key = null) + { + if (is_null($key)) { + return $this->input->getOptions(); + } + + return $this->input->getOption($key); + } + + /** + * Confirm a question with the user. + * + * @param string $question + * @param bool $default + * @return bool + */ + public function confirm($question, $default = false) + { + return $this->output->confirm($question, $default); + } + + /** + * Prompt the user for input. + * + * @param string $question + * @param string $default + * @return string + */ + public function ask($question, $default = null) + { + return $this->output->ask($question, $default); + } + + /** + * Prompt the user for input with auto completion. + * + * @param string $question + * @param array $choices + * @param string $default + * @return string + */ + public function anticipate($question, array $choices, $default = null) + { + return $this->askWithCompletion($question, $choices, $default); + } + + /** + * Prompt the user for input with auto completion. + * + * @param string $question + * @param array $choices + * @param string $default + * @return string + */ + public function askWithCompletion($question, array $choices, $default = null) + { + $question = new Question($question, $default); + + $question->setAutocompleterValues($choices); + + return $this->output->askQuestion($question); + } + + /** + * Prompt the user for input but hide the answer from the console. + * + * @param string $question + * @param bool $fallback + * @return string + */ + public function secret($question, $fallback = true) + { + $question = new Question($question); + + $question->setHidden(true)->setHiddenFallback($fallback); + + return $this->output->askQuestion($question); + } + + /** + * Give the user a single choice from an array of answers. + * + * @param string $question + * @param array $choices + * @param string $default + * @param mixed $attempts + * @param bool $multiple + * @return bool + */ + public function choice($question, array $choices, $default = null, $attempts = null, $multiple = null) + { + $question = new ChoiceQuestion($question, $choices, $default); + + $question->setMaxAttempts($attempts)->setMultiselect($multiple); + + return $this->output->askQuestion($question); + } + + /** + * Format input to textual table. + * + * @param array $headers + * @param array|\Illuminate\Contracts\Support\Arrayable $rows + * @param string $style + * @return void + */ + public function table(array $headers, $rows, $style = 'default') + { + $table = new Table($this->output); + + if ($rows instanceof Arrayable) { + $rows = $rows->toArray(); + } + + $table->setHeaders($headers)->setRows($rows)->setStyle($style)->render(); + } + + /** + * Write a string as information output. + * + * @param string $string + * @return void + */ + public function info($string) + { + $this->output->writeln("$string"); + } + + /** + * Write a string as standard output. + * + * @param string $string + * @return void + */ + public function line($string) + { + $this->output->writeln($string); + } + + /** + * Write a string as comment output. + * + * @param string $string + * @return void + */ + public function comment($string) + { + $this->output->writeln("$string"); + } + + /** + * Write a string as question output. + * + * @param string $string + * @return void + */ + public function question($string) + { + $this->output->writeln("$string"); + } + + /** + * Write a string as error output. + * + * @param string $string + * @return void + */ + public function error($string) + { + $this->output->writeln("$string"); + } + + /** + * Write a string as warning output. + * + * @param string $string + * @return void + */ + public function warn($string) + { + $style = new OutputFormatterStyle('yellow'); + + $this->output->getFormatter()->setStyle('warning', $style); + + $this->output->writeln("$string"); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return []; + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return []; + } + + /** + * Get the output implementation. + * + * @return \Symfony\Component\Console\Output\OutputInterface + */ + public function getOutput() + { + return $this->output; + } + + /** + * Get the Laravel application instance. + * + * @return \Illuminate\Contracts\Foundation\Application + */ + public function getLaravel() + { + return $this->laravel; + } + + /** + * Set the Laravel application instance. + * + * @param \Illuminate\Contracts\Foundation\Application $laravel + * @return void + */ + public function setLaravel(LaravelApplication $laravel) + { + $this->laravel = $laravel; + } +} diff --git a/vendor/illuminate/console/ConfirmableTrait.php b/vendor/illuminate/console/ConfirmableTrait.php new file mode 100644 index 0000000..69324f0 --- /dev/null +++ b/vendor/illuminate/console/ConfirmableTrait.php @@ -0,0 +1,53 @@ +getDefaultConfirmCallback() : $callback; + + $shouldConfirm = $callback instanceof Closure ? call_user_func($callback) : $callback; + + if ($shouldConfirm) { + if ($this->option('force')) { + return true; + } + + $this->comment(str_repeat('*', strlen($warning) + 12)); + $this->comment('* '.$warning.' *'); + $this->comment(str_repeat('*', strlen($warning) + 12)); + $this->output->writeln(''); + + $confirmed = $this->confirm('Do you really wish to run this command? [y/N]'); + + if (! $confirmed) { + $this->comment('Command Cancelled!'); + + return false; + } + } + + return true; + } + + /** + * Get the default confirmation callback. + * + * @return \Closure + */ + protected function getDefaultConfirmCallback() + { + return function () { return $this->getLaravel()->environment() == 'production'; }; + } +} diff --git a/vendor/illuminate/console/GeneratorCommand.php b/vendor/illuminate/console/GeneratorCommand.php new file mode 100644 index 0000000..9348ae1 --- /dev/null +++ b/vendor/illuminate/console/GeneratorCommand.php @@ -0,0 +1,219 @@ +files = $files; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + abstract protected function getStub(); + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + $name = $this->parseName($this->getNameInput()); + + $path = $this->getPath($name); + + if ($this->alreadyExists($this->getNameInput())) { + $this->error($this->type.' already exists!'); + + return false; + } + + $this->makeDirectory($path); + + $this->files->put($path, $this->buildClass($name)); + + $this->info($this->type.' created successfully.'); + } + + /** + * Determine if the class already exists. + * + * @param string $rawName + * @return bool + */ + protected function alreadyExists($rawName) + { + $name = $this->parseName($rawName); + + return $this->files->exists($path = $this->getPath($name)); + } + + /** + * Get the destination class path. + * + * @param string $name + * @return string + */ + protected function getPath($name) + { + $name = str_replace($this->laravel->getNamespace(), '', $name); + + return $this->laravel['path'].'/'.str_replace('\\', '/', $name).'.php'; + } + + /** + * Parse the name and format according to the root namespace. + * + * @param string $name + * @return string + */ + protected function parseName($name) + { + $rootNamespace = $this->laravel->getNamespace(); + + if (Str::startsWith($name, $rootNamespace)) { + return $name; + } + + if (Str::contains($name, '/')) { + $name = str_replace('/', '\\', $name); + } + + return $this->parseName($this->getDefaultNamespace(trim($rootNamespace, '\\')).'\\'.$name); + } + + /** + * Get the default namespace for the class. + * + * @param string $rootNamespace + * @return string + */ + protected function getDefaultNamespace($rootNamespace) + { + return $rootNamespace; + } + + /** + * Build the directory for the class if necessary. + * + * @param string $path + * @return string + */ + protected function makeDirectory($path) + { + if (! $this->files->isDirectory(dirname($path))) { + $this->files->makeDirectory(dirname($path), 0777, true, true); + } + } + + /** + * Build the class with the given name. + * + * @param string $name + * @return string + */ + protected function buildClass($name) + { + $stub = $this->files->get($this->getStub()); + + return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name); + } + + /** + * Replace the namespace for the given stub. + * + * @param string $stub + * @param string $name + * @return $this + */ + protected function replaceNamespace(&$stub, $name) + { + $stub = str_replace( + 'DummyNamespace', $this->getNamespace($name), $stub + ); + + $stub = str_replace( + 'DummyRootNamespace', $this->laravel->getNamespace(), $stub + ); + + return $this; + } + + /** + * Get the full namespace name for a given class. + * + * @param string $name + * @return string + */ + protected function getNamespace($name) + { + return trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\'); + } + + /** + * Replace the class name for the given stub. + * + * @param string $stub + * @param string $name + * @return string + */ + protected function replaceClass($stub, $name) + { + $class = str_replace($this->getNamespace($name).'\\', '', $name); + + return str_replace('DummyClass', $class, $stub); + } + + /** + * Get the desired class name from the input. + * + * @return string + */ + protected function getNameInput() + { + return $this->argument('name'); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['name', InputArgument::REQUIRED, 'The name of the class'], + ]; + } +} diff --git a/vendor/illuminate/console/OutputStyle.php b/vendor/illuminate/console/OutputStyle.php new file mode 100644 index 0000000..925e66d --- /dev/null +++ b/vendor/illuminate/console/OutputStyle.php @@ -0,0 +1,71 @@ +output = $output; + + parent::__construct($input, $output); + } + + /** + * Returns whether verbosity is quiet (-q). + * + * @return bool + */ + public function isQuiet() + { + return $this->output->isQuiet(); + } + + /** + * Returns whether verbosity is verbose (-v). + * + * @return bool + */ + public function isVerbose() + { + return $this->output->isVerbose(); + } + + /** + * Returns whether verbosity is very verbose (-vv). + * + * @return bool + */ + public function isVeryVerbose() + { + return $this->output->isVeryVerbose(); + } + + /** + * Returns whether verbosity is debug (-vvv). + * + * @return bool + */ + public function isDebug() + { + return $this->output->isDebug(); + } +} diff --git a/vendor/illuminate/console/Parser.php b/vendor/illuminate/console/Parser.php new file mode 100644 index 0000000..22f6905 --- /dev/null +++ b/vendor/illuminate/console/Parser.php @@ -0,0 +1,141 @@ +commands('Illuminate\Console\Scheduling\ScheduleRunCommand'); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'Illuminate\Console\Scheduling\ScheduleRunCommand', + ]; + } +} diff --git a/vendor/illuminate/console/Scheduling/CallbackEvent.php b/vendor/illuminate/console/Scheduling/CallbackEvent.php new file mode 100644 index 0000000..494f0e8 --- /dev/null +++ b/vendor/illuminate/console/Scheduling/CallbackEvent.php @@ -0,0 +1,122 @@ +callback = $callback; + $this->parameters = $parameters; + + if (! is_string($this->callback) && ! is_callable($this->callback)) { + throw new InvalidArgumentException( + 'Invalid scheduled callback event. Must be string or callable.' + ); + } + } + + /** + * Run the given event. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return mixed + * + * @throws \Exception + */ + public function run(Container $container) + { + if ($this->description) { + touch($this->mutexPath()); + } + + try { + $response = $container->call($this->callback, $this->parameters); + } finally { + $this->removeMutex(); + } + + parent::callAfterCallbacks($container); + + return $response; + } + + /** + * Remove the mutex file from disk. + * + * @return void + */ + protected function removeMutex() + { + if ($this->description) { + @unlink($this->mutexPath()); + } + } + + /** + * Do not allow the event to overlap each other. + * + * @return $this + */ + public function withoutOverlapping() + { + if (! isset($this->description)) { + throw new LogicException( + "A scheduled event name is required to prevent overlapping. Use the 'name' method before 'withoutOverlapping'." + ); + } + + return $this->skip(function () { + return file_exists($this->mutexPath()); + }); + } + + /** + * Get the mutex path for the scheduled command. + * + * @return string + */ + protected function mutexPath() + { + return storage_path('framework/schedule-'.md5($this->description)); + } + + /** + * Get the summary of the event for display. + * + * @return string + */ + public function getSummaryForDisplay() + { + if (is_string($this->description)) { + return $this->description; + } + + return is_string($this->callback) ? $this->callback : 'Closure'; + } +} diff --git a/vendor/illuminate/console/Scheduling/Event.php b/vendor/illuminate/console/Scheduling/Event.php new file mode 100644 index 0000000..0be3e38 --- /dev/null +++ b/vendor/illuminate/console/Scheduling/Event.php @@ -0,0 +1,848 @@ +command = $command; + $this->output = $this->getDefaultOutput(); + } + + /** + * Get the default output depending on the OS. + * + * @return string + */ + protected function getDefaultOutput() + { + return (DIRECTORY_SEPARATOR == '\\') ? 'NUL' : '/dev/null'; + } + + /** + * Run the given event. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return void + */ + public function run(Container $container) + { + if (count($this->afterCallbacks) > 0 || count($this->beforeCallbacks) > 0) { + $this->runCommandInForeground($container); + } else { + $this->runCommandInBackground(); + } + } + + /** + * Run the command in the background using exec. + * + * @return void + */ + protected function runCommandInBackground() + { + chdir(base_path()); + + exec($this->buildCommand()); + } + + /** + * Run the command in the foreground. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return void + */ + protected function runCommandInForeground(Container $container) + { + $this->callBeforeCallbacks($container); + + (new Process( + trim($this->buildCommand(), '& '), base_path(), null, null, null + ))->run(); + + $this->callAfterCallbacks($container); + } + + /** + * Call all of the "before" callbacks for the event. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return void + */ + protected function callBeforeCallbacks(Container $container) + { + foreach ($this->beforeCallbacks as $callback) { + $container->call($callback); + } + } + + /** + * Call all of the "after" callbacks for the event. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return void + */ + protected function callAfterCallbacks(Container $container) + { + foreach ($this->afterCallbacks as $callback) { + $container->call($callback); + } + } + + /** + * Build the comand string. + * + * @return string + */ + public function buildCommand() + { + $redirect = $this->shouldAppendOutput ? ' >> ' : ' > '; + + if ($this->withoutOverlapping) { + $command = '(touch '.$this->mutexPath().'; '.$this->command.'; rm '.$this->mutexPath().')'.$redirect.$this->output.' 2>&1 &'; + } else { + $command = $this->command.$redirect.$this->output.' 2>&1 &'; + } + + return $this->user ? 'sudo -u '.$this->user.' '.$command : $command; + } + + /** + * Get the mutex path for the scheduled command. + * + * @return string + */ + protected function mutexPath() + { + return storage_path('framework/schedule-'.md5($this->expression.$this->command)); + } + + /** + * Determine if the given event should run based on the Cron expression. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @return bool + */ + public function isDue(Application $app) + { + if (! $this->runsInMaintenanceMode() && $app->isDownForMaintenance()) { + return false; + } + + return $this->expressionPasses() && + $this->filtersPass($app) && + $this->runsInEnvironment($app->environment()); + } + + /** + * Determine if the Cron expression passes. + * + * @return bool + */ + protected function expressionPasses() + { + $date = Carbon::now(); + + if ($this->timezone) { + $date->setTimezone($this->timezone); + } + + return CronExpression::factory($this->expression)->isDue($date->toDateTimeString()); + } + + /** + * Determine if the filters pass for the event. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @return bool + */ + protected function filtersPass(Application $app) + { + if (($this->filter && ! $app->call($this->filter)) || + $this->reject && $app->call($this->reject)) { + return false; + } + + return true; + } + + /** + * Determine if the event runs in the given environment. + * + * @param string $environment + * @return bool + */ + public function runsInEnvironment($environment) + { + return empty($this->environments) || in_array($environment, $this->environments); + } + + /** + * Determine if the event runs in maintenance mode. + * + * @return bool + */ + public function runsInMaintenanceMode() + { + return $this->evenInMaintenanceMode; + } + + /** + * The Cron expression representing the event's frequency. + * + * @param string $expression + * @return $this + */ + public function cron($expression) + { + $this->expression = $expression; + + return $this; + } + + /** + * Schedule the event to run hourly. + * + * @return $this + */ + public function hourly() + { + return $this->cron('0 * * * * *'); + } + + /** + * Schedule the event to run daily. + * + * @return $this + */ + public function daily() + { + return $this->cron('0 0 * * * *'); + } + + /** + * Schedule the command at a given time. + * + * @param string $time + * @return $this + */ + public function at($time) + { + return $this->dailyAt($time); + } + + /** + * Schedule the event to run daily at a given time (10:00, 19:30, etc). + * + * @param string $time + * @return $this + */ + public function dailyAt($time) + { + $segments = explode(':', $time); + + return $this->spliceIntoPosition(2, (int) $segments[0]) + ->spliceIntoPosition(1, count($segments) == 2 ? (int) $segments[1] : '0'); + } + + /** + * Schedule the event to run twice daily. + * + * @param int $first + * @param int $second + * @return $this + */ + public function twiceDaily($first = 1, $second = 13) + { + $hours = $first.','.$second; + + return $this->spliceIntoPosition(1, 0) + ->spliceIntoPosition(2, $hours); + } + + /** + * Schedule the event to run only on weekdays. + * + * @return $this + */ + public function weekdays() + { + return $this->spliceIntoPosition(5, '1-5'); + } + + /** + * Schedule the event to run only on Mondays. + * + * @return $this + */ + public function mondays() + { + return $this->days(1); + } + + /** + * Schedule the event to run only on Tuesdays. + * + * @return $this + */ + public function tuesdays() + { + return $this->days(2); + } + + /** + * Schedule the event to run only on Wednesdays. + * + * @return $this + */ + public function wednesdays() + { + return $this->days(3); + } + + /** + * Schedule the event to run only on Thursdays. + * + * @return $this + */ + public function thursdays() + { + return $this->days(4); + } + + /** + * Schedule the event to run only on Fridays. + * + * @return $this + */ + public function fridays() + { + return $this->days(5); + } + + /** + * Schedule the event to run only on Saturdays. + * + * @return $this + */ + public function saturdays() + { + return $this->days(6); + } + + /** + * Schedule the event to run only on Sundays. + * + * @return $this + */ + public function sundays() + { + return $this->days(0); + } + + /** + * Schedule the event to run weekly. + * + * @return $this + */ + public function weekly() + { + return $this->cron('0 0 * * 0 *'); + } + + /** + * Schedule the event to run weekly on a given day and time. + * + * @param int $day + * @param string $time + * @return $this + */ + public function weeklyOn($day, $time = '0:0') + { + $this->dailyAt($time); + + return $this->spliceIntoPosition(5, $day); + } + + /** + * Schedule the event to run monthly. + * + * @return $this + */ + public function monthly() + { + return $this->cron('0 0 1 * * *'); + } + + /** + * Schedule the event to run yearly. + * + * @return $this + */ + public function yearly() + { + return $this->cron('0 0 1 1 * *'); + } + + /** + * Schedule the event to run every minute. + * + * @return $this + */ + public function everyMinute() + { + return $this->cron('* * * * * *'); + } + + /** + * Schedule the event to run every five minutes. + * + * @return $this + */ + public function everyFiveMinutes() + { + return $this->cron('*/5 * * * * *'); + } + + /** + * Schedule the event to run every ten minutes. + * + * @return $this + */ + public function everyTenMinutes() + { + return $this->cron('*/10 * * * * *'); + } + + /** + * Schedule the event to run every thirty minutes. + * + * @return $this + */ + public function everyThirtyMinutes() + { + return $this->cron('0,30 * * * * *'); + } + + /** + * Set the days of the week the command should run on. + * + * @param array|mixed $days + * @return $this + */ + public function days($days) + { + $days = is_array($days) ? $days : func_get_args(); + + return $this->spliceIntoPosition(5, implode(',', $days)); + } + + /** + * Set the timezone the date should be evaluated on. + * + * @param \DateTimeZone|string $timezone + * @return $this + */ + public function timezone($timezone) + { + $this->timezone = $timezone; + + return $this; + } + + /** + * Set which user the command should run as. + * + * @param string $user + * @return $this + */ + public function user($user) + { + $this->user = $user; + + return $this; + } + + /** + * Limit the environments the command should run in. + * + * @param array|mixed $environments + * @return $this + */ + public function environments($environments) + { + $this->environments = is_array($environments) ? $environments : func_get_args(); + + return $this; + } + + /** + * State that the command should run even in maintenance mode. + * + * @return $this + */ + public function evenInMaintenanceMode() + { + $this->evenInMaintenanceMode = true; + + return $this; + } + + /** + * Do not allow the event to overlap each other. + * + * @return $this + */ + public function withoutOverlapping() + { + $this->withoutOverlapping = true; + + return $this->skip(function () { + return file_exists($this->mutexPath()); + }); + } + + /** + * Register a callback to further filter the schedule. + * + * @param \Closure $callback + * @return $this + */ + public function when(Closure $callback) + { + $this->filter = $callback; + + return $this; + } + + /** + * Register a callback to further filter the schedule. + * + * @param \Closure $callback + * @return $this + */ + public function skip(Closure $callback) + { + $this->reject = $callback; + + return $this; + } + + /** + * Send the output of the command to a given location. + * + * @param string $location + * @param bool $append + * @return $this + */ + public function sendOutputTo($location, $append = false) + { + $this->output = $location; + + $this->shouldAppendOutput = $append; + + return $this; + } + + /** + * Append the output of the command to a given location. + * + * @param string $location + * @return $this + */ + public function appendOutputTo($location) + { + return $this->sendOutputTo($location, true); + } + + /** + * E-mail the results of the scheduled operation. + * + * @param array|mixed $addresses + * @return $this + * + * @throws \LogicException + */ + public function emailOutputTo($addresses) + { + if (is_null($this->output) || $this->output == $this->getDefaultOutput()) { + throw new LogicException('Must direct output to a file in order to e-mail results.'); + } + + $addresses = is_array($addresses) ? $addresses : func_get_args(); + + return $this->then(function (Mailer $mailer) use ($addresses) { + $this->emailOutput($mailer, $addresses); + }); + } + + /** + * E-mail the output of the event to the recipients. + * + * @param \Illuminate\Contracts\Mail\Mailer $mailer + * @param array $addresses + * @return void + */ + protected function emailOutput(Mailer $mailer, $addresses) + { + $mailer->raw(file_get_contents($this->output), function ($m) use ($addresses) { + $m->subject($this->getEmailSubject()); + + foreach ($addresses as $address) { + $m->to($address); + } + }); + } + + /** + * Get the e-mail subject line for output results. + * + * @return string + */ + protected function getEmailSubject() + { + if ($this->description) { + return 'Scheduled Job Output ('.$this->description.')'; + } + + return 'Scheduled Job Output'; + } + + /** + * Register a callback to ping a given URL before the job runs. + * + * @param string $url + * @return $this + */ + public function pingBefore($url) + { + return $this->before(function () use ($url) { (new HttpClient)->get($url); }); + } + + /** + * Register a callback to be called before the operation. + * + * @param \Closure $callback + * @return $this + */ + public function before(Closure $callback) + { + $this->beforeCallbacks[] = $callback; + + return $this; + } + + /** + * Register a callback to ping a given URL after the job runs. + * + * @param string $url + * @return $this + */ + public function thenPing($url) + { + return $this->then(function () use ($url) { (new HttpClient)->get($url); }); + } + + /** + * Register a callback to be called after the operation. + * + * @param \Closure $callback + * @return $this + */ + public function after(Closure $callback) + { + return $this->then($callback); + } + + /** + * Register a callback to be called after the operation. + * + * @param \Closure $callback + * @return $this + */ + public function then(Closure $callback) + { + $this->afterCallbacks[] = $callback; + + return $this; + } + + /** + * Set the human-friendly description of the event. + * + * @param string $description + * @return $this + */ + public function name($description) + { + return $this->description($description); + } + + /** + * Set the human-friendly description of the event. + * + * @param string $description + * @return $this + */ + public function description($description) + { + $this->description = $description; + + return $this; + } + + /** + * Splice the given value into the given position of the expression. + * + * @param int $position + * @param string $value + * @return $this + */ + protected function spliceIntoPosition($position, $value) + { + $segments = explode(' ', $this->expression); + + $segments[$position - 1] = $value; + + return $this->cron(implode(' ', $segments)); + } + + /** + * Get the summary of the event for display. + * + * @return string + */ + public function getSummaryForDisplay() + { + if (is_string($this->description)) { + return $this->description; + } + + return $this->buildCommand(); + } + + /** + * Get the Cron expression for the event. + * + * @return string + */ + public function getExpression() + { + return $this->expression; + } +} diff --git a/vendor/illuminate/console/Scheduling/Schedule.php b/vendor/illuminate/console/Scheduling/Schedule.php new file mode 100644 index 0000000..1f56b3d --- /dev/null +++ b/vendor/illuminate/console/Scheduling/Schedule.php @@ -0,0 +1,109 @@ +events[] = $event = new CallbackEvent($callback, $parameters); + + return $event; + } + + /** + * Add a new Artisan command event to the schedule. + * + * @param string $command + * @param array $parameters + * @return \Illuminate\Console\Scheduling\Event + */ + public function command($command, array $parameters = []) + { + $binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)); + + if (defined('HHVM_VERSION')) { + $binary .= ' --php'; + } + + if (defined('ARTISAN_BINARY')) { + $artisan = ProcessUtils::escapeArgument(ARTISAN_BINARY); + } else { + $artisan = 'artisan'; + } + + return $this->exec("{$binary} {$artisan} {$command}", $parameters); + } + + /** + * Add a new command event to the schedule. + * + * @param string $command + * @param array $parameters + * @return \Illuminate\Console\Scheduling\Event + */ + public function exec($command, array $parameters = []) + { + if (count($parameters)) { + $command .= ' '.$this->compileParameters($parameters); + } + + $this->events[] = $event = new Event($command); + + return $event; + } + + /** + * Compile parameters for a command. + * + * @param array $parameters + * @return string + */ + protected function compileParameters(array $parameters) + { + return collect($parameters)->map(function ($value, $key) { + return is_numeric($key) ? $value : $key.'='.(is_numeric($value) ? $value : ProcessUtils::escapeArgument($value)); + })->implode(' '); + } + + /** + * Get all of the events on the schedule. + * + * @return array + */ + public function events() + { + return $this->events; + } + + /** + * Get all of the events on the schedule that are due. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @return array + */ + public function dueEvents(Application $app) + { + return array_filter($this->events, function ($event) use ($app) { + return $event->isDue($app); + }); + } +} diff --git a/vendor/illuminate/console/Scheduling/ScheduleRunCommand.php b/vendor/illuminate/console/Scheduling/ScheduleRunCommand.php new file mode 100644 index 0000000..3ce658c --- /dev/null +++ b/vendor/illuminate/console/Scheduling/ScheduleRunCommand.php @@ -0,0 +1,62 @@ +schedule = $schedule; + + parent::__construct(); + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $events = $this->schedule->dueEvents($this->laravel); + + foreach ($events as $event) { + $this->line('Running scheduled command: '.$event->getSummaryForDisplay()); + + $event->run($this->laravel); + } + + if (count($events) === 0) { + $this->info('No scheduled commands are ready to run.'); + } + } +} diff --git a/vendor/illuminate/console/composer.json b/vendor/illuminate/console/composer.json new file mode 100755 index 0000000..f78d161 --- /dev/null +++ b/vendor/illuminate/console/composer.json @@ -0,0 +1,39 @@ +{ + "name": "illuminate/console", + "description": "The Illuminate Console package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "symfony/console": "2.7.*", + "nesbot/carbon": "~1.19" + }, + "autoload": { + "psr-4": { + "Illuminate\\Console\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "guzzlehttp/guzzle": "Required to use the thenPing method on schedules (~5.3|~6.0).", + "mtdowling/cron-expression": "Required to use scheduling component (~1.0).", + "symfony/process": "Required to use scheduling component (2.7.*)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/container/BindingResolutionException.php b/vendor/illuminate/container/BindingResolutionException.php new file mode 100644 index 0000000..198963e --- /dev/null +++ b/vendor/illuminate/container/BindingResolutionException.php @@ -0,0 +1,13 @@ +bindings[$abstract]) || isset($this->instances[$abstract]) || $this->isAlias($abstract); + } + + /** + * Determine if the given abstract type has been resolved. + * + * @param string $abstract + * @return bool + */ + public function resolved($abstract) + { + return isset($this->resolved[$abstract]) || isset($this->instances[$abstract]); + } + + /** + * Determine if a given string is an alias. + * + * @param string $name + * @return bool + */ + public function isAlias($name) + { + return isset($this->aliases[$name]); + } + + /** + * Register a binding with the container. + * + * @param string|array $abstract + * @param \Closure|string|null $concrete + * @param bool $shared + * @return void + */ + public function bind($abstract, $concrete = null, $shared = false) + { + // If the given types are actually an array, we will assume an alias is being + // defined and will grab this "real" abstract class name and register this + // alias with the container so that it can be used as a shortcut for it. + if (is_array($abstract)) { + list($abstract, $alias) = $this->extractAlias($abstract); + + $this->alias($abstract, $alias); + } + + // If no concrete type was given, we will simply set the concrete type to the + // abstract type. This will allow concrete type to be registered as shared + // without being forced to state their classes in both of the parameter. + $this->dropStaleInstances($abstract); + + if (is_null($concrete)) { + $concrete = $abstract; + } + + // If the factory is not a Closure, it means it is just a class name which is + // bound into this container to the abstract type and we will just wrap it + // up inside its own Closure to give us more convenience when extending. + if (! $concrete instanceof Closure) { + $concrete = $this->getClosure($abstract, $concrete); + } + + $this->bindings[$abstract] = compact('concrete', 'shared'); + + // If the abstract type was already resolved in this container we'll fire the + // rebound listener so that any objects which have already gotten resolved + // can have their copy of the object updated via the listener callbacks. + if ($this->resolved($abstract)) { + $this->rebound($abstract); + } + } + + /** + * Get the Closure to be used when building a type. + * + * @param string $abstract + * @param string $concrete + * @return \Closure + */ + protected function getClosure($abstract, $concrete) + { + return function ($c, $parameters = []) use ($abstract, $concrete) { + $method = ($abstract == $concrete) ? 'build' : 'make'; + + return $c->$method($concrete, $parameters); + }; + } + + /** + * Add a contextual binding to the container. + * + * @param string $concrete + * @param string $abstract + * @param \Closure|string $implementation + * @return void + */ + public function addContextualBinding($concrete, $abstract, $implementation) + { + $this->contextual[$concrete][$abstract] = $implementation; + } + + /** + * Register a binding if it hasn't already been registered. + * + * @param string $abstract + * @param \Closure|string|null $concrete + * @param bool $shared + * @return void + */ + public function bindIf($abstract, $concrete = null, $shared = false) + { + if (! $this->bound($abstract)) { + $this->bind($abstract, $concrete, $shared); + } + } + + /** + * Register a shared binding in the container. + * + * @param string|array $abstract + * @param \Closure|string|null $concrete + * @return void + */ + public function singleton($abstract, $concrete = null) + { + $this->bind($abstract, $concrete, true); + } + + /** + * Wrap a Closure such that it is shared. + * + * @param \Closure $closure + * @return \Closure + */ + public function share(Closure $closure) + { + return function ($container) use ($closure) { + // We'll simply declare a static variable within the Closures and if it has + // not been set we will execute the given Closures to resolve this value + // and return it back to these consumers of the method as an instance. + static $object; + + if (is_null($object)) { + $object = $closure($container); + } + + return $object; + }; + } + + /** + * Bind a shared Closure into the container. + * + * @param string $abstract + * @param \Closure $closure + * @return void + * + * @deprecated since version 5.1. Use singleton instead. + */ + public function bindShared($abstract, Closure $closure) + { + $this->bind($abstract, $this->share($closure), true); + } + + /** + * "Extend" an abstract type in the container. + * + * @param string $abstract + * @param \Closure $closure + * @return void + * + * @throws \InvalidArgumentException + */ + public function extend($abstract, Closure $closure) + { + if (isset($this->instances[$abstract])) { + $this->instances[$abstract] = $closure($this->instances[$abstract], $this); + + $this->rebound($abstract); + } else { + $this->extenders[$abstract][] = $closure; + } + } + + /** + * Register an existing instance as shared in the container. + * + * @param string $abstract + * @param mixed $instance + * @return void + */ + public function instance($abstract, $instance) + { + // First, we will extract the alias from the abstract if it is an array so we + // are using the correct name when binding the type. If we get an alias it + // will be registered with the container so we can resolve it out later. + if (is_array($abstract)) { + list($abstract, $alias) = $this->extractAlias($abstract); + + $this->alias($abstract, $alias); + } + + unset($this->aliases[$abstract]); + + // We'll check to determine if this type has been bound before, and if it has + // we will fire the rebound callbacks registered with the container and it + // can be updated with consuming classes that have gotten resolved here. + $bound = $this->bound($abstract); + + $this->instances[$abstract] = $instance; + + if ($bound) { + $this->rebound($abstract); + } + } + + /** + * Assign a set of tags to a given binding. + * + * @param array|string $abstracts + * @param array|mixed ...$tags + * @return void + */ + public function tag($abstracts, $tags) + { + $tags = is_array($tags) ? $tags : array_slice(func_get_args(), 1); + + foreach ($tags as $tag) { + if (! isset($this->tags[$tag])) { + $this->tags[$tag] = []; + } + + foreach ((array) $abstracts as $abstract) { + $this->tags[$tag][] = $abstract; + } + } + } + + /** + * Resolve all of the bindings for a given tag. + * + * @param string $tag + * @return array + */ + public function tagged($tag) + { + $results = []; + + if (isset($this->tags[$tag])) { + foreach ($this->tags[$tag] as $abstract) { + $results[] = $this->make($abstract); + } + } + + return $results; + } + + /** + * Alias a type to a different name. + * + * @param string $abstract + * @param string $alias + * @return void + */ + public function alias($abstract, $alias) + { + $this->aliases[$alias] = $abstract; + } + + /** + * Extract the type and alias from a given definition. + * + * @param array $definition + * @return array + */ + protected function extractAlias(array $definition) + { + return [key($definition), current($definition)]; + } + + /** + * Bind a new callback to an abstract's rebind event. + * + * @param string $abstract + * @param \Closure $callback + * @return mixed + */ + public function rebinding($abstract, Closure $callback) + { + $this->reboundCallbacks[$abstract][] = $callback; + + if ($this->bound($abstract)) { + return $this->make($abstract); + } + } + + /** + * Refresh an instance on the given target and method. + * + * @param string $abstract + * @param mixed $target + * @param string $method + * @return mixed + */ + public function refresh($abstract, $target, $method) + { + return $this->rebinding($abstract, function ($app, $instance) use ($target, $method) { + $target->{$method}($instance); + }); + } + + /** + * Fire the "rebound" callbacks for the given abstract type. + * + * @param string $abstract + * @return void + */ + protected function rebound($abstract) + { + $instance = $this->make($abstract); + + foreach ($this->getReboundCallbacks($abstract) as $callback) { + call_user_func($callback, $this, $instance); + } + } + + /** + * Get the rebound callbacks for a given type. + * + * @param string $abstract + * @return array + */ + protected function getReboundCallbacks($abstract) + { + if (isset($this->reboundCallbacks[$abstract])) { + return $this->reboundCallbacks[$abstract]; + } + + return []; + } + + /** + * Wrap the given closure such that its dependencies will be injected when executed. + * + * @param \Closure $callback + * @param array $parameters + * @return \Closure + */ + public function wrap(Closure $callback, array $parameters = []) + { + return function () use ($callback, $parameters) { + return $this->call($callback, $parameters); + }; + } + + /** + * Call the given Closure / class@method and inject its dependencies. + * + * @param callable|string $callback + * @param array $parameters + * @param string|null $defaultMethod + * @return mixed + */ + public function call($callback, array $parameters = [], $defaultMethod = null) + { + if ($this->isCallableWithAtSign($callback) || $defaultMethod) { + return $this->callClass($callback, $parameters, $defaultMethod); + } + + $dependencies = $this->getMethodDependencies($callback, $parameters); + + return call_user_func_array($callback, $dependencies); + } + + /** + * Determine if the given string is in Class@method syntax. + * + * @param mixed $callback + * @return bool + */ + protected function isCallableWithAtSign($callback) + { + if (! is_string($callback)) { + return false; + } + + return strpos($callback, '@') !== false; + } + + /** + * Get all dependencies for a given method. + * + * @param callable|string $callback + * @param array $parameters + * @return array + */ + protected function getMethodDependencies($callback, array $parameters = []) + { + $dependencies = []; + + foreach ($this->getCallReflector($callback)->getParameters() as $key => $parameter) { + $this->addDependencyForCallParameter($parameter, $parameters, $dependencies); + } + + return array_merge($dependencies, $parameters); + } + + /** + * Get the proper reflection instance for the given callback. + * + * @param callable|string $callback + * @return \ReflectionFunctionAbstract + */ + protected function getCallReflector($callback) + { + if (is_string($callback) && strpos($callback, '::') !== false) { + $callback = explode('::', $callback); + } + + if (is_array($callback)) { + return new ReflectionMethod($callback[0], $callback[1]); + } + + return new ReflectionFunction($callback); + } + + /** + * Get the dependency for the given call parameter. + * + * @param \ReflectionParameter $parameter + * @param array $parameters + * @param array $dependencies + * @return mixed + */ + protected function addDependencyForCallParameter(ReflectionParameter $parameter, array &$parameters, &$dependencies) + { + if (array_key_exists($parameter->name, $parameters)) { + $dependencies[] = $parameters[$parameter->name]; + + unset($parameters[$parameter->name]); + } elseif ($parameter->getClass()) { + $dependencies[] = $this->make($parameter->getClass()->name); + } elseif ($parameter->isDefaultValueAvailable()) { + $dependencies[] = $parameter->getDefaultValue(); + } + } + + /** + * Call a string reference to a class using Class@method syntax. + * + * @param string $target + * @param array $parameters + * @param string|null $defaultMethod + * @return mixed + */ + protected function callClass($target, array $parameters = [], $defaultMethod = null) + { + $segments = explode('@', $target); + + // If the listener has an @ sign, we will assume it is being used to delimit + // the class name from the handle method name. This allows for handlers + // to run multiple handler methods in a single class for convenience. + $method = count($segments) == 2 ? $segments[1] : $defaultMethod; + + if (is_null($method)) { + throw new InvalidArgumentException('Method not provided.'); + } + + return $this->call([$this->make($segments[0]), $method], $parameters); + } + + /** + * Resolve the given type from the container. + * + * @param string $abstract + * @param array $parameters + * @return mixed + */ + public function make($abstract, array $parameters = []) + { + $abstract = $this->getAlias($abstract); + + // If an instance of the type is currently being managed as a singleton we'll + // just return an existing instance instead of instantiating new instances + // so the developer can keep using the same objects instance every time. + if (isset($this->instances[$abstract])) { + return $this->instances[$abstract]; + } + + $concrete = $this->getConcrete($abstract); + + // We're ready to instantiate an instance of the concrete type registered for + // the binding. This will instantiate the types, as well as resolve any of + // its "nested" dependencies recursively until all have gotten resolved. + if ($this->isBuildable($concrete, $abstract)) { + $object = $this->build($concrete, $parameters); + } else { + $object = $this->make($concrete, $parameters); + } + + // If we defined any extenders for this type, we'll need to spin through them + // and apply them to the object being built. This allows for the extension + // of services, such as changing configuration or decorating the object. + foreach ($this->getExtenders($abstract) as $extender) { + $object = $extender($object, $this); + } + + // If the requested type is registered as a singleton we'll want to cache off + // the instances in "memory" so we can return it later without creating an + // entirely new instance of an object on each subsequent request for it. + if ($this->isShared($abstract)) { + $this->instances[$abstract] = $object; + } + + $this->fireResolvingCallbacks($abstract, $object); + + $this->resolved[$abstract] = true; + + return $object; + } + + /** + * Get the concrete type for a given abstract. + * + * @param string $abstract + * @return mixed $concrete + */ + protected function getConcrete($abstract) + { + if (! is_null($concrete = $this->getContextualConcrete($abstract))) { + return $concrete; + } + + // If we don't have a registered resolver or concrete for the type, we'll just + // assume each type is a concrete name and will attempt to resolve it as is + // since the container should be able to resolve concretes automatically. + if (! isset($this->bindings[$abstract])) { + if ($this->missingLeadingSlash($abstract) && + isset($this->bindings['\\'.$abstract])) { + $abstract = '\\'.$abstract; + } + + return $abstract; + } + + return $this->bindings[$abstract]['concrete']; + } + + /** + * Get the contextual concrete binding for the given abstract. + * + * @param string $abstract + * @return string|null + */ + protected function getContextualConcrete($abstract) + { + if (isset($this->contextual[end($this->buildStack)][$abstract])) { + return $this->contextual[end($this->buildStack)][$abstract]; + } + } + + /** + * Determine if the given abstract has a leading slash. + * + * @param string $abstract + * @return bool + */ + protected function missingLeadingSlash($abstract) + { + return is_string($abstract) && strpos($abstract, '\\') !== 0; + } + + /** + * Get the extender callbacks for a given type. + * + * @param string $abstract + * @return array + */ + protected function getExtenders($abstract) + { + if (isset($this->extenders[$abstract])) { + return $this->extenders[$abstract]; + } + + return []; + } + + /** + * Instantiate a concrete instance of the given type. + * + * @param string $concrete + * @param array $parameters + * @return mixed + * + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function build($concrete, array $parameters = []) + { + // If the concrete type is actually a Closure, we will just execute it and + // hand back the results of the functions, which allows functions to be + // used as resolvers for more fine-tuned resolution of these objects. + if ($concrete instanceof Closure) { + return $concrete($this, $parameters); + } + + $reflector = new ReflectionClass($concrete); + + // If the type is not instantiable, the developer is attempting to resolve + // an abstract type such as an Interface of Abstract Class and there is + // no binding registered for the abstractions so we need to bail out. + if (! $reflector->isInstantiable()) { + $message = "Target [$concrete] is not instantiable."; + + throw new BindingResolutionContractException($message); + } + + $this->buildStack[] = $concrete; + + $constructor = $reflector->getConstructor(); + + // If there are no constructors, that means there are no dependencies then + // we can just resolve the instances of the objects right away, without + // resolving any other types or dependencies out of these containers. + if (is_null($constructor)) { + array_pop($this->buildStack); + + return new $concrete; + } + + $dependencies = $constructor->getParameters(); + + // Once we have all the constructor's parameters we can create each of the + // dependency instances and then use the reflection instances to make a + // new instance of this class, injecting the created dependencies in. + $parameters = $this->keyParametersByArgument( + $dependencies, $parameters + ); + + $instances = $this->getDependencies( + $dependencies, $parameters + ); + + array_pop($this->buildStack); + + return $reflector->newInstanceArgs($instances); + } + + /** + * Resolve all of the dependencies from the ReflectionParameters. + * + * @param array $parameters + * @param array $primitives + * @return array + */ + protected function getDependencies(array $parameters, array $primitives = []) + { + $dependencies = []; + + foreach ($parameters as $parameter) { + $dependency = $parameter->getClass(); + + // If the class is null, it means the dependency is a string or some other + // primitive type which we can not resolve since it is not a class and + // we will just bomb out with an error since we have no-where to go. + if (array_key_exists($parameter->name, $primitives)) { + $dependencies[] = $primitives[$parameter->name]; + } elseif (is_null($dependency)) { + $dependencies[] = $this->resolveNonClass($parameter); + } else { + $dependencies[] = $this->resolveClass($parameter); + } + } + + return (array) $dependencies; + } + + /** + * Resolve a non-class hinted dependency. + * + * @param \ReflectionParameter $parameter + * @return mixed + * + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + protected function resolveNonClass(ReflectionParameter $parameter) + { + if ($parameter->isDefaultValueAvailable()) { + return $parameter->getDefaultValue(); + } + + $message = "Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}"; + + throw new BindingResolutionContractException($message); + } + + /** + * Resolve a class based dependency from the container. + * + * @param \ReflectionParameter $parameter + * @return mixed + * + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + protected function resolveClass(ReflectionParameter $parameter) + { + try { + return $this->make($parameter->getClass()->name); + } + + // If we can not resolve the class instance, we will check to see if the value + // is optional, and if it is we will return the optional parameter value as + // the value of the dependency, similarly to how we do this with scalars. + catch (BindingResolutionContractException $e) { + if ($parameter->isOptional()) { + return $parameter->getDefaultValue(); + } + + throw $e; + } + } + + /** + * If extra parameters are passed by numeric ID, rekey them by argument name. + * + * @param array $dependencies + * @param array $parameters + * @return array + */ + protected function keyParametersByArgument(array $dependencies, array $parameters) + { + foreach ($parameters as $key => $value) { + if (is_numeric($key)) { + unset($parameters[$key]); + + $parameters[$dependencies[$key]->name] = $value; + } + } + + return $parameters; + } + + /** + * Register a new resolving callback. + * + * @param string $abstract + * @param \Closure|null $callback + * @return void + */ + public function resolving($abstract, Closure $callback = null) + { + if ($callback === null && $abstract instanceof Closure) { + $this->resolvingCallback($abstract); + } else { + $this->resolvingCallbacks[$abstract][] = $callback; + } + } + + /** + * Register a new after resolving callback for all types. + * + * @param string $abstract + * @param \Closure|null $callback + * @return void + */ + public function afterResolving($abstract, Closure $callback = null) + { + if ($abstract instanceof Closure && $callback === null) { + $this->afterResolvingCallback($abstract); + } else { + $this->afterResolvingCallbacks[$abstract][] = $callback; + } + } + + /** + * Register a new resolving callback by type of its first argument. + * + * @param \Closure $callback + * @return void + */ + protected function resolvingCallback(Closure $callback) + { + $abstract = $this->getFunctionHint($callback); + + if ($abstract) { + $this->resolvingCallbacks[$abstract][] = $callback; + } else { + $this->globalResolvingCallbacks[] = $callback; + } + } + + /** + * Register a new after resolving callback by type of its first argument. + * + * @param \Closure $callback + * @return void + */ + protected function afterResolvingCallback(Closure $callback) + { + $abstract = $this->getFunctionHint($callback); + + if ($abstract) { + $this->afterResolvingCallbacks[$abstract][] = $callback; + } else { + $this->globalAfterResolvingCallbacks[] = $callback; + } + } + + /** + * Get the type hint for this closure's first argument. + * + * @param \Closure $callback + * @return mixed + */ + protected function getFunctionHint(Closure $callback) + { + $function = new ReflectionFunction($callback); + + if ($function->getNumberOfParameters() == 0) { + return; + } + + $expected = $function->getParameters()[0]; + + if (! $expected->getClass()) { + return; + } + + return $expected->getClass()->name; + } + + /** + * Fire all of the resolving callbacks. + * + * @param string $abstract + * @param mixed $object + * @return void + */ + protected function fireResolvingCallbacks($abstract, $object) + { + $this->fireCallbackArray($object, $this->globalResolvingCallbacks); + + $this->fireCallbackArray( + $object, $this->getCallbacksForType( + $abstract, $object, $this->resolvingCallbacks + ) + ); + + $this->fireCallbackArray($object, $this->globalAfterResolvingCallbacks); + + $this->fireCallbackArray( + $object, $this->getCallbacksForType( + $abstract, $object, $this->afterResolvingCallbacks + ) + ); + } + + /** + * Get all callbacks for a given type. + * + * @param string $abstract + * @param object $object + * @param array $callbacksPerType + * + * @return array + */ + protected function getCallbacksForType($abstract, $object, array $callbacksPerType) + { + $results = []; + + foreach ($callbacksPerType as $type => $callbacks) { + if ($type === $abstract || $object instanceof $type) { + $results = array_merge($results, $callbacks); + } + } + + return $results; + } + + /** + * Fire an array of callbacks with an object. + * + * @param mixed $object + * @param array $callbacks + * @return void + */ + protected function fireCallbackArray($object, array $callbacks) + { + foreach ($callbacks as $callback) { + $callback($object, $this); + } + } + + /** + * Determine if a given type is shared. + * + * @param string $abstract + * @return bool + */ + public function isShared($abstract) + { + if (isset($this->bindings[$abstract]['shared'])) { + $shared = $this->bindings[$abstract]['shared']; + } else { + $shared = false; + } + + return isset($this->instances[$abstract]) || $shared === true; + } + + /** + * Determine if the given concrete is buildable. + * + * @param mixed $concrete + * @param string $abstract + * @return bool + */ + protected function isBuildable($concrete, $abstract) + { + return $concrete === $abstract || $concrete instanceof Closure; + } + + /** + * Get the alias for an abstract if available. + * + * @param string $abstract + * @return string + */ + protected function getAlias($abstract) + { + return isset($this->aliases[$abstract]) ? $this->aliases[$abstract] : $abstract; + } + + /** + * Get the container's bindings. + * + * @return array + */ + public function getBindings() + { + return $this->bindings; + } + + /** + * Drop all of the stale instances and aliases. + * + * @param string $abstract + * @return void + */ + protected function dropStaleInstances($abstract) + { + unset($this->instances[$abstract], $this->aliases[$abstract]); + } + + /** + * Remove a resolved instance from the instance cache. + * + * @param string $abstract + * @return void + */ + public function forgetInstance($abstract) + { + unset($this->instances[$abstract]); + } + + /** + * Clear all of the instances from the container. + * + * @return void + */ + public function forgetInstances() + { + $this->instances = []; + } + + /** + * Flush the container of all bindings and resolved instances. + * + * @return void + */ + public function flush() + { + $this->aliases = []; + $this->resolved = []; + $this->bindings = []; + $this->instances = []; + } + + /** + * Set the globally available instance of the container. + * + * @return static + */ + public static function getInstance() + { + return static::$instance; + } + + /** + * Set the shared instance of the container. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return void + */ + public static function setInstance(ContainerContract $container) + { + static::$instance = $container; + } + + /** + * Determine if a given offset exists. + * + * @param string $key + * @return bool + */ + public function offsetExists($key) + { + return isset($this->bindings[$key]); + } + + /** + * Get the value at a given offset. + * + * @param string $key + * @return mixed + */ + public function offsetGet($key) + { + return $this->make($key); + } + + /** + * Set the value at a given offset. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + // If the value is not a Closure, we will make it one. This simply gives + // more "drop-in" replacement functionality for the Pimple which this + // container's simplest functions are base modeled and built after. + if (! $value instanceof Closure) { + $value = function () use ($value) { + return $value; + }; + } + + $this->bind($key, $value); + } + + /** + * Unset the value at a given offset. + * + * @param string $key + * @return void + */ + public function offsetUnset($key) + { + unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]); + } + + /** + * Dynamically access container services. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + return $this[$key]; + } + + /** + * Dynamically set container services. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function __set($key, $value) + { + $this[$key] = $value; + } +} diff --git a/vendor/illuminate/container/ContextualBindingBuilder.php b/vendor/illuminate/container/ContextualBindingBuilder.php new file mode 100644 index 0000000..fc5cd61 --- /dev/null +++ b/vendor/illuminate/container/ContextualBindingBuilder.php @@ -0,0 +1,66 @@ +concrete = $concrete; + $this->container = $container; + } + + /** + * Define the abstract target that depends on the context. + * + * @param string $abstract + * @return $this + */ + public function needs($abstract) + { + $this->needs = $abstract; + + return $this; + } + + /** + * Define the implementation for the contextual binding. + * + * @param \Closure|string $implementation + * @return void + */ + public function give($implementation) + { + $this->container->addContextualBinding($this->concrete, $this->needs, $implementation); + } +} diff --git a/vendor/illuminate/container/composer.json b/vendor/illuminate/container/composer.json new file mode 100755 index 0000000..567d018 --- /dev/null +++ b/vendor/illuminate/container/composer.json @@ -0,0 +1,31 @@ +{ + "name": "illuminate/container", + "description": "The Illuminate Container package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Container\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/contracts/Auth/Access/Authorizable.php b/vendor/illuminate/contracts/Auth/Access/Authorizable.php new file mode 100644 index 0000000..2f9657c --- /dev/null +++ b/vendor/illuminate/contracts/Auth/Access/Authorizable.php @@ -0,0 +1,15 @@ +id = $id; + $this->class = $class; + } +} diff --git a/vendor/illuminate/contracts/Debug/ExceptionHandler.php b/vendor/illuminate/contracts/Debug/ExceptionHandler.php new file mode 100644 index 0000000..e3f18a5 --- /dev/null +++ b/vendor/illuminate/contracts/Debug/ExceptionHandler.php @@ -0,0 +1,34 @@ +provider = $provider; + } + + /** + * Get the validation error message provider. + * + * @return \Illuminate\Contracts\Support\MessageBag + */ + public function errors() + { + return $this->provider->getMessageBag(); + } + + /** + * Get the validation error message provider. + * + * @return \Illuminate\Contracts\Support\MessageProvider + */ + public function getMessageProvider() + { + return $this->provider; + } +} diff --git a/vendor/illuminate/contracts/Validation/Validator.php b/vendor/illuminate/contracts/Validation/Validator.php new file mode 100644 index 0000000..9cf68c7 --- /dev/null +++ b/vendor/illuminate/contracts/Validation/Validator.php @@ -0,0 +1,40 @@ +=5.5.9" + }, + "autoload": { + "psr-4": { + "Illuminate\\Contracts\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/cookie/CookieJar.php b/vendor/illuminate/cookie/CookieJar.php new file mode 100755 index 0000000..3cfcbf7 --- /dev/null +++ b/vendor/illuminate/cookie/CookieJar.php @@ -0,0 +1,168 @@ +getPathAndDomain($path, $domain); + + $time = ($minutes == 0) ? 0 : time() + ($minutes * 60); + + return new Cookie($name, $value, $time, $path, $domain, $secure, $httpOnly); + } + + /** + * Create a cookie that lasts "forever" (five years). + * + * @param string $name + * @param string $value + * @param string $path + * @param string $domain + * @param bool $secure + * @param bool $httpOnly + * @return \Symfony\Component\HttpFoundation\Cookie + */ + public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true) + { + return $this->make($name, $value, 2628000, $path, $domain, $secure, $httpOnly); + } + + /** + * Expire the given cookie. + * + * @param string $name + * @param string $path + * @param string $domain + * @return \Symfony\Component\HttpFoundation\Cookie + */ + public function forget($name, $path = null, $domain = null) + { + return $this->make($name, null, -2628000, $path, $domain); + } + + /** + * Determine if a cookie has been queued. + * + * @param string $key + * @return bool + */ + public function hasQueued($key) + { + return ! is_null($this->queued($key)); + } + + /** + * Get a queued cookie instance. + * + * @param string $key + * @param mixed $default + * @return \Symfony\Component\HttpFoundation\Cookie + */ + public function queued($key, $default = null) + { + return Arr::get($this->queued, $key, $default); + } + + /** + * Queue a cookie to send with the next response. + * + * @param mixed + * @return void + */ + public function queue() + { + if (head(func_get_args()) instanceof Cookie) { + $cookie = head(func_get_args()); + } else { + $cookie = call_user_func_array([$this, 'make'], func_get_args()); + } + + $this->queued[$cookie->getName()] = $cookie; + } + + /** + * Remove a cookie from the queue. + * + * @param string $name + * @return void + */ + public function unqueue($name) + { + unset($this->queued[$name]); + } + + /** + * Get the path and domain, or the default values. + * + * @param string $path + * @param string $domain + * @return array + */ + protected function getPathAndDomain($path, $domain) + { + return [$path ?: $this->path, $domain ?: $this->domain]; + } + + /** + * Set the default path and domain for the jar. + * + * @param string $path + * @param string $domain + * @return $this + */ + public function setDefaultPathAndDomain($path, $domain) + { + list($this->path, $this->domain) = [$path, $domain]; + + return $this; + } + + /** + * Get the cookies which have been queued for the next request. + * + * @return array + */ + public function getQueuedCookies() + { + return $this->queued; + } +} diff --git a/vendor/illuminate/cookie/CookieServiceProvider.php b/vendor/illuminate/cookie/CookieServiceProvider.php new file mode 100755 index 0000000..c5c0dbc --- /dev/null +++ b/vendor/illuminate/cookie/CookieServiceProvider.php @@ -0,0 +1,22 @@ +app->singleton('cookie', function ($app) { + $config = $app['config']['session']; + + return (new CookieJar)->setDefaultPathAndDomain($config['path'], $config['domain']); + }); + } +} diff --git a/vendor/illuminate/cookie/Middleware/AddQueuedCookiesToResponse.php b/vendor/illuminate/cookie/Middleware/AddQueuedCookiesToResponse.php new file mode 100644 index 0000000..4caa574 --- /dev/null +++ b/vendor/illuminate/cookie/Middleware/AddQueuedCookiesToResponse.php @@ -0,0 +1,45 @@ +cookies = $cookies; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + $response = $next($request); + + foreach ($this->cookies->getQueuedCookies() as $cookie) { + $response->headers->setCookie($cookie); + } + + return $response; + } +} diff --git a/vendor/illuminate/cookie/Middleware/EncryptCookies.php b/vendor/illuminate/cookie/Middleware/EncryptCookies.php new file mode 100644 index 0000000..3bb9abf --- /dev/null +++ b/vendor/illuminate/cookie/Middleware/EncryptCookies.php @@ -0,0 +1,161 @@ +encrypter = $encrypter; + } + + /** + * Disable encryption for the given cookie name(s). + * + * @param string|array $cookieName + * @return void + */ + public function disableFor($cookieName) + { + $this->except = array_merge($this->except, (array) $cookieName); + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + return $this->encrypt($next($this->decrypt($request))); + } + + /** + * Decrypt the cookies on the request. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * @return \Symfony\Component\HttpFoundation\Request + */ + protected function decrypt(Request $request) + { + foreach ($request->cookies as $key => $c) { + if ($this->isDisabled($key)) { + continue; + } + + try { + $request->cookies->set($key, $this->decryptCookie($c)); + } catch (DecryptException $e) { + $request->cookies->set($key, null); + } + } + + return $request; + } + + /** + * Decrypt the given cookie and return the value. + * + * @param string|array $cookie + * @return string|array + */ + protected function decryptCookie($cookie) + { + return is_array($cookie) + ? $this->decryptArray($cookie) + : $this->encrypter->decrypt($cookie); + } + + /** + * Decrypt an array based cookie. + * + * @param array $cookie + * @return array + */ + protected function decryptArray(array $cookie) + { + $decrypted = []; + + foreach ($cookie as $key => $value) { + $decrypted[$key] = $this->encrypter->decrypt($value); + } + + return $decrypted; + } + + /** + * Encrypt the cookies on an outgoing response. + * + * @param \Symfony\Component\HttpFoundation\Response $response + * @return \Symfony\Component\HttpFoundation\Response + */ + protected function encrypt(Response $response) + { + foreach ($response->headers->getCookies() as $cookie) { + if ($this->isDisabled($cookie->getName())) { + continue; + } + + $response->headers->setCookie($this->duplicate( + $cookie, $this->encrypter->encrypt($cookie->getValue()) + )); + } + + return $response; + } + + /** + * Duplicate a cookie with a new value. + * + * @param \Symfony\Component\HttpFoundation\Cookie $c + * @param mixed $value + * @return \Symfony\Component\HttpFoundation\Cookie + */ + protected function duplicate(Cookie $c, $value) + { + return new Cookie( + $c->getName(), $value, $c->getExpiresTime(), $c->getPath(), + $c->getDomain(), $c->isSecure(), $c->isHttpOnly() + ); + } + + /** + * Determine whether encryption has been disabled for the given cookie. + * + * @param string $name + * @return bool + */ + public function isDisabled($name) + { + return in_array($name, $this->except); + } +} diff --git a/vendor/illuminate/cookie/composer.json b/vendor/illuminate/cookie/composer.json new file mode 100755 index 0000000..a3c3312 --- /dev/null +++ b/vendor/illuminate/cookie/composer.json @@ -0,0 +1,34 @@ +{ + "name": "illuminate/cookie", + "description": "The Illuminate Cookie package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "symfony/http-kernel": "2.7.*", + "symfony/http-foundation": "2.7.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Cookie\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/database/Capsule/Manager.php b/vendor/illuminate/database/Capsule/Manager.php new file mode 100755 index 0000000..1a14401 --- /dev/null +++ b/vendor/illuminate/database/Capsule/Manager.php @@ -0,0 +1,201 @@ +setupContainer($container ?: new Container); + + // Once we have the container setup, we will setup the default configuration + // options in the container "config" binding. This will make the database + // manager behave correctly since all the correct binding are in place. + $this->setupDefaultConfiguration(); + + $this->setupManager(); + } + + /** + * Setup the default database configuration options. + * + * @return void + */ + protected function setupDefaultConfiguration() + { + $this->container['config']['database.fetch'] = PDO::FETCH_OBJ; + + $this->container['config']['database.default'] = 'default'; + } + + /** + * Build the database manager instance. + * + * @return void + */ + protected function setupManager() + { + $factory = new ConnectionFactory($this->container); + + $this->manager = new DatabaseManager($this->container, $factory); + } + + /** + * Get a connection instance from the global manager. + * + * @param string $connection + * @return \Illuminate\Database\Connection + */ + public static function connection($connection = null) + { + return static::$instance->getConnection($connection); + } + + /** + * Get a fluent query builder instance. + * + * @param string $table + * @param string $connection + * @return \Illuminate\Database\Query\Builder + */ + public static function table($table, $connection = null) + { + return static::$instance->connection($connection)->table($table); + } + + /** + * Get a schema builder instance. + * + * @param string $connection + * @return \Illuminate\Database\Schema\Builder + */ + public static function schema($connection = null) + { + return static::$instance->connection($connection)->getSchemaBuilder(); + } + + /** + * Get a registered connection instance. + * + * @param string $name + * @return \Illuminate\Database\Connection + */ + public function getConnection($name = null) + { + return $this->manager->connection($name); + } + + /** + * Register a connection with the manager. + * + * @param array $config + * @param string $name + * @return void + */ + public function addConnection(array $config, $name = 'default') + { + $connections = $this->container['config']['database.connections']; + + $connections[$name] = $config; + + $this->container['config']['database.connections'] = $connections; + } + + /** + * Bootstrap Eloquent so it is ready for usage. + * + * @return void + */ + public function bootEloquent() + { + Eloquent::setConnectionResolver($this->manager); + + // If we have an event dispatcher instance, we will go ahead and register it + // with the Eloquent ORM, allowing for model callbacks while creating and + // updating "model" instances; however, if it not necessary to operate. + if ($dispatcher = $this->getEventDispatcher()) { + Eloquent::setEventDispatcher($dispatcher); + } + } + + /** + * Set the fetch mode for the database connections. + * + * @param int $fetchMode + * @return $this + */ + public function setFetchMode($fetchMode) + { + $this->container['config']['database.fetch'] = $fetchMode; + + return $this; + } + + /** + * Get the database manager instance. + * + * @return \Illuminate\Database\DatabaseManager + */ + public function getDatabaseManager() + { + return $this->manager; + } + + /** + * Get the current event dispatcher instance. + * + * @return \Illuminate\Contracts\Events\Dispatcher|null + */ + public function getEventDispatcher() + { + if ($this->container->bound('events')) { + return $this->container['events']; + } + } + + /** + * Set the event dispatcher instance to be used by connections. + * + * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher + * @return void + */ + public function setEventDispatcher(Dispatcher $dispatcher) + { + $this->container->instance('events', $dispatcher); + } + + /** + * Dynamically pass methods to the default connection. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public static function __callStatic($method, $parameters) + { + return call_user_func_array([static::connection(), $method], $parameters); + } +} diff --git a/vendor/illuminate/database/Connection.php b/vendor/illuminate/database/Connection.php new file mode 100755 index 0000000..d966e75 --- /dev/null +++ b/vendor/illuminate/database/Connection.php @@ -0,0 +1,1148 @@ +pdo = $pdo; + + // First we will setup the default properties. We keep track of the DB + // name we are connected to since it is needed when some reflective + // type commands are run such as checking whether a table exists. + $this->database = $database; + + $this->tablePrefix = $tablePrefix; + + $this->config = $config; + + // We need to initialize a query grammar and the query post processors + // which are both very important parts of the database abstractions + // so we initialize these to their default values while starting. + $this->useDefaultQueryGrammar(); + + $this->useDefaultPostProcessor(); + } + + /** + * Set the query grammar to the default implementation. + * + * @return void + */ + public function useDefaultQueryGrammar() + { + $this->queryGrammar = $this->getDefaultQueryGrammar(); + } + + /** + * Get the default query grammar instance. + * + * @return \Illuminate\Database\Query\Grammars\Grammar + */ + protected function getDefaultQueryGrammar() + { + return new QueryGrammar; + } + + /** + * Set the schema grammar to the default implementation. + * + * @return void + */ + public function useDefaultSchemaGrammar() + { + $this->schemaGrammar = $this->getDefaultSchemaGrammar(); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\Grammar + */ + protected function getDefaultSchemaGrammar() + { + // + } + + /** + * Set the query post processor to the default implementation. + * + * @return void + */ + public function useDefaultPostProcessor() + { + $this->postProcessor = $this->getDefaultPostProcessor(); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\Processor + */ + protected function getDefaultPostProcessor() + { + return new Processor; + } + + /** + * Get a schema builder instance for the connection. + * + * @return \Illuminate\Database\Schema\Builder + */ + public function getSchemaBuilder() + { + if (is_null($this->schemaGrammar)) { + $this->useDefaultSchemaGrammar(); + } + + return new SchemaBuilder($this); + } + + /** + * Begin a fluent query against a database table. + * + * @param string $table + * @return \Illuminate\Database\Query\Builder + */ + public function table($table) + { + return $this->query()->from($table); + } + + /** + * Get a new query builder instance. + * + * @return \Illuminate\Database\Query\Builder + */ + public function query() + { + return new QueryBuilder( + $this, $this->getQueryGrammar(), $this->getPostProcessor() + ); + } + + /** + * Get a new raw query expression. + * + * @param mixed $value + * @return \Illuminate\Database\Query\Expression + */ + public function raw($value) + { + return new Expression($value); + } + + /** + * Run a select statement and return a single result. + * + * @param string $query + * @param array $bindings + * @return mixed + */ + public function selectOne($query, $bindings = []) + { + $records = $this->select($query, $bindings); + + return count($records) > 0 ? reset($records) : null; + } + + /** + * Run a select statement against the database. + * + * @param string $query + * @param array $bindings + * @return array + */ + public function selectFromWriteConnection($query, $bindings = []) + { + return $this->select($query, $bindings, false); + } + + /** + * Run a select statement against the database. + * + * @param string $query + * @param array $bindings + * @param bool $useReadPdo + * @return array + */ + public function select($query, $bindings = [], $useReadPdo = true) + { + return $this->run($query, $bindings, function ($me, $query, $bindings) use ($useReadPdo) { + if ($me->pretending()) { + return []; + } + + // For select statements, we'll simply execute the query and return an array + // of the database result set. Each element in the array will be a single + // row from the database table, and will either be an array or objects. + $statement = $this->getPdoForSelect($useReadPdo)->prepare($query); + + $statement->execute($me->prepareBindings($bindings)); + + return $statement->fetchAll($me->getFetchMode()); + }); + } + + /** + * Get the PDO connection to use for a select query. + * + * @param bool $useReadPdo + * @return \PDO + */ + protected function getPdoForSelect($useReadPdo = true) + { + return $useReadPdo ? $this->getReadPdo() : $this->getPdo(); + } + + /** + * Run an insert statement against the database. + * + * @param string $query + * @param array $bindings + * @return bool + */ + public function insert($query, $bindings = []) + { + return $this->statement($query, $bindings); + } + + /** + * Run an update statement against the database. + * + * @param string $query + * @param array $bindings + * @return int + */ + public function update($query, $bindings = []) + { + return $this->affectingStatement($query, $bindings); + } + + /** + * Run a delete statement against the database. + * + * @param string $query + * @param array $bindings + * @return int + */ + public function delete($query, $bindings = []) + { + return $this->affectingStatement($query, $bindings); + } + + /** + * Execute an SQL statement and return the boolean result. + * + * @param string $query + * @param array $bindings + * @return bool + */ + public function statement($query, $bindings = []) + { + return $this->run($query, $bindings, function ($me, $query, $bindings) { + if ($me->pretending()) { + return true; + } + + $bindings = $me->prepareBindings($bindings); + + return $me->getPdo()->prepare($query)->execute($bindings); + }); + } + + /** + * Run an SQL statement and get the number of rows affected. + * + * @param string $query + * @param array $bindings + * @return int + */ + public function affectingStatement($query, $bindings = []) + { + return $this->run($query, $bindings, function ($me, $query, $bindings) { + if ($me->pretending()) { + return 0; + } + + // For update or delete statements, we want to get the number of rows affected + // by the statement and return that back to the developer. We'll first need + // to execute the statement and then we'll use PDO to fetch the affected. + $statement = $me->getPdo()->prepare($query); + + $statement->execute($me->prepareBindings($bindings)); + + return $statement->rowCount(); + }); + } + + /** + * Run a raw, unprepared query against the PDO connection. + * + * @param string $query + * @return bool + */ + public function unprepared($query) + { + return $this->run($query, [], function ($me, $query) { + if ($me->pretending()) { + return true; + } + + return (bool) $me->getPdo()->exec($query); + }); + } + + /** + * Prepare the query bindings for execution. + * + * @param array $bindings + * @return array + */ + public function prepareBindings(array $bindings) + { + $grammar = $this->getQueryGrammar(); + + foreach ($bindings as $key => $value) { + // We need to transform all instances of DateTimeInterface into the actual + // date string. Each query grammar maintains its own date string format + // so we'll just ask the grammar for the format to get from the date. + if ($value instanceof DateTimeInterface) { + $bindings[$key] = $value->format($grammar->getDateFormat()); + } elseif ($value === false) { + $bindings[$key] = 0; + } + } + + return $bindings; + } + + /** + * Execute a Closure within a transaction. + * + * @param \Closure $callback + * @return mixed + * + * @throws \Throwable + */ + public function transaction(Closure $callback) + { + $this->beginTransaction(); + + // We'll simply execute the given callback within a try / catch block + // and if we catch any exception we can rollback the transaction + // so that none of the changes are persisted to the database. + try { + $result = $callback($this); + + $this->commit(); + } + + // If we catch an exception, we will roll back so nothing gets messed + // up in the database. Then we'll re-throw the exception so it can + // be handled how the developer sees fit for their applications. + catch (Exception $e) { + $this->rollBack(); + + throw $e; + } catch (Throwable $e) { + $this->rollBack(); + + throw $e; + } + + return $result; + } + + /** + * Start a new database transaction. + * + * @return void + */ + public function beginTransaction() + { + ++$this->transactions; + + if ($this->transactions == 1) { + $this->pdo->beginTransaction(); + } elseif ($this->transactions > 1 && $this->queryGrammar->supportsSavepoints()) { + $this->pdo->exec( + $this->queryGrammar->compileSavepoint('trans'.$this->transactions) + ); + } + + $this->fireConnectionEvent('beganTransaction'); + } + + /** + * Commit the active database transaction. + * + * @return void + */ + public function commit() + { + if ($this->transactions == 1) { + $this->pdo->commit(); + } + + --$this->transactions; + + $this->fireConnectionEvent('committed'); + } + + /** + * Rollback the active database transaction. + * + * @return void + */ + public function rollBack() + { + if ($this->transactions == 1) { + $this->pdo->rollBack(); + } elseif ($this->transactions > 1 && $this->queryGrammar->supportsSavepoints()) { + $this->pdo->exec( + $this->queryGrammar->compileSavepointRollBack('trans'.$this->transactions) + ); + } + + $this->transactions = max(0, $this->transactions - 1); + + $this->fireConnectionEvent('rollingBack'); + } + + /** + * Get the number of active transactions. + * + * @return int + */ + public function transactionLevel() + { + return $this->transactions; + } + + /** + * Execute the given callback in "dry run" mode. + * + * @param \Closure $callback + * @return array + */ + public function pretend(Closure $callback) + { + $loggingQueries = $this->loggingQueries; + + $this->enableQueryLog(); + + $this->pretending = true; + + $this->queryLog = []; + + // Basically to make the database connection "pretend", we will just return + // the default values for all the query methods, then we will return an + // array of queries that were "executed" within the Closure callback. + $callback($this); + + $this->pretending = false; + + $this->loggingQueries = $loggingQueries; + + return $this->queryLog; + } + + /** + * Run a SQL statement and log its execution context. + * + * @param string $query + * @param array $bindings + * @param \Closure $callback + * @return mixed + * + * @throws \Illuminate\Database\QueryException + */ + protected function run($query, $bindings, Closure $callback) + { + $this->reconnectIfMissingConnection(); + + $start = microtime(true); + + // Here we will run this query. If an exception occurs we'll determine if it was + // caused by a connection that has been lost. If that is the cause, we'll try + // to re-establish connection and re-run the query with a fresh connection. + try { + $result = $this->runQueryCallback($query, $bindings, $callback); + } catch (QueryException $e) { + $result = $this->tryAgainIfCausedByLostConnection( + $e, $query, $bindings, $callback + ); + } + + // Once we have run the query we will calculate the time that it took to run and + // then log the query, bindings, and execution time so we will report them on + // the event that the developer needs them. We'll log time in milliseconds. + $time = $this->getElapsedTime($start); + + $this->logQuery($query, $bindings, $time); + + return $result; + } + + /** + * Run a SQL statement. + * + * @param string $query + * @param array $bindings + * @param \Closure $callback + * @return mixed + * + * @throws \Illuminate\Database\QueryException + */ + protected function runQueryCallback($query, $bindings, Closure $callback) + { + // To execute the statement, we'll simply call the callback, which will actually + // run the SQL against the PDO connection. Then we can calculate the time it + // took to execute and log the query SQL, bindings and time in our memory. + try { + $result = $callback($this, $query, $bindings); + } + + // If an exception occurs when attempting to run a query, we'll format the error + // message to include the bindings with SQL, which will make this exception a + // lot more helpful to the developer instead of just the database's errors. + catch (Exception $e) { + throw new QueryException( + $query, $this->prepareBindings($bindings), $e + ); + } + + return $result; + } + + /** + * Handle a query exception that occurred during query execution. + * + * @param \Illuminate\Database\QueryException $e + * @param string $query + * @param array $bindings + * @param \Closure $callback + * @return mixed + * + * @throws \Illuminate\Database\QueryException + */ + protected function tryAgainIfCausedByLostConnection(QueryException $e, $query, $bindings, Closure $callback) + { + if ($this->causedByLostConnection($e->getPrevious())) { + $this->reconnect(); + + return $this->runQueryCallback($query, $bindings, $callback); + } + + throw $e; + } + + /** + * Disconnect from the underlying PDO connection. + * + * @return void + */ + public function disconnect() + { + $this->setPdo(null)->setReadPdo(null); + } + + /** + * Reconnect to the database. + * + * @return void + * + * @throws \LogicException + */ + public function reconnect() + { + if (is_callable($this->reconnector)) { + return call_user_func($this->reconnector, $this); + } + + throw new LogicException('Lost connection and no reconnector available.'); + } + + /** + * Reconnect to the database if a PDO connection is missing. + * + * @return void + */ + protected function reconnectIfMissingConnection() + { + if (is_null($this->getPdo()) || is_null($this->getReadPdo())) { + $this->reconnect(); + } + } + + /** + * Log a query in the connection's query log. + * + * @param string $query + * @param array $bindings + * @param float|null $time + * @return void + */ + public function logQuery($query, $bindings, $time = null) + { + if (isset($this->events)) { + $this->events->fire('illuminate.query', [$query, $bindings, $time, $this->getName()]); + } + + if (! $this->loggingQueries) { + return; + } + + $this->queryLog[] = compact('query', 'bindings', 'time'); + } + + /** + * Register a database query listener with the connection. + * + * @param \Closure $callback + * @return void + */ + public function listen(Closure $callback) + { + if (isset($this->events)) { + $this->events->listen('illuminate.query', $callback); + } + } + + /** + * Fire an event for this connection. + * + * @param string $event + * @return void + */ + protected function fireConnectionEvent($event) + { + if (isset($this->events)) { + $this->events->fire('connection.'.$this->getName().'.'.$event, $this); + } + } + + /** + * Get the elapsed time since a given starting point. + * + * @param int $start + * @return float + */ + protected function getElapsedTime($start) + { + return round((microtime(true) - $start) * 1000, 2); + } + + /** + * Is Doctrine available? + * + * @return bool + */ + public function isDoctrineAvailable() + { + return class_exists('Doctrine\DBAL\Connection'); + } + + /** + * Get a Doctrine Schema Column instance. + * + * @param string $table + * @param string $column + * @return \Doctrine\DBAL\Schema\Column + */ + public function getDoctrineColumn($table, $column) + { + $schema = $this->getDoctrineSchemaManager(); + + return $schema->listTableDetails($table)->getColumn($column); + } + + /** + * Get the Doctrine DBAL schema manager for the connection. + * + * @return \Doctrine\DBAL\Schema\AbstractSchemaManager + */ + public function getDoctrineSchemaManager() + { + return $this->getDoctrineDriver()->getSchemaManager($this->getDoctrineConnection()); + } + + /** + * Get the Doctrine DBAL database connection instance. + * + * @return \Doctrine\DBAL\Connection + */ + public function getDoctrineConnection() + { + if (is_null($this->doctrineConnection)) { + $driver = $this->getDoctrineDriver(); + + $data = ['pdo' => $this->pdo, 'dbname' => $this->getConfig('database')]; + + $this->doctrineConnection = new DoctrineConnection($data, $driver); + } + + return $this->doctrineConnection; + } + + /** + * Get the current PDO connection. + * + * @return \PDO + */ + public function getPdo() + { + return $this->pdo; + } + + /** + * Get the current PDO connection used for reading. + * + * @return \PDO + */ + public function getReadPdo() + { + if ($this->transactions >= 1) { + return $this->getPdo(); + } + + return $this->readPdo ?: $this->pdo; + } + + /** + * Set the PDO connection. + * + * @param \PDO|null $pdo + * @return $this + */ + public function setPdo($pdo) + { + if ($this->transactions >= 1) { + throw new RuntimeException("Can't swap PDO instance while within transaction."); + } + + $this->pdo = $pdo; + + return $this; + } + + /** + * Set the PDO connection used for reading. + * + * @param \PDO|null $pdo + * @return $this + */ + public function setReadPdo($pdo) + { + $this->readPdo = $pdo; + + return $this; + } + + /** + * Set the reconnect instance on the connection. + * + * @param callable $reconnector + * @return $this + */ + public function setReconnector(callable $reconnector) + { + $this->reconnector = $reconnector; + + return $this; + } + + /** + * Get the database connection name. + * + * @return string|null + */ + public function getName() + { + return $this->getConfig('name'); + } + + /** + * Get an option from the configuration options. + * + * @param string $option + * @return mixed + */ + public function getConfig($option) + { + return Arr::get($this->config, $option); + } + + /** + * Get the PDO driver name. + * + * @return string + */ + public function getDriverName() + { + return $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME); + } + + /** + * Get the query grammar used by the connection. + * + * @return \Illuminate\Database\Query\Grammars\Grammar + */ + public function getQueryGrammar() + { + return $this->queryGrammar; + } + + /** + * Set the query grammar used by the connection. + * + * @param \Illuminate\Database\Query\Grammars\Grammar $grammar + * @return void + */ + public function setQueryGrammar(Query\Grammars\Grammar $grammar) + { + $this->queryGrammar = $grammar; + } + + /** + * Get the schema grammar used by the connection. + * + * @return \Illuminate\Database\Schema\Grammars\Grammar + */ + public function getSchemaGrammar() + { + return $this->schemaGrammar; + } + + /** + * Set the schema grammar used by the connection. + * + * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar + * @return void + */ + public function setSchemaGrammar(Schema\Grammars\Grammar $grammar) + { + $this->schemaGrammar = $grammar; + } + + /** + * Get the query post processor used by the connection. + * + * @return \Illuminate\Database\Query\Processors\Processor + */ + public function getPostProcessor() + { + return $this->postProcessor; + } + + /** + * Set the query post processor used by the connection. + * + * @param \Illuminate\Database\Query\Processors\Processor $processor + * @return void + */ + public function setPostProcessor(Processor $processor) + { + $this->postProcessor = $processor; + } + + /** + * Get the event dispatcher used by the connection. + * + * @return \Illuminate\Contracts\Events\Dispatcher + */ + public function getEventDispatcher() + { + return $this->events; + } + + /** + * Set the event dispatcher instance on the connection. + * + * @param \Illuminate\Contracts\Events\Dispatcher $events + * @return void + */ + public function setEventDispatcher(Dispatcher $events) + { + $this->events = $events; + } + + /** + * Determine if the connection in a "dry run". + * + * @return bool + */ + public function pretending() + { + return $this->pretending === true; + } + + /** + * Get the default fetch mode for the connection. + * + * @return int + */ + public function getFetchMode() + { + return $this->fetchMode; + } + + /** + * Set the default fetch mode for the connection. + * + * @param int $fetchMode + * @return int + */ + public function setFetchMode($fetchMode) + { + $this->fetchMode = $fetchMode; + } + + /** + * Get the connection query log. + * + * @return array + */ + public function getQueryLog() + { + return $this->queryLog; + } + + /** + * Clear the query log. + * + * @return void + */ + public function flushQueryLog() + { + $this->queryLog = []; + } + + /** + * Enable the query log on the connection. + * + * @return void + */ + public function enableQueryLog() + { + $this->loggingQueries = true; + } + + /** + * Disable the query log on the connection. + * + * @return void + */ + public function disableQueryLog() + { + $this->loggingQueries = false; + } + + /** + * Determine whether we're logging queries. + * + * @return bool + */ + public function logging() + { + return $this->loggingQueries; + } + + /** + * Get the name of the connected database. + * + * @return string + */ + public function getDatabaseName() + { + return $this->database; + } + + /** + * Set the name of the connected database. + * + * @param string $database + * @return string + */ + public function setDatabaseName($database) + { + $this->database = $database; + } + + /** + * Get the table prefix for the connection. + * + * @return string + */ + public function getTablePrefix() + { + return $this->tablePrefix; + } + + /** + * Set the table prefix in use by the connection. + * + * @param string $prefix + * @return void + */ + public function setTablePrefix($prefix) + { + $this->tablePrefix = $prefix; + + $this->getQueryGrammar()->setTablePrefix($prefix); + } + + /** + * Set the table prefix and return the grammar. + * + * @param \Illuminate\Database\Grammar $grammar + * @return \Illuminate\Database\Grammar + */ + public function withTablePrefix(Grammar $grammar) + { + $grammar->setTablePrefix($this->tablePrefix); + + return $grammar; + } +} diff --git a/vendor/illuminate/database/ConnectionInterface.php b/vendor/illuminate/database/ConnectionInterface.php new file mode 100755 index 0000000..16eb667 --- /dev/null +++ b/vendor/illuminate/database/ConnectionInterface.php @@ -0,0 +1,149 @@ + $connection) { + $this->addConnection($name, $connection); + } + } + + /** + * Get a database connection instance. + * + * @param string $name + * @return \Illuminate\Database\ConnectionInterface + */ + public function connection($name = null) + { + if (is_null($name)) { + $name = $this->getDefaultConnection(); + } + + return $this->connections[$name]; + } + + /** + * Add a connection to the resolver. + * + * @param string $name + * @param \Illuminate\Database\ConnectionInterface $connection + * @return void + */ + public function addConnection($name, ConnectionInterface $connection) + { + $this->connections[$name] = $connection; + } + + /** + * Check if a connection has been registered. + * + * @param string $name + * @return bool + */ + public function hasConnection($name) + { + return isset($this->connections[$name]); + } + + /** + * Get the default connection name. + * + * @return string + */ + public function getDefaultConnection() + { + return $this->default; + } + + /** + * Set the default connection name. + * + * @param string $name + * @return void + */ + public function setDefaultConnection($name) + { + $this->default = $name; + } +} diff --git a/vendor/illuminate/database/ConnectionResolverInterface.php b/vendor/illuminate/database/ConnectionResolverInterface.php new file mode 100755 index 0000000..eb0397a --- /dev/null +++ b/vendor/illuminate/database/ConnectionResolverInterface.php @@ -0,0 +1,29 @@ +container = $container; + } + + /** + * Establish a PDO connection based on the configuration. + * + * @param array $config + * @param string $name + * @return \Illuminate\Database\Connection + */ + public function make(array $config, $name = null) + { + $config = $this->parseConfig($config, $name); + + if (isset($config['read'])) { + return $this->createReadWriteConnection($config); + } + + return $this->createSingleConnection($config); + } + + /** + * Create a single database connection instance. + * + * @param array $config + * @return \Illuminate\Database\Connection + */ + protected function createSingleConnection(array $config) + { + $pdo = $this->createConnector($config)->connect($config); + + return $this->createConnection($config['driver'], $pdo, $config['database'], $config['prefix'], $config); + } + + /** + * Create a single database connection instance. + * + * @param array $config + * @return \Illuminate\Database\Connection + */ + protected function createReadWriteConnection(array $config) + { + $connection = $this->createSingleConnection($this->getWriteConfig($config)); + + return $connection->setReadPdo($this->createReadPdo($config)); + } + + /** + * Create a new PDO instance for reading. + * + * @param array $config + * @return \PDO + */ + protected function createReadPdo(array $config) + { + $readConfig = $this->getReadConfig($config); + + return $this->createConnector($readConfig)->connect($readConfig); + } + + /** + * Get the read configuration for a read / write connection. + * + * @param array $config + * @return array + */ + protected function getReadConfig(array $config) + { + $readConfig = $this->getReadWriteConfig($config, 'read'); + + if (isset($readConfig['host']) && is_array($readConfig['host'])) { + $readConfig['host'] = count($readConfig['host']) > 1 + ? $readConfig['host'][array_rand($readConfig['host'])] + : $readConfig['host'][0]; + } + + return $this->mergeReadWriteConfig($config, $readConfig); + } + + /** + * Get the read configuration for a read / write connection. + * + * @param array $config + * @return array + */ + protected function getWriteConfig(array $config) + { + $writeConfig = $this->getReadWriteConfig($config, 'write'); + + return $this->mergeReadWriteConfig($config, $writeConfig); + } + + /** + * Get a read / write level configuration. + * + * @param array $config + * @param string $type + * @return array + */ + protected function getReadWriteConfig(array $config, $type) + { + if (isset($config[$type][0])) { + return $config[$type][array_rand($config[$type])]; + } + + return $config[$type]; + } + + /** + * Merge a configuration for a read / write connection. + * + * @param array $config + * @param array $merge + * @return array + */ + protected function mergeReadWriteConfig(array $config, array $merge) + { + return array_except(array_merge($config, $merge), ['read', 'write']); + } + + /** + * Parse and prepare the database configuration. + * + * @param array $config + * @param string $name + * @return array + */ + protected function parseConfig(array $config, $name) + { + return Arr::add(Arr::add($config, 'prefix', ''), 'name', $name); + } + + /** + * Create a connector instance based on the configuration. + * + * @param array $config + * @return \Illuminate\Database\Connectors\ConnectorInterface + * + * @throws \InvalidArgumentException + */ + public function createConnector(array $config) + { + if (! isset($config['driver'])) { + throw new InvalidArgumentException('A driver must be specified.'); + } + + if ($this->container->bound($key = "db.connector.{$config['driver']}")) { + return $this->container->make($key); + } + + switch ($config['driver']) { + case 'mysql': + return new MySqlConnector; + + case 'pgsql': + return new PostgresConnector; + + case 'sqlite': + return new SQLiteConnector; + + case 'sqlsrv': + return new SqlServerConnector; + } + + throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]"); + } + + /** + * Create a new connection instance. + * + * @param string $driver + * @param \PDO $connection + * @param string $database + * @param string $prefix + * @param array $config + * @return \Illuminate\Database\Connection + * + * @throws \InvalidArgumentException + */ + protected function createConnection($driver, PDO $connection, $database, $prefix = '', array $config = []) + { + if ($this->container->bound($key = "db.connection.{$driver}")) { + return $this->container->make($key, [$connection, $database, $prefix, $config]); + } + + switch ($driver) { + case 'mysql': + return new MySqlConnection($connection, $database, $prefix, $config); + + case 'pgsql': + return new PostgresConnection($connection, $database, $prefix, $config); + + case 'sqlite': + return new SQLiteConnection($connection, $database, $prefix, $config); + + case 'sqlsrv': + return new SqlServerConnection($connection, $database, $prefix, $config); + } + + throw new InvalidArgumentException("Unsupported driver [$driver]"); + } +} diff --git a/vendor/illuminate/database/Connectors/Connector.php b/vendor/illuminate/database/Connectors/Connector.php new file mode 100755 index 0000000..ea2637c --- /dev/null +++ b/vendor/illuminate/database/Connectors/Connector.php @@ -0,0 +1,106 @@ + PDO::CASE_NATURAL, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, + PDO::ATTR_STRINGIFY_FETCHES => false, + PDO::ATTR_EMULATE_PREPARES => false, + ]; + + /** + * Get the PDO options based on the configuration. + * + * @param array $config + * @return array + */ + public function getOptions(array $config) + { + $options = Arr::get($config, 'options', []); + + return array_diff_key($this->options, $options) + $options; + } + + /** + * Create a new PDO connection. + * + * @param string $dsn + * @param array $config + * @param array $options + * @return \PDO + */ + public function createConnection($dsn, array $config, array $options) + { + $username = Arr::get($config, 'username'); + + $password = Arr::get($config, 'password'); + + try { + $pdo = new PDO($dsn, $username, $password, $options); + } catch (Exception $e) { + $pdo = $this->tryAgainIfCausedByLostConnection( + $e, $dsn, $username, $password, $options + ); + } + + return $pdo; + } + + /** + * Get the default PDO connection options. + * + * @return array + */ + public function getDefaultOptions() + { + return $this->options; + } + + /** + * Set the default PDO connection options. + * + * @param array $options + * @return void + */ + public function setDefaultOptions(array $options) + { + $this->options = $options; + } + + /** + * Handle a exception that occurred during connect execution. + * + * @param \Exception $e + * @param string $dsn + * @param string $username + * @param string $password + * @param array $options + * @return \PDO + * + * @throws \Exception + */ + protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $username, $password, $options) + { + if ($this->causedByLostConnection($e)) { + return new PDO($dsn, $username, $password, $options); + } + + throw $e; + } +} diff --git a/vendor/illuminate/database/Connectors/ConnectorInterface.php b/vendor/illuminate/database/Connectors/ConnectorInterface.php new file mode 100755 index 0000000..08597ac --- /dev/null +++ b/vendor/illuminate/database/Connectors/ConnectorInterface.php @@ -0,0 +1,14 @@ +getDsn($config); + + $options = $this->getOptions($config); + + // We need to grab the PDO options that should be used while making the brand + // new connection instance. The PDO options control various aspects of the + // connection's behavior, and some might be specified by the developers. + $connection = $this->createConnection($dsn, $config, $options); + + if (isset($config['unix_socket'])) { + $connection->exec("use `{$config['database']}`;"); + } + + $collation = $config['collation']; + + // Next we will set the "names" and "collation" on the clients connections so + // a correct character set will be used by this client. The collation also + // is set on the server but needs to be set here on this client objects. + $charset = $config['charset']; + + $names = "set names '$charset'". + (! is_null($collation) ? " collate '$collation'" : ''); + + $connection->prepare($names)->execute(); + + // Next, we will check to see if a timezone has been specified in this config + // and if it has we will issue a statement to modify the timezone with the + // database. Setting this DB timezone is an optional configuration item. + if (isset($config['timezone'])) { + $connection->prepare( + 'set time_zone="'.$config['timezone'].'"' + )->execute(); + } + + // If the "strict" option has been configured for the connection we will setup + // strict mode for this session. Strict mode enforces some extra rules when + // using the MySQL database system and is a quicker way to enforce them. + if (isset($config['strict'])) { + if ($config['strict']) { + $connection->prepare("set session sql_mode='STRICT_ALL_TABLES'")->execute(); + } else { + $connection->prepare("set session sql_mode=''")->execute(); + } + } + + return $connection; + } + + /** + * Create a DSN string from a configuration. + * + * Chooses socket or host/port based on the 'unix_socket' config value. + * + * @param array $config + * @return string + */ + protected function getDsn(array $config) + { + return $this->configHasSocket($config) ? $this->getSocketDsn($config) : $this->getHostDsn($config); + } + + /** + * Determine if the given configuration array has a UNIX socket value. + * + * @param array $config + * @return bool + */ + protected function configHasSocket(array $config) + { + return isset($config['unix_socket']) && ! empty($config['unix_socket']); + } + + /** + * Get the DSN string for a socket configuration. + * + * @param array $config + * @return string + */ + protected function getSocketDsn(array $config) + { + return "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}"; + } + + /** + * Get the DSN string for a host / port configuration. + * + * @param array $config + * @return string + */ + protected function getHostDsn(array $config) + { + extract($config); + + return isset($port) + ? "mysql:host={$host};port={$port};dbname={$database}" + : "mysql:host={$host};dbname={$database}"; + } +} diff --git a/vendor/illuminate/database/Connectors/PostgresConnector.php b/vendor/illuminate/database/Connectors/PostgresConnector.php new file mode 100755 index 0000000..05fb5a4 --- /dev/null +++ b/vendor/illuminate/database/Connectors/PostgresConnector.php @@ -0,0 +1,117 @@ + PDO::CASE_NATURAL, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, + PDO::ATTR_STRINGIFY_FETCHES => false, + ]; + + /** + * Establish a database connection. + * + * @param array $config + * @return \PDO + */ + public function connect(array $config) + { + // First we'll create the basic DSN and connection instance connecting to the + // using the configuration option specified by the developer. We will also + // set the default character set on the connections to UTF-8 by default. + $dsn = $this->getDsn($config); + + $options = $this->getOptions($config); + + $connection = $this->createConnection($dsn, $config, $options); + + $charset = $config['charset']; + + $connection->prepare("set names '$charset'")->execute(); + + // Next, we will check to see if a timezone has been specified in this config + // and if it has we will issue a statement to modify the timezone with the + // database. Setting this DB timezone is an optional configuration item. + if (isset($config['timezone'])) { + $timezone = $config['timezone']; + + $connection->prepare("set time zone '$timezone'")->execute(); + } + + // Unlike MySQL, Postgres allows the concept of "schema" and a default schema + // may have been specified on the connections. If that is the case we will + // set the default schema search paths to the specified database schema. + if (isset($config['schema'])) { + $schema = $this->formatSchema($config['schema']); + + $connection->prepare("set search_path to {$schema}")->execute(); + } + + // Postgres allows an application_name to be set by the user and this name is + // used to when monitoring the application with pg_stat_activity. So we'll + // determine if the option has been specified and run a statement if so. + if (isset($config['application_name'])) { + $applicationName = $config['application_name']; + + $connection->prepare("set application_name to '$applicationName'")->execute(); + } + + return $connection; + } + + /** + * Create a DSN string from a configuration. + * + * @param array $config + * @return string + */ + protected function getDsn(array $config) + { + // First we will create the basic DSN setup as well as the port if it is in + // in the configuration options. This will give us the basic DSN we will + // need to establish the PDO connections and return them back for use. + extract($config); + + $host = isset($host) ? "host={$host};" : ''; + + $dsn = "pgsql:{$host}dbname={$database}"; + + // If a port was specified, we will add it to this Postgres DSN connections + // format. Once we have done that we are ready to return this connection + // string back out for usage, as this has been fully constructed here. + if (isset($config['port'])) { + $dsn .= ";port={$port}"; + } + + if (isset($config['sslmode'])) { + $dsn .= ";sslmode={$sslmode}"; + } + + return $dsn; + } + + /** + * Format the schema for the DSN. + * + * @param array|string $schema + * @return string + */ + protected function formatSchema($schema) + { + if (is_array($schema)) { + return '"'.implode('", "', $schema).'"'; + } else { + return '"'.$schema.'"'; + } + } +} diff --git a/vendor/illuminate/database/Connectors/SQLiteConnector.php b/vendor/illuminate/database/Connectors/SQLiteConnector.php new file mode 100755 index 0000000..28f9091 --- /dev/null +++ b/vendor/illuminate/database/Connectors/SQLiteConnector.php @@ -0,0 +1,39 @@ +getOptions($config); + + // SQLite supports "in-memory" databases that only last as long as the owning + // connection does. These are useful for tests or for short lifetime store + // querying. In-memory databases may only have a single open connection. + if ($config['database'] == ':memory:') { + return $this->createConnection('sqlite::memory:', $config, $options); + } + + $path = realpath($config['database']); + + // Here we'll verify that the SQLite database exists before going any further + // as the developer probably wants to know if the database exists and this + // SQLite driver will not throw any exception if it does not by default. + if ($path === false) { + throw new InvalidArgumentException("Database (${config['database']}) does not exist."); + } + + return $this->createConnection("sqlite:{$path}", $config, $options); + } +} diff --git a/vendor/illuminate/database/Connectors/SqlServerConnector.php b/vendor/illuminate/database/Connectors/SqlServerConnector.php new file mode 100755 index 0000000..46e0b84 --- /dev/null +++ b/vendor/illuminate/database/Connectors/SqlServerConnector.php @@ -0,0 +1,137 @@ + PDO::CASE_NATURAL, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, + PDO::ATTR_STRINGIFY_FETCHES => false, + ]; + + /** + * Establish a database connection. + * + * @param array $config + * @return \PDO + */ + public function connect(array $config) + { + $options = $this->getOptions($config); + + return $this->createConnection($this->getDsn($config), $config, $options); + } + + /** + * Create a DSN string from a configuration. + * + * @param array $config + * @return string + */ + protected function getDsn(array $config) + { + // First we will create the basic DSN setup as well as the port if it is in + // in the configuration options. This will give us the basic DSN we will + // need to establish the PDO connections and return them back for use. + if (in_array('dblib', $this->getAvailableDrivers())) { + return $this->getDblibDsn($config); + } else { + return $this->getSqlSrvDsn($config); + } + } + + /** + * Get the DSN string for a DbLib connection. + * + * @param array $config + * @return string + */ + protected function getDblibDsn(array $config) + { + $arguments = [ + 'host' => $this->buildHostString($config, ':'), + 'dbname' => $config['database'], + ]; + + $arguments = array_merge( + $arguments, Arr::only($config, ['appname', 'charset']) + ); + + return $this->buildConnectString('dblib', $arguments); + } + + /** + * Get the DSN string for a SqlSrv connection. + * + * @param array $config + * @return string + */ + protected function getSqlSrvDsn(array $config) + { + $arguments = [ + 'Server' => $this->buildHostString($config, ','), + ]; + + if (isset($config['database'])) { + $arguments['Database'] = $config['database']; + } + + if (isset($config['appname'])) { + $arguments['APP'] = $config['appname']; + } + + return $this->buildConnectString('sqlsrv', $arguments); + } + + /** + * Build a connection string from the given arguments. + * + * @param string $driver + * @param array $arguments + * @return string + */ + protected function buildConnectString($driver, array $arguments) + { + $options = array_map(function ($key) use ($arguments) { + return sprintf('%s=%s', $key, $arguments[$key]); + }, array_keys($arguments)); + + return $driver.':'.implode(';', $options); + } + + /** + * Build a host string from the given configuration. + * + * @param array $config + * @param string $separator + * @return string + */ + protected function buildHostString(array $config, $separator) + { + if (isset($config['port'])) { + return $config['host'].$separator.$config['port']; + } else { + return $config['host']; + } + } + + /** + * Get the available PDO drivers. + * + * @return array + */ + protected function getAvailableDrivers() + { + return PDO::getAvailableDrivers(); + } +} diff --git a/vendor/illuminate/database/Console/Migrations/BaseCommand.php b/vendor/illuminate/database/Console/Migrations/BaseCommand.php new file mode 100755 index 0000000..f3459ac --- /dev/null +++ b/vendor/illuminate/database/Console/Migrations/BaseCommand.php @@ -0,0 +1,18 @@ +laravel->databasePath().'/migrations'; + } +} diff --git a/vendor/illuminate/database/Console/Migrations/InstallCommand.php b/vendor/illuminate/database/Console/Migrations/InstallCommand.php new file mode 100755 index 0000000..103dcaa --- /dev/null +++ b/vendor/illuminate/database/Console/Migrations/InstallCommand.php @@ -0,0 +1,70 @@ +repository = $repository; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $this->repository->setSource($this->input->getOption('database')); + + $this->repository->createRepository(); + + $this->info('Migration table created successfully.'); + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'], + ]; + } +} diff --git a/vendor/illuminate/database/Console/Migrations/MigrateCommand.php b/vendor/illuminate/database/Console/Migrations/MigrateCommand.php new file mode 100755 index 0000000..920d417 --- /dev/null +++ b/vendor/illuminate/database/Console/Migrations/MigrateCommand.php @@ -0,0 +1,126 @@ +migrator = $migrator; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + if (! $this->confirmToProceed()) { + return; + } + + $this->prepareDatabase(); + + // The pretend option can be used for "simulating" the migration and grabbing + // the SQL queries that would fire if the migration were to be run against + // a database for real, which is helpful for double checking migrations. + $pretend = $this->input->getOption('pretend'); + + // Next, we will check to see if a path option has been defined. If it has + // we will use the path relative to the root of this installation folder + // so that migrations may be run for any path within the applications. + if (! is_null($path = $this->input->getOption('path'))) { + $path = $this->laravel->basePath().'/'.$path; + } else { + $path = $this->getMigrationPath(); + } + + $this->migrator->run($path, $pretend); + + // Once the migrator has run we will grab the note output and send it out to + // the console screen, since the migrator itself functions without having + // any instances of the OutputInterface contract passed into the class. + foreach ($this->migrator->getNotes() as $note) { + $this->output->writeln($note); + } + + // Finally, if the "seed" option has been given, we will re-run the database + // seed task to re-populate the database, which is convenient when adding + // a migration and a seed at the same time, as it is only this command. + if ($this->input->getOption('seed')) { + $this->call('db:seed', ['--force' => true]); + } + } + + /** + * Prepare the migration database for running. + * + * @return void + */ + protected function prepareDatabase() + { + $this->migrator->setConnection($this->input->getOption('database')); + + if (! $this->migrator->repositoryExists()) { + $options = ['--database' => $this->input->getOption('database')]; + + $this->call('migrate:install', $options); + } + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'], + + ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'], + + ['path', null, InputOption::VALUE_OPTIONAL, 'The path of migrations files to be executed.'], + + ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'], + + ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'], + ]; + } +} diff --git a/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php b/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php new file mode 100644 index 0000000..7fef3b9 --- /dev/null +++ b/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php @@ -0,0 +1,114 @@ +creator = $creator; + $this->composer = $composer; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + // It's possible for the developer to specify the tables to modify in this + // schema operation. The developer may also specify if this table needs + // to be freshly created so we can create the appropriate migrations. + $name = $this->input->getArgument('name'); + + $table = $this->input->getOption('table'); + + $create = $this->input->getOption('create'); + + if (! $table && is_string($create)) { + $table = $create; + } + + // Now we are ready to write the migration out to disk. Once we've written + // the migration out, we will dump-autoload for the entire framework to + // make sure that the migrations are registered by the class loaders. + $this->writeMigration($name, $table, $create); + + $this->composer->dumpAutoloads(); + } + + /** + * Write the migration file to disk. + * + * @param string $name + * @param string $table + * @param bool $create + * @return string + */ + protected function writeMigration($name, $table, $create) + { + $path = $this->getMigrationPath(); + + $file = pathinfo($this->creator->create($name, $path, $table, $create), PATHINFO_FILENAME); + + $this->line("Created Migration: $file"); + } + + /** + * Get migration path (either specified by '--path' option or default location). + * + * @return string + */ + protected function getMigrationPath() + { + if (! is_null($targetPath = $this->input->getOption('path'))) { + return $this->laravel->basePath().'/'.$targetPath; + } + + return parent::getMigrationPath(); + } +} diff --git a/vendor/illuminate/database/Console/Migrations/RefreshCommand.php b/vendor/illuminate/database/Console/Migrations/RefreshCommand.php new file mode 100755 index 0000000..cbec9af --- /dev/null +++ b/vendor/illuminate/database/Console/Migrations/RefreshCommand.php @@ -0,0 +1,102 @@ +confirmToProceed()) { + return; + } + + $database = $this->input->getOption('database'); + + $force = $this->input->getOption('force'); + + $this->call('migrate:reset', [ + '--database' => $database, '--force' => $force, + ]); + + // The refresh command is essentially just a brief aggregate of a few other of + // the migration commands and just provides a convenient wrapper to execute + // them in succession. We'll also see if we need to re-seed the database. + $this->call('migrate', [ + '--database' => $database, '--force' => $force, + ]); + + if ($this->needsSeeding()) { + $this->runSeeder($database); + } + } + + /** + * Determine if the developer has requested database seeding. + * + * @return bool + */ + protected function needsSeeding() + { + return $this->option('seed') || $this->option('seeder'); + } + + /** + * Run the database seeder command. + * + * @param string $database + * @return void + */ + protected function runSeeder($database) + { + $class = $this->option('seeder') ?: 'DatabaseSeeder'; + + $force = $this->input->getOption('force'); + + $this->call('db:seed', [ + '--database' => $database, '--class' => $class, '--force' => $force, + ]); + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'], + + ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'], + + ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run.'], + + ['seeder', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder.'], + ]; + } +} diff --git a/vendor/illuminate/database/Console/Migrations/ResetCommand.php b/vendor/illuminate/database/Console/Migrations/ResetCommand.php new file mode 100755 index 0000000..8871d3d --- /dev/null +++ b/vendor/illuminate/database/Console/Migrations/ResetCommand.php @@ -0,0 +1,94 @@ +migrator = $migrator; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + if (! $this->confirmToProceed()) { + return; + } + + $this->migrator->setConnection($this->input->getOption('database')); + + if (! $this->migrator->repositoryExists()) { + $this->output->writeln('Migration table not found.'); + + return; + } + + $pretend = $this->input->getOption('pretend'); + + $this->migrator->reset($pretend); + + // Once the migrator has run we will grab the note output and send it out to + // the console screen, since the migrator itself functions without having + // any instances of the OutputInterface contract passed into the class. + foreach ($this->migrator->getNotes() as $note) { + $this->output->writeln($note); + } + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'], + + ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'], + + ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'], + ]; + } +} diff --git a/vendor/illuminate/database/Console/Migrations/RollbackCommand.php b/vendor/illuminate/database/Console/Migrations/RollbackCommand.php new file mode 100755 index 0000000..a341b4f --- /dev/null +++ b/vendor/illuminate/database/Console/Migrations/RollbackCommand.php @@ -0,0 +1,88 @@ +migrator = $migrator; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + if (! $this->confirmToProceed()) { + return; + } + + $this->migrator->setConnection($this->input->getOption('database')); + + $pretend = $this->input->getOption('pretend'); + + $this->migrator->rollback($pretend); + + // Once the migrator has run we will grab the note output and send it out to + // the console screen, since the migrator itself functions without having + // any instances of the OutputInterface contract passed into the class. + foreach ($this->migrator->getNotes() as $note) { + $this->output->writeln($note); + } + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use.'], + + ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'], + + ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run.'], + ]; + } +} diff --git a/vendor/illuminate/database/Console/Migrations/StatusCommand.php b/vendor/illuminate/database/Console/Migrations/StatusCommand.php new file mode 100644 index 0000000..fd375a6 --- /dev/null +++ b/vendor/illuminate/database/Console/Migrations/StatusCommand.php @@ -0,0 +1,78 @@ +migrator = $migrator; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + if (! $this->migrator->repositoryExists()) { + return $this->error('No migrations found.'); + } + + $ran = $this->migrator->getRepository()->getRan(); + + $migrations = []; + + foreach ($this->getAllMigrationFiles() as $migration) { + $migrations[] = in_array($migration, $ran) ? ['Y', $migration] : ['N', $migration]; + } + + if (count($migrations) > 0) { + $this->table(['Ran?', 'Migration'], $migrations); + } else { + $this->error('No migrations found'); + } + } + + /** + * Get all of the migration files. + * + * @return array + */ + protected function getAllMigrationFiles() + { + return $this->migrator->getMigrationFiles($this->getMigrationPath()); + } +} diff --git a/vendor/illuminate/database/Console/Seeds/SeedCommand.php b/vendor/illuminate/database/Console/Seeds/SeedCommand.php new file mode 100644 index 0000000..f74164b --- /dev/null +++ b/vendor/illuminate/database/Console/Seeds/SeedCommand.php @@ -0,0 +1,103 @@ +resolver = $resolver; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + if (! $this->confirmToProceed()) { + return; + } + + $this->resolver->setDefaultConnection($this->getDatabase()); + + $this->getSeeder()->run(); + } + + /** + * Get a seeder instance from the container. + * + * @return \Illuminate\Database\Seeder + */ + protected function getSeeder() + { + $class = $this->laravel->make($this->input->getOption('class')); + + return $class->setContainer($this->laravel)->setCommand($this); + } + + /** + * Get the name of the database connection to use. + * + * @return string + */ + protected function getDatabase() + { + $database = $this->input->getOption('database'); + + return $database ?: $this->laravel['config']['database.default']; + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['class', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder', 'DatabaseSeeder'], + + ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed'], + + ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'], + ]; + } +} diff --git a/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php b/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php new file mode 100644 index 0000000..06a83c1 --- /dev/null +++ b/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php @@ -0,0 +1,96 @@ +composer = $composer; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + parent::fire(); + + $this->composer->dumpAutoloads(); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getStub() + { + return __DIR__.'/stubs/seeder.stub'; + } + + /** + * Get the destination class path. + * + * @param string $name + * @return string + */ + protected function getPath($name) + { + return $this->laravel->databasePath().'/seeds/'.$name.'.php'; + } + + /** + * Parse the name and format according to the root namespace. + * + * @param string $name + * @return string + */ + protected function parseName($name) + { + return $name; + } +} diff --git a/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub b/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub new file mode 100644 index 0000000..4aa3845 --- /dev/null +++ b/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub @@ -0,0 +1,16 @@ +app = $app; + $this->factory = $factory; + } + + /** + * Get a database connection instance. + * + * @param string $name + * @return \Illuminate\Database\Connection + */ + public function connection($name = null) + { + list($name, $type) = $this->parseConnectionName($name); + + // If we haven't created this connection, we'll create it based on the config + // provided in the application. Once we've created the connections we will + // set the "fetch mode" for PDO which determines the query return types. + if (! isset($this->connections[$name])) { + $connection = $this->makeConnection($name); + + $this->setPdoForType($connection, $type); + + $this->connections[$name] = $this->prepare($connection); + } + + return $this->connections[$name]; + } + + /** + * Parse the connection into an array of the name and read / write type. + * + * @param string $name + * @return array + */ + protected function parseConnectionName($name) + { + $name = $name ?: $this->getDefaultConnection(); + + return Str::endsWith($name, ['::read', '::write']) + ? explode('::', $name, 2) : [$name, null]; + } + + /** + * Disconnect from the given database and remove from local cache. + * + * @param string $name + * @return void + */ + public function purge($name = null) + { + $this->disconnect($name); + + unset($this->connections[$name]); + } + + /** + * Disconnect from the given database. + * + * @param string $name + * @return void + */ + public function disconnect($name = null) + { + if (isset($this->connections[$name = $name ?: $this->getDefaultConnection()])) { + $this->connections[$name]->disconnect(); + } + } + + /** + * Reconnect to the given database. + * + * @param string $name + * @return \Illuminate\Database\Connection + */ + public function reconnect($name = null) + { + $this->disconnect($name = $name ?: $this->getDefaultConnection()); + + if (! isset($this->connections[$name])) { + return $this->connection($name); + } + + return $this->refreshPdoConnections($name); + } + + /** + * Refresh the PDO connections on a given connection. + * + * @param string $name + * @return \Illuminate\Database\Connection + */ + protected function refreshPdoConnections($name) + { + $fresh = $this->makeConnection($name); + + return $this->connections[$name] + ->setPdo($fresh->getPdo()) + ->setReadPdo($fresh->getReadPdo()); + } + + /** + * Make the database connection instance. + * + * @param string $name + * @return \Illuminate\Database\Connection + */ + protected function makeConnection($name) + { + $config = $this->getConfig($name); + + // First we will check by the connection name to see if an extension has been + // registered specifically for that connection. If it has we will call the + // Closure and pass it the config allowing it to resolve the connection. + if (isset($this->extensions[$name])) { + return call_user_func($this->extensions[$name], $config, $name); + } + + $driver = $config['driver']; + + // Next we will check to see if an extension has been registered for a driver + // and will call the Closure if so, which allows us to have a more generic + // resolver for the drivers themselves which applies to all connections. + if (isset($this->extensions[$driver])) { + return call_user_func($this->extensions[$driver], $config, $name); + } + + return $this->factory->make($config, $name); + } + + /** + * Prepare the database connection instance. + * + * @param \Illuminate\Database\Connection $connection + * @return \Illuminate\Database\Connection + */ + protected function prepare(Connection $connection) + { + $connection->setFetchMode($this->app['config']['database.fetch']); + + if ($this->app->bound('events')) { + $connection->setEventDispatcher($this->app['events']); + } + + // Here we'll set a reconnector callback. This reconnector can be any callable + // so we will set a Closure to reconnect from this manager with the name of + // the connection, which will allow us to reconnect from the connections. + $connection->setReconnector(function ($connection) { + $this->reconnect($connection->getName()); + }); + + return $connection; + } + + /** + * Prepare the read write mode for database connection instance. + * + * @param \Illuminate\Database\Connection $connection + * @param string $type + * @return \Illuminate\Database\Connection + */ + protected function setPdoForType(Connection $connection, $type = null) + { + if ($type == 'read') { + $connection->setPdo($connection->getReadPdo()); + } elseif ($type == 'write') { + $connection->setReadPdo($connection->getPdo()); + } + + return $connection; + } + + /** + * Get the configuration for a connection. + * + * @param string $name + * @return array + * + * @throws \InvalidArgumentException + */ + protected function getConfig($name) + { + $name = $name ?: $this->getDefaultConnection(); + + // To get the database connection configuration, we will just pull each of the + // connection configurations and get the configurations for the given name. + // If the configuration doesn't exist, we'll throw an exception and bail. + $connections = $this->app['config']['database.connections']; + + if (is_null($config = Arr::get($connections, $name))) { + throw new InvalidArgumentException("Database [$name] not configured."); + } + + return $config; + } + + /** + * Get the default connection name. + * + * @return string + */ + public function getDefaultConnection() + { + return $this->app['config']['database.default']; + } + + /** + * Set the default connection name. + * + * @param string $name + * @return void + */ + public function setDefaultConnection($name) + { + $this->app['config']['database.default'] = $name; + } + + /** + * Register an extension connection resolver. + * + * @param string $name + * @param callable $resolver + * @return void + */ + public function extend($name, callable $resolver) + { + $this->extensions[$name] = $resolver; + } + + /** + * Return all of the created connections. + * + * @return array + */ + public function getConnections() + { + return $this->connections; + } + + /** + * Dynamically pass methods to the default connection. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->connection(), $method], $parameters); + } +} diff --git a/vendor/illuminate/database/DatabaseServiceProvider.php b/vendor/illuminate/database/DatabaseServiceProvider.php new file mode 100755 index 0000000..976f5a1 --- /dev/null +++ b/vendor/illuminate/database/DatabaseServiceProvider.php @@ -0,0 +1,84 @@ +app['db']); + + Model::setEventDispatcher($this->app['events']); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + Model::clearBootedModels(); + + $this->registerEloquentFactory(); + + $this->registerQueueableEntityResolver(); + + // The connection factory is used to create the actual connection instances on + // the database. We will inject the factory into the manager so that it may + // make the connections while they are actually needed and not of before. + $this->app->singleton('db.factory', function ($app) { + return new ConnectionFactory($app); + }); + + // The database manager is used to resolve various connections, since multiple + // connections might be managed. It also implements the connection resolver + // interface which may be used by other components requiring connections. + $this->app->singleton('db', function ($app) { + return new DatabaseManager($app, $app['db.factory']); + }); + } + + /** + * Register the Eloquent factory instance in the container. + * + * @return void + */ + protected function registerEloquentFactory() + { + $this->app->singleton(FakerGenerator::class, function () { + return FakerFactory::create(); + }); + + $this->app->singleton(EloquentFactory::class, function ($app) { + $faker = $app->make(FakerGenerator::class); + + return EloquentFactory::construct($faker, database_path('factories')); + }); + } + + /** + * Register the queueable entity resolver implementation. + * + * @return void + */ + protected function registerQueueableEntityResolver() + { + $this->app->singleton('Illuminate\Contracts\Queue\EntityResolver', function () { + return new QueueEntityResolver; + }); + } +} diff --git a/vendor/illuminate/database/DetectsLostConnections.php b/vendor/illuminate/database/DetectsLostConnections.php new file mode 100644 index 0000000..78c65a9 --- /dev/null +++ b/vendor/illuminate/database/DetectsLostConnections.php @@ -0,0 +1,28 @@ +getMessage(); + + return Str::contains($message, [ + 'server has gone away', + 'no connection to the server', + 'Lost connection', + 'is dead or not enabled', + 'Error while sending', + ]); + } +} diff --git a/vendor/illuminate/database/Eloquent/Builder.php b/vendor/illuminate/database/Eloquent/Builder.php new file mode 100755 index 0000000..91b97ab --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Builder.php @@ -0,0 +1,957 @@ +query = $query; + } + + /** + * Find a model by its primary key. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null + */ + public function find($id, $columns = ['*']) + { + if (is_array($id)) { + return $this->findMany($id, $columns); + } + + $this->query->where($this->model->getQualifiedKeyName(), '=', $id); + + return $this->first($columns); + } + + /** + * Find a model by its primary key. + * + * @param array $ids + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection + */ + public function findMany($ids, $columns = ['*']) + { + if (empty($ids)) { + return $this->model->newCollection(); + } + + $this->query->whereIn($this->model->getQualifiedKeyName(), $ids); + + return $this->get($columns); + } + + /** + * Find a model by its primary key or throw an exception. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function findOrFail($id, $columns = ['*']) + { + $result = $this->find($id, $columns); + + if (is_array($id)) { + if (count($result) == count(array_unique($id))) { + return $result; + } + } elseif (! is_null($result)) { + return $result; + } + + throw (new ModelNotFoundException)->setModel(get_class($this->model)); + } + + /** + * Execute the query and get the first result. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|static|null + */ + public function first($columns = ['*']) + { + return $this->take(1)->get($columns)->first(); + } + + /** + * Execute the query and get the first result or throw an exception. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|static + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function firstOrFail($columns = ['*']) + { + if (! is_null($model = $this->first($columns))) { + return $model; + } + + throw (new ModelNotFoundException)->setModel(get_class($this->model)); + } + + /** + * Execute the query as a "select" statement. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection|static[] + */ + public function get($columns = ['*']) + { + $models = $this->getModels($columns); + + // If we actually found models we will also eager load any relationships that + // have been specified as needing to be eager loaded, which will solve the + // n+1 query issue for the developers to avoid running a lot of queries. + if (count($models) > 0) { + $models = $this->eagerLoadRelations($models); + } + + return $this->model->newCollection($models); + } + + /** + * Get a single column's value from the first result of a query. + * + * @param string $column + * @return mixed + */ + public function value($column) + { + $result = $this->first([$column]); + + if ($result) { + return $result->{$column}; + } + } + + /** + * Get a single column's value from the first result of a query. + * + * This is an alias for the "value" method. + * + * @param string $column + * @return mixed + * + * @deprecated since version 5.1. + */ + public function pluck($column) + { + return $this->value($column); + } + + /** + * Chunk the results of the query. + * + * @param int $count + * @param callable $callback + * @return void + */ + public function chunk($count, callable $callback) + { + $results = $this->forPage($page = 1, $count)->get(); + + while (count($results) > 0) { + // On each chunk result set, we will pass them to the callback and then let the + // developer take care of everything within the callback, which allows us to + // keep the memory low for spinning through large result sets for working. + if (call_user_func($callback, $results) === false) { + break; + } + + $page++; + + $results = $this->forPage($page, $count)->get(); + } + } + + /** + * Get an array with the values of a given column. + * + * @param string $column + * @param string $key + * @return \Illuminate\Support\Collection + */ + public function lists($column, $key = null) + { + $results = $this->query->lists($column, $key); + + // If the model has a mutator for the requested column, we will spin through + // the results and mutate the values so that the mutated version of these + // columns are returned as you would expect from these Eloquent models. + if ($this->model->hasGetMutator($column)) { + foreach ($results as $key => &$value) { + $fill = [$column => $value]; + + $value = $this->model->newFromBuilder($fill)->$column; + } + } + + return collect($results); + } + + /** + * Paginate the given query. + * + * @param int $perPage + * @param array $columns + * @param string $pageName + * @param int|null $page + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * + * @throws \InvalidArgumentException + */ + public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null) + { + $total = $this->query->getCountForPagination(); + + $this->query->forPage( + $page = $page ?: Paginator::resolveCurrentPage($pageName), + $perPage = $perPage ?: $this->model->getPerPage() + ); + + return new LengthAwarePaginator($this->get($columns), $total, $perPage, $page, [ + 'path' => Paginator::resolveCurrentPath(), + 'pageName' => $pageName, + ]); + } + + /** + * Paginate the given query into a simple paginator. + * + * @param int $perPage + * @param array $columns + * @param string $pageName + * @return \Illuminate\Contracts\Pagination\Paginator + */ + public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page') + { + $page = Paginator::resolveCurrentPage($pageName); + + $perPage = $perPage ?: $this->model->getPerPage(); + + $this->skip(($page - 1) * $perPage)->take($perPage + 1); + + return new Paginator($this->get($columns), $perPage, $page, [ + 'path' => Paginator::resolveCurrentPath(), + 'pageName' => $pageName, + ]); + } + + /** + * Update a record in the database. + * + * @param array $values + * @return int + */ + public function update(array $values) + { + return $this->query->update($this->addUpdatedAtColumn($values)); + } + + /** + * Increment a column's value by a given amount. + * + * @param string $column + * @param int $amount + * @param array $extra + * @return int + */ + public function increment($column, $amount = 1, array $extra = []) + { + $extra = $this->addUpdatedAtColumn($extra); + + return $this->query->increment($column, $amount, $extra); + } + + /** + * Decrement a column's value by a given amount. + * + * @param string $column + * @param int $amount + * @param array $extra + * @return int + */ + public function decrement($column, $amount = 1, array $extra = []) + { + $extra = $this->addUpdatedAtColumn($extra); + + return $this->query->decrement($column, $amount, $extra); + } + + /** + * Add the "updated at" column to an array of values. + * + * @param array $values + * @return array + */ + protected function addUpdatedAtColumn(array $values) + { + if (! $this->model->usesTimestamps()) { + return $values; + } + + $column = $this->model->getUpdatedAtColumn(); + + return Arr::add($values, $column, $this->model->freshTimestampString()); + } + + /** + * Delete a record from the database. + * + * @return mixed + */ + public function delete() + { + if (isset($this->onDelete)) { + return call_user_func($this->onDelete, $this); + } + + return $this->query->delete(); + } + + /** + * Run the default delete function on the builder. + * + * @return mixed + */ + public function forceDelete() + { + return $this->query->delete(); + } + + /** + * Register a replacement for the default delete function. + * + * @param \Closure $callback + * @return void + */ + public function onDelete(Closure $callback) + { + $this->onDelete = $callback; + } + + /** + * Get the hydrated models without eager loading. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model[] + */ + public function getModels($columns = ['*']) + { + $results = $this->query->get($columns); + + $connection = $this->model->getConnectionName(); + + return $this->model->hydrate($results, $connection)->all(); + } + + /** + * Eager load the relationships for the models. + * + * @param array $models + * @return array + */ + public function eagerLoadRelations(array $models) + { + foreach ($this->eagerLoad as $name => $constraints) { + // For nested eager loads we'll skip loading them here and they will be set as an + // eager load on the query to retrieve the relation so that they will be eager + // loaded on that query, because that is where they get hydrated as models. + if (strpos($name, '.') === false) { + $models = $this->loadRelation($models, $name, $constraints); + } + } + + return $models; + } + + /** + * Eagerly load the relationship on a set of models. + * + * @param array $models + * @param string $name + * @param \Closure $constraints + * @return array + */ + protected function loadRelation(array $models, $name, Closure $constraints) + { + // First we will "back up" the existing where conditions on the query so we can + // add our eager constraints. Then we will merge the wheres that were on the + // query back to it in order that any where conditions might be specified. + $relation = $this->getRelation($name); + + $relation->addEagerConstraints($models); + + call_user_func($constraints, $relation); + + $models = $relation->initRelation($models, $name); + + // Once we have the results, we just match those back up to their parent models + // using the relationship instance. Then we just return the finished arrays + // of models which have been eagerly hydrated and are readied for return. + $results = $relation->getEager(); + + return $relation->match($models, $results, $name); + } + + /** + * Get the relation instance for the given relation name. + * + * @param string $relation + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function getRelation($relation) + { + // We want to run a relationship query without any constrains so that we will + // not have to remove these where clauses manually which gets really hacky + // and is error prone while we remove the developer's own where clauses. + $query = Relation::noConstraints(function () use ($relation) { + return $this->getModel()->$relation(); + }); + + $nested = $this->nestedRelations($relation); + + // If there are nested relationships set on the query, we will put those onto + // the query instances so that they can be handled after this relationship + // is loaded. In this way they will all trickle down as they are loaded. + if (count($nested) > 0) { + $query->getQuery()->with($nested); + } + + return $query; + } + + /** + * Get the deeply nested relations for a given top-level relation. + * + * @param string $relation + * @return array + */ + protected function nestedRelations($relation) + { + $nested = []; + + // We are basically looking for any relationships that are nested deeper than + // the given top-level relationship. We will just check for any relations + // that start with the given top relations and adds them to our arrays. + foreach ($this->eagerLoad as $name => $constraints) { + if ($this->isNested($name, $relation)) { + $nested[substr($name, strlen($relation.'.'))] = $constraints; + } + } + + return $nested; + } + + /** + * Determine if the relationship is nested. + * + * @param string $name + * @param string $relation + * @return bool + */ + protected function isNested($name, $relation) + { + $dots = Str::contains($name, '.'); + + return $dots && Str::startsWith($name, $relation.'.'); + } + + /** + * Add a basic where clause to the query. + * + * @param string $column + * @param string $operator + * @param mixed $value + * @param string $boolean + * @return $this + */ + public function where($column, $operator = null, $value = null, $boolean = 'and') + { + if ($column instanceof Closure) { + $query = $this->model->newQueryWithoutScopes(); + + call_user_func($column, $query); + + $this->query->addNestedWhereQuery($query->getQuery(), $boolean); + } else { + call_user_func_array([$this->query, 'where'], func_get_args()); + } + + return $this; + } + + /** + * Add an "or where" clause to the query. + * + * @param string $column + * @param string $operator + * @param mixed $value + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function orWhere($column, $operator = null, $value = null) + { + return $this->where($column, $operator, $value, 'or'); + } + + /** + * Add a relationship count condition to the query. + * + * @param string $relation + * @param string $operator + * @param int $count + * @param string $boolean + * @param \Closure|null $callback + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function has($relation, $operator = '>=', $count = 1, $boolean = 'and', Closure $callback = null) + { + if (strpos($relation, '.') !== false) { + return $this->hasNested($relation, $operator, $count, $boolean, $callback); + } + + $relation = $this->getHasRelationQuery($relation); + + $query = $relation->getRelationCountQuery($relation->getRelated()->newQuery(), $this); + + if ($callback) { + call_user_func($callback, $query); + } + + return $this->addHasWhere($query, $relation, $operator, $count, $boolean); + } + + /** + * Add nested relationship count conditions to the query. + * + * @param string $relations + * @param string $operator + * @param int $count + * @param string $boolean + * @param \Closure|null $callback + * @return \Illuminate\Database\Eloquent\Builder|static + */ + protected function hasNested($relations, $operator = '>=', $count = 1, $boolean = 'and', $callback = null) + { + $relations = explode('.', $relations); + + // In order to nest "has", we need to add count relation constraints on the + // callback Closure. We'll do this by simply passing the Closure its own + // reference to itself so it calls itself recursively on each segment. + $closure = function ($q) use (&$closure, &$relations, $operator, $count, $boolean, $callback) { + if (count($relations) > 1) { + $q->whereHas(array_shift($relations), $closure); + } else { + $q->has(array_shift($relations), $operator, $count, 'and', $callback); + } + }; + + return $this->has(array_shift($relations), '>=', 1, $boolean, $closure); + } + + /** + * Add a relationship count condition to the query. + * + * @param string $relation + * @param string $boolean + * @param \Closure|null $callback + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function doesntHave($relation, $boolean = 'and', Closure $callback = null) + { + return $this->has($relation, '<', 1, $boolean, $callback); + } + + /** + * Add a relationship count condition to the query with where clauses. + * + * @param string $relation + * @param \Closure $callback + * @param string $operator + * @param int $count + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function whereHas($relation, Closure $callback, $operator = '>=', $count = 1) + { + return $this->has($relation, $operator, $count, 'and', $callback); + } + + /** + * Add a relationship count condition to the query with where clauses. + * + * @param string $relation + * @param \Closure|null $callback + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function whereDoesntHave($relation, Closure $callback = null) + { + return $this->doesntHave($relation, 'and', $callback); + } + + /** + * Add a relationship count condition to the query with an "or". + * + * @param string $relation + * @param string $operator + * @param int $count + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function orHas($relation, $operator = '>=', $count = 1) + { + return $this->has($relation, $operator, $count, 'or'); + } + + /** + * Add a relationship count condition to the query with where clauses and an "or". + * + * @param string $relation + * @param \Closure $callback + * @param string $operator + * @param int $count + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function orWhereHas($relation, Closure $callback, $operator = '>=', $count = 1) + { + return $this->has($relation, $operator, $count, 'or', $callback); + } + + /** + * Add the "has" condition where clause to the query. + * + * @param \Illuminate\Database\Eloquent\Builder $hasQuery + * @param \Illuminate\Database\Eloquent\Relations\Relation $relation + * @param string $operator + * @param int $count + * @param string $boolean + * @return \Illuminate\Database\Eloquent\Builder + */ + protected function addHasWhere(Builder $hasQuery, Relation $relation, $operator, $count, $boolean) + { + $this->mergeWheresToHas($hasQuery, $relation); + + if (is_numeric($count)) { + $count = new Expression($count); + } + + return $this->where(new Expression('('.$hasQuery->toSql().')'), $operator, $count, $boolean); + } + + /** + * Merge the "wheres" from a relation query to a has query. + * + * @param \Illuminate\Database\Eloquent\Builder $hasQuery + * @param \Illuminate\Database\Eloquent\Relations\Relation $relation + * @return void + */ + protected function mergeWheresToHas(Builder $hasQuery, Relation $relation) + { + // Here we have the "has" query and the original relation. We need to copy over any + // where clauses the developer may have put in the relationship function over to + // the has query, and then copy the bindings from the "has" query to the main. + $relationQuery = $relation->getBaseQuery(); + + $hasQuery = $hasQuery->getModel()->removeGlobalScopes($hasQuery); + + $hasQuery->mergeWheres( + $relationQuery->wheres, $relationQuery->getBindings() + ); + + $this->query->addBinding($hasQuery->getQuery()->getBindings(), 'where'); + } + + /** + * Get the "has relation" base query instance. + * + * @param string $relation + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + protected function getHasRelationQuery($relation) + { + return Relation::noConstraints(function () use ($relation) { + return $this->getModel()->$relation(); + }); + } + + /** + * Set the relationships that should be eager loaded. + * + * @param mixed $relations + * @return $this + */ + public function with($relations) + { + if (is_string($relations)) { + $relations = func_get_args(); + } + + $eagers = $this->parseRelations($relations); + + $this->eagerLoad = array_merge($this->eagerLoad, $eagers); + + return $this; + } + + /** + * Parse a list of relations into individuals. + * + * @param array $relations + * @return array + */ + protected function parseRelations(array $relations) + { + $results = []; + + foreach ($relations as $name => $constraints) { + // If the "relation" value is actually a numeric key, we can assume that no + // constraints have been specified for the eager load and we'll just put + // an empty Closure with the loader so that we can treat all the same. + if (is_numeric($name)) { + $f = function () {}; + + list($name, $constraints) = [$constraints, $f]; + } + + // We need to separate out any nested includes. Which allows the developers + // to load deep relationships using "dots" without stating each level of + // the relationship with its own key in the array of eager load names. + $results = $this->parseNested($name, $results); + + $results[$name] = $constraints; + } + + return $results; + } + + /** + * Parse the nested relationships in a relation. + * + * @param string $name + * @param array $results + * @return array + */ + protected function parseNested($name, $results) + { + $progress = []; + + // If the relation has already been set on the result array, we will not set it + // again, since that would override any constraints that were already placed + // on the relationships. We will only set the ones that are not specified. + foreach (explode('.', $name) as $segment) { + $progress[] = $segment; + + if (! isset($results[$last = implode('.', $progress)])) { + $results[$last] = function () {}; + } + } + + return $results; + } + + /** + * Call the given model scope on the underlying model. + * + * @param string $scope + * @param array $parameters + * @return \Illuminate\Database\Query\Builder + */ + protected function callScope($scope, $parameters) + { + array_unshift($parameters, $this); + + return call_user_func_array([$this->model, $scope], $parameters) ?: $this; + } + + /** + * Get the underlying query builder instance. + * + * @return \Illuminate\Database\Query\Builder|static + */ + public function getQuery() + { + return $this->query; + } + + /** + * Set the underlying query builder instance. + * + * @param \Illuminate\Database\Query\Builder $query + * @return $this + */ + public function setQuery($query) + { + $this->query = $query; + + return $this; + } + + /** + * Get the relationships being eagerly loaded. + * + * @return array + */ + public function getEagerLoads() + { + return $this->eagerLoad; + } + + /** + * Set the relationships being eagerly loaded. + * + * @param array $eagerLoad + * @return $this + */ + public function setEagerLoads(array $eagerLoad) + { + $this->eagerLoad = $eagerLoad; + + return $this; + } + + /** + * Get the model instance being queried. + * + * @return \Illuminate\Database\Eloquent\Model + */ + public function getModel() + { + return $this->model; + } + + /** + * Set a model instance for the model being queried. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return $this + */ + public function setModel(Model $model) + { + $this->model = $model; + + $this->query->from($model->getTable()); + + return $this; + } + + /** + * Extend the builder with a given callback. + * + * @param string $name + * @param \Closure $callback + * @return void + */ + public function macro($name, Closure $callback) + { + $this->macros[$name] = $callback; + } + + /** + * Get the given macro by name. + * + * @param string $name + * @return \Closure + */ + public function getMacro($name) + { + return Arr::get($this->macros, $name); + } + + /** + * Dynamically handle calls into the query instance. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if (isset($this->macros[$method])) { + array_unshift($parameters, $this); + + return call_user_func_array($this->macros[$method], $parameters); + } elseif (method_exists($this->model, $scope = 'scope'.ucfirst($method))) { + return $this->callScope($scope, $parameters); + } + + $result = call_user_func_array([$this->query, $method], $parameters); + + return in_array($method, $this->passthru) ? $result : $this; + } + + /** + * Force a clone of the underlying query builder when cloning. + * + * @return void + */ + public function __clone() + { + $this->query = clone $this->query; + } +} diff --git a/vendor/illuminate/database/Eloquent/Collection.php b/vendor/illuminate/database/Eloquent/Collection.php new file mode 100755 index 0000000..cac3e24 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Collection.php @@ -0,0 +1,253 @@ +getKey(); + } + + return Arr::first($this->items, function ($itemKey, $model) use ($key) { + return $model->getKey() == $key; + + }, $default); + } + + /** + * Load a set of relationships onto the collection. + * + * @param mixed $relations + * @return $this + */ + public function load($relations) + { + if (count($this->items) > 0) { + if (is_string($relations)) { + $relations = func_get_args(); + } + + $query = $this->first()->newQuery()->with($relations); + + $this->items = $query->eagerLoadRelations($this->items); + } + + return $this; + } + + /** + * Add an item to the collection. + * + * @param mixed $item + * @return $this + */ + public function add($item) + { + $this->items[] = $item; + + return $this; + } + + /** + * Determine if a key exists in the collection. + * + * @param mixed $key + * @param mixed $value + * @return bool + */ + public function contains($key, $value = null) + { + if (func_num_args() == 2) { + return parent::contains($key, $value); + } + + if ($this->useAsCallable($key)) { + return parent::contains($key); + } + + $key = $key instanceof Model ? $key->getKey() : $key; + + return parent::contains(function ($k, $m) use ($key) { + return $m->getKey() == $key; + }); + } + + /** + * Fetch a nested element of the collection. + * + * @param string $key + * @return static + * + * @deprecated since version 5.1. Use pluck instead. + */ + public function fetch($key) + { + return new static(Arr::fetch($this->toArray(), $key)); + } + + /** + * Get the array of primary keys. + * + * @return array + */ + public function modelKeys() + { + return array_map(function ($m) { return $m->getKey(); }, $this->items); + } + + /** + * Merge the collection with the given items. + * + * @param \ArrayAccess|array $items + * @return static + */ + public function merge($items) + { + $dictionary = $this->getDictionary(); + + foreach ($items as $item) { + $dictionary[$item->getKey()] = $item; + } + + return new static(array_values($dictionary)); + } + + /** + * Diff the collection with the given items. + * + * @param \ArrayAccess|array $items + * @return static + */ + public function diff($items) + { + $diff = new static; + + $dictionary = $this->getDictionary($items); + + foreach ($this->items as $item) { + if (! isset($dictionary[$item->getKey()])) { + $diff->add($item); + } + } + + return $diff; + } + + /** + * Intersect the collection with the given items. + * + * @param \ArrayAccess|array $items + * @return static + */ + public function intersect($items) + { + $intersect = new static; + + $dictionary = $this->getDictionary($items); + + foreach ($this->items as $item) { + if (isset($dictionary[$item->getKey()])) { + $intersect->add($item); + } + } + + return $intersect; + } + + /** + * Return only unique items from the collection. + * + * @param string|callable|null $key + * @return static + */ + public function unique($key = null) + { + if (! is_null($key)) { + return parent::unique($key); + } + + return new static(array_values($this->getDictionary())); + } + + /** + * Returns only the models from the collection with the specified keys. + * + * @param mixed $keys + * @return static + */ + public function only($keys) + { + $dictionary = Arr::only($this->getDictionary(), $keys); + + return new static(array_values($dictionary)); + } + + /** + * Returns all models in the collection except the models with specified keys. + * + * @param mixed $keys + * @return static + */ + public function except($keys) + { + $dictionary = array_except($this->getDictionary(), $keys); + + return new static(array_values($dictionary)); + } + + /** + * Make the given, typically hidden, attributes visible across the entire collection. + * + * @param array|string $attributes + * @return $this + */ + public function withHidden($attributes) + { + $this->each(function ($model) use ($attributes) { + $model->withHidden($attributes); + }); + + return $this; + } + + /** + * Get a dictionary keyed by primary keys. + * + * @param \ArrayAccess|array $items + * @return array + */ + public function getDictionary($items = null) + { + $items = is_null($items) ? $this->items : $items; + + $dictionary = []; + + foreach ($items as $value) { + $dictionary[$value->getKey()] = $value; + } + + return $dictionary; + } + + /** + * Get a base Support collection instance from this collection. + * + * @return \Illuminate\Support\Collection + */ + public function toBase() + { + return new BaseCollection($this->items); + } +} diff --git a/vendor/illuminate/database/Eloquent/Factory.php b/vendor/illuminate/database/Eloquent/Factory.php new file mode 100644 index 0000000..af5680f --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Factory.php @@ -0,0 +1,218 @@ +faker = $faker; + } + + /** + * The model definitions in the container. + * + * @var array + */ + protected $definitions = []; + + /** + * Create a new factory container. + * + * @param \Faker\Generator $faker + * @param string|null $pathToFactories + * @return static + */ + public static function construct(Faker $faker, $pathToFactories = null) + { + $pathToFactories = $pathToFactories ?: database_path('factories'); + + $factory = new static($faker); + + if (is_dir($pathToFactories)) { + foreach (Finder::create()->files()->in($pathToFactories) as $file) { + require $file->getRealPath(); + } + } + + return $factory; + } + + /** + * Define a class with a given short-name. + * + * @param string $class + * @param string $name + * @param callable $attributes + * @return void + */ + public function defineAs($class, $name, callable $attributes) + { + return $this->define($class, $attributes, $name); + } + + /** + * Define a class with a given set of attributes. + * + * @param string $class + * @param callable $attributes + * @param string $name + * @return void + */ + public function define($class, callable $attributes, $name = 'default') + { + $this->definitions[$class][$name] = $attributes; + } + + /** + * Create an instance of the given model and persist it to the database. + * + * @param string $class + * @param array $attributes + * @return mixed + */ + public function create($class, array $attributes = []) + { + return $this->of($class)->create($attributes); + } + + /** + * Create an instance of the given model and type and persist it to the database. + * + * @param string $class + * @param string $name + * @param array $attributes + * @return mixed + */ + public function createAs($class, $name, array $attributes = []) + { + return $this->of($class, $name)->create($attributes); + } + + /** + * Create an instance of the given model. + * + * @param string $class + * @param array $attributes + * @return mixed + */ + public function make($class, array $attributes = []) + { + return $this->of($class)->make($attributes); + } + + /** + * Create an instance of the given model and type. + * + * @param string $class + * @param string $name + * @param array $attributes + * @return mixed + */ + public function makeAs($class, $name, array $attributes = []) + { + return $this->of($class, $name)->make($attributes); + } + + /** + * Get the raw attribute array for a given named model. + * + * @param string $class + * @param string $name + * @param array $attributes + * @return array + */ + public function rawOf($class, $name, array $attributes = []) + { + return $this->raw($class, $attributes, $name); + } + + /** + * Get the raw attribute array for a given model. + * + * @param string $class + * @param array $attributes + * @param string $name + * @return array + */ + public function raw($class, array $attributes = [], $name = 'default') + { + $raw = call_user_func($this->definitions[$class][$name], $this->faker); + + return array_merge($raw, $attributes); + } + + /** + * Create a builder for the given model. + * + * @param string $class + * @param string $name + * @return \Illuminate\Database\Eloquent\FactoryBuilder + */ + public function of($class, $name = 'default') + { + return new FactoryBuilder($class, $name, $this->definitions, $this->faker); + } + + /** + * Determine if the given offset exists. + * + * @param string $offset + * @return bool + */ + public function offsetExists($offset) + { + return isset($this->definitions[$offset]); + } + + /** + * Get the value of the given offset. + * + * @param string $offset + * @return mixed + */ + public function offsetGet($offset) + { + return $this->make($offset); + } + + /** + * Set the given offset to the given value. + * + * @param string $offset + * @param callable $value + * @return void + */ + public function offsetSet($offset, $value) + { + return $this->define($offset, $value); + } + + /** + * Unset the value at the given offset. + * + * @param string $offset + * @return void + */ + public function offsetUnset($offset) + { + unset($this->definitions[$offset]); + } +} diff --git a/vendor/illuminate/database/Eloquent/FactoryBuilder.php b/vendor/illuminate/database/Eloquent/FactoryBuilder.php new file mode 100644 index 0000000..89d274e --- /dev/null +++ b/vendor/illuminate/database/Eloquent/FactoryBuilder.php @@ -0,0 +1,135 @@ +name = $name; + $this->class = $class; + $this->faker = $faker; + $this->definitions = $definitions; + } + + /** + * Set the amount of models you wish to create / make. + * + * @param int $amount + * @return $this + */ + public function times($amount) + { + $this->amount = $amount; + + return $this; + } + + /** + * Create a collection of models and persist them to the database. + * + * @param array $attributes + * @return mixed + */ + public function create(array $attributes = []) + { + $results = $this->make($attributes); + + if ($this->amount === 1) { + $results->save(); + } else { + foreach ($results as $result) { + $result->save(); + } + } + + return $results; + } + + /** + * Create a collection of models. + * + * @param array $attributes + * @return mixed + */ + public function make(array $attributes = []) + { + if ($this->amount === 1) { + return $this->makeInstance($attributes); + } else { + $results = []; + + for ($i = 0; $i < $this->amount; $i++) { + $results[] = $this->makeInstance($attributes); + } + + return new Collection($results); + } + } + + /** + * Make an instance of the model with the given attributes. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + protected function makeInstance(array $attributes = []) + { + return Model::unguarded(function () use ($attributes) { + if (! isset($this->definitions[$this->class][$this->name])) { + throw new InvalidArgumentException("Unable to locate factory with name [{$this->name}] [{$this->class}]."); + } + + $definition = call_user_func($this->definitions[$this->class][$this->name], $this->faker, $attributes); + + return new $this->class(array_merge($definition, $attributes)); + }); + } +} diff --git a/vendor/illuminate/database/Eloquent/MassAssignmentException.php b/vendor/illuminate/database/Eloquent/MassAssignmentException.php new file mode 100755 index 0000000..7c81aae --- /dev/null +++ b/vendor/illuminate/database/Eloquent/MassAssignmentException.php @@ -0,0 +1,10 @@ +bootIfNotBooted(); + + $this->syncOriginal(); + + $this->fill($attributes); + } + + /** + * Check if the model needs to be booted and if so, do it. + * + * @return void + */ + protected function bootIfNotBooted() + { + $class = get_class($this); + + if (! isset(static::$booted[$class])) { + static::$booted[$class] = true; + + $this->fireModelEvent('booting', false); + + static::boot(); + + $this->fireModelEvent('booted', false); + } + } + + /** + * The "booting" method of the model. + * + * @return void + */ + protected static function boot() + { + static::bootTraits(); + } + + /** + * Boot all of the bootable traits on the model. + * + * @return void + */ + protected static function bootTraits() + { + foreach (class_uses_recursive(get_called_class()) as $trait) { + if (method_exists(get_called_class(), $method = 'boot'.class_basename($trait))) { + forward_static_call([get_called_class(), $method]); + } + } + } + + /** + * Clear the list of booted models so they will be re-booted. + * + * @return void + */ + public static function clearBootedModels() + { + static::$booted = []; + } + + /** + * Register a new global scope on the model. + * + * @param \Illuminate\Database\Eloquent\ScopeInterface $scope + * @return void + */ + public static function addGlobalScope(ScopeInterface $scope) + { + static::$globalScopes[get_called_class()][get_class($scope)] = $scope; + } + + /** + * Determine if a model has a global scope. + * + * @param \Illuminate\Database\Eloquent\ScopeInterface $scope + * @return bool + */ + public static function hasGlobalScope($scope) + { + return ! is_null(static::getGlobalScope($scope)); + } + + /** + * Get a global scope registered with the model. + * + * @param \Illuminate\Database\Eloquent\ScopeInterface $scope + * @return \Illuminate\Database\Eloquent\ScopeInterface|null + */ + public static function getGlobalScope($scope) + { + return Arr::first(static::$globalScopes[get_called_class()], function ($key, $value) use ($scope) { + return $scope instanceof $value; + }); + } + + /** + * Get the global scopes for this class instance. + * + * @return \Illuminate\Database\Eloquent\ScopeInterface[] + */ + public function getGlobalScopes() + { + return Arr::get(static::$globalScopes, get_class($this), []); + } + + /** + * Register an observer with the Model. + * + * @param object|string $class + * @param int $priority + * @return void + */ + public static function observe($class, $priority = 0) + { + $instance = new static; + + $className = is_string($class) ? $class : get_class($class); + + // When registering a model observer, we will spin through the possible events + // and determine if this observer has that method. If it does, we will hook + // it into the model's event system, making it convenient to watch these. + foreach ($instance->getObservableEvents() as $event) { + if (method_exists($class, $event)) { + static::registerModelEvent($event, $className.'@'.$event, $priority); + } + } + } + + /** + * Fill the model with an array of attributes. + * + * @param array $attributes + * @return $this + * + * @throws \Illuminate\Database\Eloquent\MassAssignmentException + */ + public function fill(array $attributes) + { + $totallyGuarded = $this->totallyGuarded(); + + foreach ($this->fillableFromArray($attributes) as $key => $value) { + $key = $this->removeTableFromKey($key); + + // The developers may choose to place some attributes in the "fillable" + // array, which means only those attributes may be set through mass + // assignment to the model, and all others will just be ignored. + if ($this->isFillable($key)) { + $this->setAttribute($key, $value); + } elseif ($totallyGuarded) { + throw new MassAssignmentException($key); + } + } + + return $this; + } + + /** + * Fill the model with an array of attributes. Force mass assignment. + * + * @param array $attributes + * @return $this + */ + public function forceFill(array $attributes) + { + // Since some versions of PHP have a bug that prevents it from properly + // binding the late static context in a closure, we will first store + // the model in a variable, which we will then use in the closure. + $model = $this; + + return static::unguarded(function () use ($model, $attributes) { + return $model->fill($attributes); + }); + } + + /** + * Get the fillable attributes of a given array. + * + * @param array $attributes + * @return array + */ + protected function fillableFromArray(array $attributes) + { + if (count($this->fillable) > 0 && ! static::$unguarded) { + return array_intersect_key($attributes, array_flip($this->fillable)); + } + + return $attributes; + } + + /** + * Create a new instance of the given model. + * + * @param array $attributes + * @param bool $exists + * @return static + */ + public function newInstance($attributes = [], $exists = false) + { + // This method just provides a convenient way for us to generate fresh model + // instances of this current model. It is particularly useful during the + // hydration of new objects via the Eloquent query builder instances. + $model = new static((array) $attributes); + + $model->exists = $exists; + + return $model; + } + + /** + * Create a new model instance that is existing. + * + * @param array $attributes + * @param string|null $connection + * @return static + */ + public function newFromBuilder($attributes = [], $connection = null) + { + $model = $this->newInstance([], true); + + $model->setRawAttributes((array) $attributes, true); + + $model->setConnection($connection ?: $this->connection); + + return $model; + } + + /** + * Create a collection of models from plain arrays. + * + * @param array $items + * @param string|null $connection + * @return \Illuminate\Database\Eloquent\Collection + */ + public static function hydrate(array $items, $connection = null) + { + $instance = (new static)->setConnection($connection); + + $items = array_map(function ($item) use ($instance) { + return $instance->newFromBuilder($item); + }, $items); + + return $instance->newCollection($items); + } + + /** + * Create a collection of models from a raw query. + * + * @param string $query + * @param array $bindings + * @param string|null $connection + * @return \Illuminate\Database\Eloquent\Collection + */ + public static function hydrateRaw($query, $bindings = [], $connection = null) + { + $instance = (new static)->setConnection($connection); + + $items = $instance->getConnection()->select($query, $bindings); + + return static::hydrate($items, $connection); + } + + /** + * Save a new model and return the instance. + * + * @param array $attributes + * @return static + */ + public static function create(array $attributes = []) + { + $model = new static($attributes); + + $model->save(); + + return $model; + } + + /** + * Save a new model and return the instance. Allow mass-assignment. + * + * @param array $attributes + * @return static + */ + public static function forceCreate(array $attributes) + { + // Since some versions of PHP have a bug that prevents it from properly + // binding the late static context in a closure, we will first store + // the model in a variable, which we will then use in the closure. + $model = new static; + + return static::unguarded(function () use ($model, $attributes) { + return $model->create($attributes); + }); + } + + /** + * Get the first record matching the attributes or create it. + * + * @param array $attributes + * @return static + */ + public static function firstOrCreate(array $attributes) + { + if (! is_null($instance = static::where($attributes)->first())) { + return $instance; + } + + return static::create($attributes); + } + + /** + * Get the first record matching the attributes or instantiate it. + * + * @param array $attributes + * @return static + */ + public static function firstOrNew(array $attributes) + { + if (! is_null($instance = static::where($attributes)->first())) { + return $instance; + } + + return new static($attributes); + } + + /** + * Create or update a record matching the attributes, and fill it with values. + * + * @param array $attributes + * @param array $values + * @return static + */ + public static function updateOrCreate(array $attributes, array $values = []) + { + $instance = static::firstOrNew($attributes); + + $instance->fill($values)->save(); + + return $instance; + } + + /** + * Begin querying the model. + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public static function query() + { + return (new static)->newQuery(); + } + + /** + * Begin querying the model on a given connection. + * + * @param string|null $connection + * @return \Illuminate\Database\Eloquent\Builder + */ + public static function on($connection = null) + { + // First we will just create a fresh instance of this model, and then we can + // set the connection on the model so that it is be used for the queries + // we execute, as well as being set on each relationship we retrieve. + $instance = new static; + + $instance->setConnection($connection); + + return $instance->newQuery(); + } + + /** + * Begin querying the model on the write connection. + * + * @return \Illuminate\Database\Query\Builder + */ + public static function onWriteConnection() + { + $instance = new static; + + return $instance->newQuery()->useWritePdo(); + } + + /** + * Get all of the models from the database. + * + * @param array|mixed $columns + * @return \Illuminate\Database\Eloquent\Collection|static[] + */ + public static function all($columns = ['*']) + { + $columns = is_array($columns) ? $columns : func_get_args(); + + $instance = new static; + + return $instance->newQuery()->get($columns); + } + + /** + * Find a model by its primary key or return new static. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Support\Collection|static + */ + public static function findOrNew($id, $columns = ['*']) + { + if (! is_null($model = static::find($id, $columns))) { + return $model; + } + + return new static; + } + + /** + * Reload a fresh model instance from the database. + * + * @param array $with + * @return $this|null + */ + public function fresh(array $with = []) + { + if (! $this->exists) { + return; + } + + $key = $this->getKeyName(); + + return static::with($with)->where($key, $this->getKey())->first(); + } + + /** + * Eager load relations on the model. + * + * @param array|string $relations + * @return $this + */ + public function load($relations) + { + if (is_string($relations)) { + $relations = func_get_args(); + } + + $query = $this->newQuery()->with($relations); + + $query->eagerLoadRelations([$this]); + + return $this; + } + + /** + * Begin querying a model with eager loading. + * + * @param array|string $relations + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public static function with($relations) + { + if (is_string($relations)) { + $relations = func_get_args(); + } + + $instance = new static; + + return $instance->newQuery()->with($relations); + } + + /** + * Append attributes to query when building a query. + * + * @param array|string $attributes + * @return $this + */ + public function append($attributes) + { + if (is_string($attributes)) { + $attributes = func_get_args(); + } + + $this->appends = array_unique( + array_merge($this->appends, $attributes) + ); + + return $this; + } + + /** + * Define a one-to-one relationship. + * + * @param string $related + * @param string $foreignKey + * @param string $localKey + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function hasOne($related, $foreignKey = null, $localKey = null) + { + $foreignKey = $foreignKey ?: $this->getForeignKey(); + + $instance = new $related; + + $localKey = $localKey ?: $this->getKeyName(); + + return new HasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey); + } + + /** + * Define a polymorphic one-to-one relationship. + * + * @param string $related + * @param string $name + * @param string $type + * @param string $id + * @param string $localKey + * @return \Illuminate\Database\Eloquent\Relations\MorphOne + */ + public function morphOne($related, $name, $type = null, $id = null, $localKey = null) + { + $instance = new $related; + + list($type, $id) = $this->getMorphs($name, $type, $id); + + $table = $instance->getTable(); + + $localKey = $localKey ?: $this->getKeyName(); + + return new MorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey); + } + + /** + * Define an inverse one-to-one or many relationship. + * + * @param string $related + * @param string $foreignKey + * @param string $otherKey + * @param string $relation + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null) + { + // If no relation name was given, we will use this debug backtrace to extract + // the calling method's name and use that as the relationship name as most + // of the time this will be what we desire to use for the relationships. + if (is_null($relation)) { + list($current, $caller) = debug_backtrace(false, 2); + + $relation = $caller['function']; + } + + // If no foreign key was supplied, we can use a backtrace to guess the proper + // foreign key name by using the name of the relationship function, which + // when combined with an "_id" should conventionally match the columns. + if (is_null($foreignKey)) { + $foreignKey = Str::snake($relation).'_id'; + } + + $instance = new $related; + + // Once we have the foreign key names, we'll just create a new Eloquent query + // for the related models and returns the relationship instance which will + // actually be responsible for retrieving and hydrating every relations. + $query = $instance->newQuery(); + + $otherKey = $otherKey ?: $instance->getKeyName(); + + return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation); + } + + /** + * Define a polymorphic, inverse one-to-one or many relationship. + * + * @param string $name + * @param string $type + * @param string $id + * @return \Illuminate\Database\Eloquent\Relations\MorphTo + */ + public function morphTo($name = null, $type = null, $id = null) + { + // If no name is provided, we will use the backtrace to get the function name + // since that is most likely the name of the polymorphic interface. We can + // use that to get both the class and foreign key that will be utilized. + if (is_null($name)) { + list($current, $caller) = debug_backtrace(false, 2); + + $name = Str::snake($caller['function']); + } + + list($type, $id) = $this->getMorphs($name, $type, $id); + + // If the type value is null it is probably safe to assume we're eager loading + // the relationship. When that is the case we will pass in a dummy query as + // there are multiple types in the morph and we can't use single queries. + if (is_null($class = $this->$type)) { + return new MorphTo( + $this->newQuery(), $this, $id, null, $type, $name + ); + } + + // If we are not eager loading the relationship we will essentially treat this + // as a belongs-to style relationship since morph-to extends that class and + // we will pass in the appropriate values so that it behaves as expected. + else { + $class = $this->getActualClassNameForMorph($class); + + $instance = new $class; + + return new MorphTo( + $instance->newQuery(), $this, $id, $instance->getKeyName(), $type, $name + ); + } + } + + /** + * Retrieve the fully qualified class name from a slug. + * + * @param string $class + * @return string + */ + public function getActualClassNameForMorph($class) + { + return Arr::get(Relation::morphMap(), $class, $class); + } + + /** + * Define a one-to-many relationship. + * + * @param string $related + * @param string $foreignKey + * @param string $localKey + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function hasMany($related, $foreignKey = null, $localKey = null) + { + $foreignKey = $foreignKey ?: $this->getForeignKey(); + + $instance = new $related; + + $localKey = $localKey ?: $this->getKeyName(); + + return new HasMany($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey); + } + + /** + * Define a has-many-through relationship. + * + * @param string $related + * @param string $through + * @param string|null $firstKey + * @param string|null $secondKey + * @param string|null $localKey + * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough + */ + public function hasManyThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null) + { + $through = new $through; + + $firstKey = $firstKey ?: $this->getForeignKey(); + + $secondKey = $secondKey ?: $through->getForeignKey(); + + $localKey = $localKey ?: $this->getKeyName(); + + return new HasManyThrough((new $related)->newQuery(), $this, $through, $firstKey, $secondKey, $localKey); + } + + /** + * Define a polymorphic one-to-many relationship. + * + * @param string $related + * @param string $name + * @param string $type + * @param string $id + * @param string $localKey + * @return \Illuminate\Database\Eloquent\Relations\MorphMany + */ + public function morphMany($related, $name, $type = null, $id = null, $localKey = null) + { + $instance = new $related; + + // Here we will gather up the morph type and ID for the relationship so that we + // can properly query the intermediate table of a relation. Finally, we will + // get the table and create the relationship instances for the developers. + list($type, $id) = $this->getMorphs($name, $type, $id); + + $table = $instance->getTable(); + + $localKey = $localKey ?: $this->getKeyName(); + + return new MorphMany($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey); + } + + /** + * Define a many-to-many relationship. + * + * @param string $related + * @param string $table + * @param string $foreignKey + * @param string $otherKey + * @param string $relation + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function belongsToMany($related, $table = null, $foreignKey = null, $otherKey = null, $relation = null) + { + // If no relationship name was passed, we will pull backtraces to get the + // name of the calling function. We will use that function name as the + // title of this relation since that is a great convention to apply. + if (is_null($relation)) { + $relation = $this->getBelongsToManyCaller(); + } + + // First, we'll need to determine the foreign key and "other key" for the + // relationship. Once we have determined the keys we'll make the query + // instances as well as the relationship instances we need for this. + $foreignKey = $foreignKey ?: $this->getForeignKey(); + + $instance = new $related; + + $otherKey = $otherKey ?: $instance->getForeignKey(); + + // If no table name was provided, we can guess it by concatenating the two + // models using underscores in alphabetical order. The two model names + // are transformed to snake case from their default CamelCase also. + if (is_null($table)) { + $table = $this->joiningTable($related); + } + + // Now we're ready to create a new query builder for the related model and + // the relationship instances for the relation. The relations will set + // appropriate query constraint and entirely manages the hydrations. + $query = $instance->newQuery(); + + return new BelongsToMany($query, $this, $table, $foreignKey, $otherKey, $relation); + } + + /** + * Define a polymorphic many-to-many relationship. + * + * @param string $related + * @param string $name + * @param string $table + * @param string $foreignKey + * @param string $otherKey + * @param bool $inverse + * @return \Illuminate\Database\Eloquent\Relations\MorphToMany + */ + public function morphToMany($related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false) + { + $caller = $this->getBelongsToManyCaller(); + + // First, we will need to determine the foreign key and "other key" for the + // relationship. Once we have determined the keys we will make the query + // instances, as well as the relationship instances we need for these. + $foreignKey = $foreignKey ?: $name.'_id'; + + $instance = new $related; + + $otherKey = $otherKey ?: $instance->getForeignKey(); + + // Now we're ready to create a new query builder for this related model and + // the relationship instances for this relation. This relations will set + // appropriate query constraints then entirely manages the hydrations. + $query = $instance->newQuery(); + + $table = $table ?: Str::plural($name); + + return new MorphToMany( + $query, $this, $name, $table, $foreignKey, + $otherKey, $caller, $inverse + ); + } + + /** + * Define a polymorphic, inverse many-to-many relationship. + * + * @param string $related + * @param string $name + * @param string $table + * @param string $foreignKey + * @param string $otherKey + * @return \Illuminate\Database\Eloquent\Relations\MorphToMany + */ + public function morphedByMany($related, $name, $table = null, $foreignKey = null, $otherKey = null) + { + $foreignKey = $foreignKey ?: $this->getForeignKey(); + + // For the inverse of the polymorphic many-to-many relations, we will change + // the way we determine the foreign and other keys, as it is the opposite + // of the morph-to-many method since we're figuring out these inverses. + $otherKey = $otherKey ?: $name.'_id'; + + return $this->morphToMany($related, $name, $table, $foreignKey, $otherKey, true); + } + + /** + * Get the relationship name of the belongs to many. + * + * @return string + */ + protected function getBelongsToManyCaller() + { + $self = __FUNCTION__; + + $caller = Arr::first(debug_backtrace(false), function ($key, $trace) use ($self) { + $caller = $trace['function']; + + return ! in_array($caller, Model::$manyMethods) && $caller != $self; + }); + + return ! is_null($caller) ? $caller['function'] : null; + } + + /** + * Get the joining table name for a many-to-many relation. + * + * @param string $related + * @return string + */ + public function joiningTable($related) + { + // The joining table name, by convention, is simply the snake cased models + // sorted alphabetically and concatenated with an underscore, so we can + // just sort the models and join them together to get the table name. + $base = Str::snake(class_basename($this)); + + $related = Str::snake(class_basename($related)); + + $models = [$related, $base]; + + // Now that we have the model names in an array we can just sort them and + // use the implode function to join them together with an underscores, + // which is typically used by convention within the database system. + sort($models); + + return strtolower(implode('_', $models)); + } + + /** + * Destroy the models for the given IDs. + * + * @param array|int $ids + * @return int + */ + public static function destroy($ids) + { + // We'll initialize a count here so we will return the total number of deletes + // for the operation. The developers can then check this number as a boolean + // type value or get this total count of records deleted for logging, etc. + $count = 0; + + $ids = is_array($ids) ? $ids : func_get_args(); + + $instance = new static; + + // We will actually pull the models from the database table and call delete on + // each of them individually so that their events get fired properly with a + // correct set of attributes in case the developers wants to check these. + $key = $instance->getKeyName(); + + foreach ($instance->whereIn($key, $ids)->get() as $model) { + if ($model->delete()) { + $count++; + } + } + + return $count; + } + + /** + * Delete the model from the database. + * + * @return bool|null + * @throws \Exception + */ + public function delete() + { + if (is_null($this->getKeyName())) { + throw new Exception('No primary key defined on model.'); + } + + if ($this->exists) { + if ($this->fireModelEvent('deleting') === false) { + return false; + } + + // Here, we'll touch the owning models, verifying these timestamps get updated + // for the models. This will allow any caching to get broken on the parents + // by the timestamp. Then we will go ahead and delete the model instance. + $this->touchOwners(); + + $this->performDeleteOnModel(); + + $this->exists = false; + + // Once the model has been deleted, we will fire off the deleted event so that + // the developers may hook into post-delete operations. We will then return + // a boolean true as the delete is presumably successful on the database. + $this->fireModelEvent('deleted', false); + + return true; + } + } + + /** + * Force a hard delete on a soft deleted model. + * + * This method protects developers from running forceDelete when trait is missing. + * + * @return bool|null + */ + public function forceDelete() + { + return $this->delete(); + } + + /** + * Perform the actual delete query on this model instance. + * + * @return void + */ + protected function performDeleteOnModel() + { + $this->setKeysForSaveQuery($this->newQueryWithoutScopes())->delete(); + } + + /** + * Register a saving model event with the dispatcher. + * + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + public static function saving($callback, $priority = 0) + { + static::registerModelEvent('saving', $callback, $priority); + } + + /** + * Register a saved model event with the dispatcher. + * + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + public static function saved($callback, $priority = 0) + { + static::registerModelEvent('saved', $callback, $priority); + } + + /** + * Register an updating model event with the dispatcher. + * + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + public static function updating($callback, $priority = 0) + { + static::registerModelEvent('updating', $callback, $priority); + } + + /** + * Register an updated model event with the dispatcher. + * + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + public static function updated($callback, $priority = 0) + { + static::registerModelEvent('updated', $callback, $priority); + } + + /** + * Register a creating model event with the dispatcher. + * + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + public static function creating($callback, $priority = 0) + { + static::registerModelEvent('creating', $callback, $priority); + } + + /** + * Register a created model event with the dispatcher. + * + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + public static function created($callback, $priority = 0) + { + static::registerModelEvent('created', $callback, $priority); + } + + /** + * Register a deleting model event with the dispatcher. + * + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + public static function deleting($callback, $priority = 0) + { + static::registerModelEvent('deleting', $callback, $priority); + } + + /** + * Register a deleted model event with the dispatcher. + * + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + public static function deleted($callback, $priority = 0) + { + static::registerModelEvent('deleted', $callback, $priority); + } + + /** + * Remove all of the event listeners for the model. + * + * @return void + */ + public static function flushEventListeners() + { + if (! isset(static::$dispatcher)) { + return; + } + + $instance = new static; + + foreach ($instance->getObservableEvents() as $event) { + static::$dispatcher->forget("eloquent.{$event}: ".get_called_class()); + } + } + + /** + * Register a model event with the dispatcher. + * + * @param string $event + * @param \Closure|string $callback + * @param int $priority + * @return void + */ + protected static function registerModelEvent($event, $callback, $priority = 0) + { + if (isset(static::$dispatcher)) { + $name = get_called_class(); + + static::$dispatcher->listen("eloquent.{$event}: {$name}", $callback, $priority); + } + } + + /** + * Get the observable event names. + * + * @return array + */ + public function getObservableEvents() + { + return array_merge( + [ + 'creating', 'created', 'updating', 'updated', + 'deleting', 'deleted', 'saving', 'saved', + 'restoring', 'restored', + ], + $this->observables + ); + } + + /** + * Set the observable event names. + * + * @param array $observables + * @return $this + */ + public function setObservableEvents(array $observables) + { + $this->observables = $observables; + + return $this; + } + + /** + * Add an observable event name. + * + * @param array|mixed $observables + * @return void + */ + public function addObservableEvents($observables) + { + $observables = is_array($observables) ? $observables : func_get_args(); + + $this->observables = array_unique(array_merge($this->observables, $observables)); + } + + /** + * Remove an observable event name. + * + * @param array|mixed $observables + * @return void + */ + public function removeObservableEvents($observables) + { + $observables = is_array($observables) ? $observables : func_get_args(); + + $this->observables = array_diff($this->observables, $observables); + } + + /** + * Increment a column's value by a given amount. + * + * @param string $column + * @param int $amount + * @return int + */ + protected function increment($column, $amount = 1) + { + return $this->incrementOrDecrement($column, $amount, 'increment'); + } + + /** + * Decrement a column's value by a given amount. + * + * @param string $column + * @param int $amount + * @return int + */ + protected function decrement($column, $amount = 1) + { + return $this->incrementOrDecrement($column, $amount, 'decrement'); + } + + /** + * Run the increment or decrement method on the model. + * + * @param string $column + * @param int $amount + * @param string $method + * @return int + */ + protected function incrementOrDecrement($column, $amount, $method) + { + $query = $this->newQuery(); + + if (! $this->exists) { + return $query->{$method}($column, $amount); + } + + $this->incrementOrDecrementAttributeValue($column, $amount, $method); + + return $query->where($this->getKeyName(), $this->getKey())->{$method}($column, $amount); + } + + /** + * Increment the underlying attribute value and sync with original. + * + * @param string $column + * @param int $amount + * @param string $method + * @return void + */ + protected function incrementOrDecrementAttributeValue($column, $amount, $method) + { + $this->{$column} = $this->{$column} + ($method == 'increment' ? $amount : $amount * -1); + + $this->syncOriginalAttribute($column); + } + + /** + * Update the model in the database. + * + * @param array $attributes + * @return bool|int + */ + public function update(array $attributes = []) + { + if (! $this->exists) { + return $this->newQuery()->update($attributes); + } + + return $this->fill($attributes)->save(); + } + + /** + * Save the model and all of its relationships. + * + * @return bool + */ + public function push() + { + if (! $this->save()) { + return false; + } + + // To sync all of the relationships to the database, we will simply spin through + // the relationships and save each model via this "push" method, which allows + // us to recurse into all of these nested relations for the model instance. + foreach ($this->relations as $models) { + $models = $models instanceof Collection + ? $models->all() : [$models]; + + foreach (array_filter($models) as $model) { + if (! $model->push()) { + return false; + } + } + } + + return true; + } + + /** + * Save the model to the database. + * + * @param array $options + * @return bool + */ + public function save(array $options = []) + { + $query = $this->newQueryWithoutScopes(); + + // If the "saving" event returns false we'll bail out of the save and return + // false, indicating that the save failed. This provides a chance for any + // listeners to cancel save operations if validations fail or whatever. + if ($this->fireModelEvent('saving') === false) { + return false; + } + + // If the model already exists in the database we can just update our record + // that is already in this database using the current IDs in this "where" + // clause to only update this model. Otherwise, we'll just insert them. + if ($this->exists) { + $saved = $this->performUpdate($query, $options); + } + + // If the model is brand new, we'll insert it into our database and set the + // ID attribute on the model to the value of the newly inserted row's ID + // which is typically an auto-increment value managed by the database. + else { + $saved = $this->performInsert($query, $options); + } + + if ($saved) { + $this->finishSave($options); + } + + return $saved; + } + + /** + * Finish processing on a successful save operation. + * + * @param array $options + * @return void + */ + protected function finishSave(array $options) + { + $this->fireModelEvent('saved', false); + + $this->syncOriginal(); + + if (Arr::get($options, 'touch', true)) { + $this->touchOwners(); + } + } + + /** + * Perform a model update operation. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param array $options + * @return bool + */ + protected function performUpdate(Builder $query, array $options = []) + { + $dirty = $this->getDirty(); + + if (count($dirty) > 0) { + // If the updating event returns false, we will cancel the update operation so + // developers can hook Validation systems into their models and cancel this + // operation if the model does not pass validation. Otherwise, we update. + if ($this->fireModelEvent('updating') === false) { + return false; + } + + // First we need to create a fresh query instance and touch the creation and + // update timestamp on the model which are maintained by us for developer + // convenience. Then we will just continue saving the model instances. + if ($this->timestamps && Arr::get($options, 'timestamps', true)) { + $this->updateTimestamps(); + } + + // Once we have run the update operation, we will fire the "updated" event for + // this model instance. This will allow developers to hook into these after + // models are updated, giving them a chance to do any special processing. + $dirty = $this->getDirty(); + + if (count($dirty) > 0) { + $numRows = $this->setKeysForSaveQuery($query)->update($dirty); + + $this->fireModelEvent('updated', false); + } + } + + return true; + } + + /** + * Perform a model insert operation. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param array $options + * @return bool + */ + protected function performInsert(Builder $query, array $options = []) + { + if ($this->fireModelEvent('creating') === false) { + return false; + } + + // First we'll need to create a fresh query instance and touch the creation and + // update timestamps on this model, which are maintained by us for developer + // convenience. After, we will just continue saving these model instances. + if ($this->timestamps && Arr::get($options, 'timestamps', true)) { + $this->updateTimestamps(); + } + + // If the model has an incrementing key, we can use the "insertGetId" method on + // the query builder, which will give us back the final inserted ID for this + // table from the database. Not all tables have to be incrementing though. + $attributes = $this->attributes; + + if ($this->incrementing) { + $this->insertAndSetId($query, $attributes); + } + + // If the table isn't incrementing we'll simply insert these attributes as they + // are. These attribute arrays must contain an "id" column previously placed + // there by the developer as the manually determined key for these models. + else { + $query->insert($attributes); + } + + // We will go ahead and set the exists property to true, so that it is set when + // the created event is fired, just in case the developer tries to update it + // during the event. This will allow them to do so and run an update here. + $this->exists = true; + + $this->wasRecentlyCreated = true; + + $this->fireModelEvent('created', false); + + return true; + } + + /** + * Insert the given attributes and set the ID on the model. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param array $attributes + * @return void + */ + protected function insertAndSetId(Builder $query, $attributes) + { + $id = $query->insertGetId($attributes, $keyName = $this->getKeyName()); + + $this->setAttribute($keyName, $id); + } + + /** + * Touch the owning relations of the model. + * + * @return void + */ + public function touchOwners() + { + foreach ($this->touches as $relation) { + $this->$relation()->touch(); + + if ($this->$relation instanceof self) { + $this->$relation->touchOwners(); + } elseif ($this->$relation instanceof Collection) { + $this->$relation->each(function (Model $relation) { + $relation->touchOwners(); + }); + } + } + } + + /** + * Determine if the model touches a given relation. + * + * @param string $relation + * @return bool + */ + public function touches($relation) + { + return in_array($relation, $this->touches); + } + + /** + * Fire the given event for the model. + * + * @param string $event + * @param bool $halt + * @return mixed + */ + protected function fireModelEvent($event, $halt = true) + { + if (! isset(static::$dispatcher)) { + return true; + } + + // We will append the names of the class to the event to distinguish it from + // other model events that are fired, allowing us to listen on each model + // event set individually instead of catching event for all the models. + $event = "eloquent.{$event}: ".get_class($this); + + $method = $halt ? 'until' : 'fire'; + + return static::$dispatcher->$method($event, $this); + } + + /** + * Set the keys for a save update query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @return \Illuminate\Database\Eloquent\Builder + */ + protected function setKeysForSaveQuery(Builder $query) + { + $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery()); + + return $query; + } + + /** + * Get the primary key value for a save query. + * + * @return mixed + */ + protected function getKeyForSaveQuery() + { + if (isset($this->original[$this->getKeyName()])) { + return $this->original[$this->getKeyName()]; + } + + return $this->getAttribute($this->getKeyName()); + } + + /** + * Update the model's update timestamp. + * + * @return bool + */ + public function touch() + { + if (! $this->timestamps) { + return false; + } + + $this->updateTimestamps(); + + return $this->save(); + } + + /** + * Update the creation and update timestamps. + * + * @return void + */ + protected function updateTimestamps() + { + $time = $this->freshTimestamp(); + + if (! $this->isDirty(static::UPDATED_AT)) { + $this->setUpdatedAt($time); + } + + if (! $this->exists && ! $this->isDirty(static::CREATED_AT)) { + $this->setCreatedAt($time); + } + } + + /** + * Set the value of the "created at" attribute. + * + * @param mixed $value + * @return $this + */ + public function setCreatedAt($value) + { + $this->{static::CREATED_AT} = $value; + + return $this; + } + + /** + * Set the value of the "updated at" attribute. + * + * @param mixed $value + * @return $this + */ + public function setUpdatedAt($value) + { + $this->{static::UPDATED_AT} = $value; + + return $this; + } + + /** + * Get the name of the "created at" column. + * + * @return string + */ + public function getCreatedAtColumn() + { + return static::CREATED_AT; + } + + /** + * Get the name of the "updated at" column. + * + * @return string + */ + public function getUpdatedAtColumn() + { + return static::UPDATED_AT; + } + + /** + * Get a fresh timestamp for the model. + * + * @return \Carbon\Carbon + */ + public function freshTimestamp() + { + return new Carbon; + } + + /** + * Get a fresh timestamp for the model. + * + * @return string + */ + public function freshTimestampString() + { + return $this->fromDateTime($this->freshTimestamp()); + } + + /** + * Get a new query builder for the model's table. + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function newQuery() + { + $builder = $this->newQueryWithoutScopes(); + + return $this->applyGlobalScopes($builder); + } + + /** + * Get a new query instance without a given scope. + * + * @param \Illuminate\Database\Eloquent\ScopeInterface $scope + * @return \Illuminate\Database\Eloquent\Builder + */ + public function newQueryWithoutScope($scope) + { + $this->getGlobalScope($scope)->remove($builder = $this->newQuery(), $this); + + return $builder; + } + + /** + * Get a new query builder that doesn't have any global scopes. + * + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function newQueryWithoutScopes() + { + $builder = $this->newEloquentBuilder( + $this->newBaseQueryBuilder() + ); + + // Once we have the query builders, we will set the model instances so the + // builder can easily access any information it may need from the model + // while it is constructing and executing various queries against it. + return $builder->setModel($this)->with($this->with); + } + + /** + * Apply all of the global scopes to an Eloquent builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return \Illuminate\Database\Eloquent\Builder + */ + public function applyGlobalScopes($builder) + { + foreach ($this->getGlobalScopes() as $scope) { + $scope->apply($builder, $this); + } + + return $builder; + } + + /** + * Remove all of the global scopes from an Eloquent builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return \Illuminate\Database\Eloquent\Builder + */ + public function removeGlobalScopes($builder) + { + foreach ($this->getGlobalScopes() as $scope) { + $scope->remove($builder, $this); + } + + return $builder; + } + + /** + * Create a new Eloquent query builder for the model. + * + * @param \Illuminate\Database\Query\Builder $query + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function newEloquentBuilder($query) + { + return new Builder($query); + } + + /** + * Get a new query builder instance for the connection. + * + * @return \Illuminate\Database\Query\Builder + */ + protected function newBaseQueryBuilder() + { + $conn = $this->getConnection(); + + $grammar = $conn->getQueryGrammar(); + + return new QueryBuilder($conn, $grammar, $conn->getPostProcessor()); + } + + /** + * Create a new Eloquent Collection instance. + * + * @param array $models + * @return \Illuminate\Database\Eloquent\Collection + */ + public function newCollection(array $models = []) + { + return new Collection($models); + } + + /** + * Create a new pivot model instance. + * + * @param \Illuminate\Database\Eloquent\Model $parent + * @param array $attributes + * @param string $table + * @param bool $exists + * @return \Illuminate\Database\Eloquent\Relations\Pivot + */ + public function newPivot(Model $parent, array $attributes, $table, $exists) + { + return new Pivot($parent, $attributes, $table, $exists); + } + + /** + * Get the table associated with the model. + * + * @return string + */ + public function getTable() + { + if (isset($this->table)) { + return $this->table; + } + + return str_replace('\\', '', Str::snake(Str::plural(class_basename($this)))); + } + + /** + * Set the table associated with the model. + * + * @param string $table + * @return $this + */ + public function setTable($table) + { + $this->table = $table; + + return $this; + } + + /** + * Get the value of the model's primary key. + * + * @return mixed + */ + public function getKey() + { + return $this->getAttribute($this->getKeyName()); + } + + /** + * Get the queueable identity for the entity. + * + * @return mixed + */ + public function getQueueableId() + { + return $this->getKey(); + } + + /** + * Get the primary key for the model. + * + * @return string + */ + public function getKeyName() + { + return $this->primaryKey; + } + + /** + * Set the primary key for the model. + * + * @param string $key + * @return $this + */ + public function setKeyName($key) + { + $this->primaryKey = $key; + + return $this; + } + + /** + * Get the table qualified key name. + * + * @return string + */ + public function getQualifiedKeyName() + { + return $this->getTable().'.'.$this->getKeyName(); + } + + /** + * Get the value of the model's route key. + * + * @return mixed + */ + public function getRouteKey() + { + return $this->getAttribute($this->getRouteKeyName()); + } + + /** + * Get the route key for the model. + * + * @return string + */ + public function getRouteKeyName() + { + return $this->getKeyName(); + } + + /** + * Determine if the model uses timestamps. + * + * @return bool + */ + public function usesTimestamps() + { + return $this->timestamps; + } + + /** + * Get the polymorphic relationship columns. + * + * @param string $name + * @param string $type + * @param string $id + * @return array + */ + protected function getMorphs($name, $type, $id) + { + $type = $type ?: $name.'_type'; + + $id = $id ?: $name.'_id'; + + return [$type, $id]; + } + + /** + * Get the class name for polymorphic relations. + * + * @return string + */ + public function getMorphClass() + { + $morphMap = Relation::morphMap(); + + $class = get_class($this); + + if (! empty($morphMap) && in_array($class, $morphMap)) { + return array_search($class, $morphMap, true); + } + + return $this->morphClass ?: $class; + } + + /** + * Get the number of models to return per page. + * + * @return int + */ + public function getPerPage() + { + return $this->perPage; + } + + /** + * Set the number of models to return per page. + * + * @param int $perPage + * @return $this + */ + public function setPerPage($perPage) + { + $this->perPage = $perPage; + + return $this; + } + + /** + * Get the default foreign key name for the model. + * + * @return string + */ + public function getForeignKey() + { + return Str::snake(class_basename($this)).'_id'; + } + + /** + * Get the hidden attributes for the model. + * + * @return array + */ + public function getHidden() + { + return $this->hidden; + } + + /** + * Set the hidden attributes for the model. + * + * @param array $hidden + * @return $this + */ + public function setHidden(array $hidden) + { + $this->hidden = $hidden; + + return $this; + } + + /** + * Add hidden attributes for the model. + * + * @param array|string|null $attributes + * @return void + */ + public function addHidden($attributes = null) + { + $attributes = is_array($attributes) ? $attributes : func_get_args(); + + $this->hidden = array_merge($this->hidden, $attributes); + } + + /** + * Make the given, typically hidden, attributes visible. + * + * @param array|string $attributes + * @return $this + */ + public function withHidden($attributes) + { + $this->hidden = array_diff($this->hidden, (array) $attributes); + + return $this; + } + + /** + * Get the visible attributes for the model. + * + * @return array + */ + public function getVisible() + { + return $this->visible; + } + + /** + * Set the visible attributes for the model. + * + * @param array $visible + * @return $this + */ + public function setVisible(array $visible) + { + $this->visible = $visible; + + return $this; + } + + /** + * Add visible attributes for the model. + * + * @param array|string|null $attributes + * @return void + */ + public function addVisible($attributes = null) + { + $attributes = is_array($attributes) ? $attributes : func_get_args(); + + $this->visible = array_merge($this->visible, $attributes); + } + + /** + * Set the accessors to append to model arrays. + * + * @param array $appends + * @return $this + */ + public function setAppends(array $appends) + { + $this->appends = $appends; + + return $this; + } + + /** + * Get the fillable attributes for the model. + * + * @return array + */ + public function getFillable() + { + return $this->fillable; + } + + /** + * Set the fillable attributes for the model. + * + * @param array $fillable + * @return $this + */ + public function fillable(array $fillable) + { + $this->fillable = $fillable; + + return $this; + } + + /** + * Get the guarded attributes for the model. + * + * @return array + */ + public function getGuarded() + { + return $this->guarded; + } + + /** + * Set the guarded attributes for the model. + * + * @param array $guarded + * @return $this + */ + public function guard(array $guarded) + { + $this->guarded = $guarded; + + return $this; + } + + /** + * Disable all mass assignable restrictions. + * + * @param bool $state + * @return void + */ + public static function unguard($state = true) + { + static::$unguarded = $state; + } + + /** + * Enable the mass assignment restrictions. + * + * @return void + */ + public static function reguard() + { + static::$unguarded = false; + } + + /** + * Determine if current state is "unguarded". + * + * @return bool + */ + public static function isUnguarded() + { + return static::$unguarded; + } + + /** + * Run the given callable while being unguarded. + * + * @param callable $callback + * @return mixed + */ + public static function unguarded(callable $callback) + { + if (static::$unguarded) { + return $callback(); + } + + static::unguard(); + + $result = $callback(); + + static::reguard(); + + return $result; + } + + /** + * Determine if the given attribute may be mass assigned. + * + * @param string $key + * @return bool + */ + public function isFillable($key) + { + if (static::$unguarded) { + return true; + } + + // If the key is in the "fillable" array, we can of course assume that it's + // a fillable attribute. Otherwise, we will check the guarded array when + // we need to determine if the attribute is black-listed on the model. + if (in_array($key, $this->fillable)) { + return true; + } + + if ($this->isGuarded($key)) { + return false; + } + + return empty($this->fillable) && ! Str::startsWith($key, '_'); + } + + /** + * Determine if the given key is guarded. + * + * @param string $key + * @return bool + */ + public function isGuarded($key) + { + return in_array($key, $this->guarded) || $this->guarded == ['*']; + } + + /** + * Determine if the model is totally guarded. + * + * @return bool + */ + public function totallyGuarded() + { + return count($this->fillable) == 0 && $this->guarded == ['*']; + } + + /** + * Remove the table name from a given key. + * + * @param string $key + * @return string + */ + protected function removeTableFromKey($key) + { + if (! Str::contains($key, '.')) { + return $key; + } + + return last(explode('.', $key)); + } + + /** + * Get the relationships that are touched on save. + * + * @return array + */ + public function getTouchedRelations() + { + return $this->touches; + } + + /** + * Set the relationships that are touched on save. + * + * @param array $touches + * @return $this + */ + public function setTouchedRelations(array $touches) + { + $this->touches = $touches; + + return $this; + } + + /** + * Get the value indicating whether the IDs are incrementing. + * + * @return bool + */ + public function getIncrementing() + { + return $this->incrementing; + } + + /** + * Set whether IDs are incrementing. + * + * @param bool $value + * @return $this + */ + public function setIncrementing($value) + { + $this->incrementing = $value; + + return $this; + } + + /** + * Convert the model instance to JSON. + * + * @param int $options + * @return string + */ + public function toJson($options = 0) + { + return json_encode($this->jsonSerialize(), $options); + } + + /** + * Convert the object into something JSON serializable. + * + * @return array + */ + public function jsonSerialize() + { + return $this->toArray(); + } + + /** + * Convert the model instance to an array. + * + * @return array + */ + public function toArray() + { + $attributes = $this->attributesToArray(); + + return array_merge($attributes, $this->relationsToArray()); + } + + /** + * Convert the model's attributes to an array. + * + * @return array + */ + public function attributesToArray() + { + $attributes = $this->getArrayableAttributes(); + + // If an attribute is a date, we will cast it to a string after converting it + // to a DateTime / Carbon instance. This is so we will get some consistent + // formatting while accessing attributes vs. arraying / JSONing a model. + foreach ($this->getDates() as $key) { + if (! isset($attributes[$key])) { + continue; + } + + $attributes[$key] = $this->serializeDate( + $this->asDateTime($attributes[$key]) + ); + } + + $mutatedAttributes = $this->getMutatedAttributes(); + + // We want to spin through all the mutated attributes for this model and call + // the mutator for the attribute. We cache off every mutated attributes so + // we don't have to constantly check on attributes that actually change. + foreach ($mutatedAttributes as $key) { + if (! array_key_exists($key, $attributes)) { + continue; + } + + $attributes[$key] = $this->mutateAttributeForArray( + $key, $attributes[$key] + ); + } + + // Next we will handle any casts that have been setup for this model and cast + // the values to their appropriate type. If the attribute has a mutator we + // will not perform the cast on those attributes to avoid any confusion. + foreach ($this->casts as $key => $value) { + if (! array_key_exists($key, $attributes) || + in_array($key, $mutatedAttributes)) { + continue; + } + + $attributes[$key] = $this->castAttribute( + $key, $attributes[$key] + ); + } + + // Here we will grab all of the appended, calculated attributes to this model + // as these attributes are not really in the attributes array, but are run + // when we need to array or JSON the model for convenience to the coder. + foreach ($this->getArrayableAppends() as $key) { + $attributes[$key] = $this->mutateAttributeForArray($key, null); + } + + return $attributes; + } + + /** + * Get an attribute array of all arrayable attributes. + * + * @return array + */ + protected function getArrayableAttributes() + { + return $this->getArrayableItems($this->attributes); + } + + /** + * Get all of the appendable values that are arrayable. + * + * @return array + */ + protected function getArrayableAppends() + { + if (! count($this->appends)) { + return []; + } + + return $this->getArrayableItems( + array_combine($this->appends, $this->appends) + ); + } + + /** + * Get the model's relationships in array form. + * + * @return array + */ + public function relationsToArray() + { + $attributes = []; + + foreach ($this->getArrayableRelations() as $key => $value) { + // If the values implements the Arrayable interface we can just call this + // toArray method on the instances which will convert both models and + // collections to their proper array form and we'll set the values. + if ($value instanceof Arrayable) { + $relation = $value->toArray(); + } + + // If the value is null, we'll still go ahead and set it in this list of + // attributes since null is used to represent empty relationships if + // if it a has one or belongs to type relationships on the models. + elseif (is_null($value)) { + $relation = $value; + } + + // If the relationships snake-casing is enabled, we will snake case this + // key so that the relation attribute is snake cased in this returned + // array to the developers, making this consistent with attributes. + if (static::$snakeAttributes) { + $key = Str::snake($key); + } + + // If the relation value has been set, we will set it on this attributes + // list for returning. If it was not arrayable or null, we'll not set + // the value on the array because it is some type of invalid value. + if (isset($relation) || is_null($value)) { + $attributes[$key] = $relation; + } + + unset($relation); + } + + return $attributes; + } + + /** + * Get an attribute array of all arrayable relations. + * + * @return array + */ + protected function getArrayableRelations() + { + return $this->getArrayableItems($this->relations); + } + + /** + * Get an attribute array of all arrayable values. + * + * @param array $values + * @return array + */ + protected function getArrayableItems(array $values) + { + if (count($this->getVisible()) > 0) { + return array_intersect_key($values, array_flip($this->getVisible())); + } + + return array_diff_key($values, array_flip($this->getHidden())); + } + + /** + * Get an attribute from the model. + * + * @param string $key + * @return mixed + */ + public function getAttribute($key) + { + if (array_key_exists($key, $this->attributes) || $this->hasGetMutator($key)) { + return $this->getAttributeValue($key); + } + + return $this->getRelationValue($key); + } + + /** + * Get a plain attribute (not a relationship). + * + * @param string $key + * @return mixed + */ + public function getAttributeValue($key) + { + $value = $this->getAttributeFromArray($key); + + // If the attribute has a get mutator, we will call that then return what + // it returns as the value, which is useful for transforming values on + // retrieval from the model to a form that is more useful for usage. + if ($this->hasGetMutator($key)) { + return $this->mutateAttribute($key, $value); + } + + // If the attribute exists within the cast array, we will convert it to + // an appropriate native PHP type dependant upon the associated value + // given with the key in the pair. Dayle made this comment line up. + if ($this->hasCast($key)) { + $value = $this->castAttribute($key, $value); + } + + // If the attribute is listed as a date, we will convert it to a DateTime + // instance on retrieval, which makes it quite convenient to work with + // date fields without having to create a mutator for each property. + elseif (in_array($key, $this->getDates())) { + if (! is_null($value)) { + return $this->asDateTime($value); + } + } + + return $value; + } + + /** + * Get a relationship. + * + * @param string $key + * @return mixed + */ + public function getRelationValue($key) + { + // If the key already exists in the relationships array, it just means the + // relationship has already been loaded, so we'll just return it out of + // here because there is no need to query within the relations twice. + if ($this->relationLoaded($key)) { + return $this->relations[$key]; + } + + // If the "attribute" exists as a method on the model, we will just assume + // it is a relationship and will load and return results from the query + // and hydrate the relationship's value on the "relationships" array. + if (method_exists($this, $key)) { + return $this->getRelationshipFromMethod($key); + } + } + + /** + * Get an attribute from the $attributes array. + * + * @param string $key + * @return mixed + */ + protected function getAttributeFromArray($key) + { + if (array_key_exists($key, $this->attributes)) { + return $this->attributes[$key]; + } + } + + /** + * Get a relationship value from a method. + * + * @param string $method + * @return mixed + * + * @throws \LogicException + */ + protected function getRelationshipFromMethod($method) + { + $relations = $this->$method(); + + if (! $relations instanceof Relation) { + throw new LogicException('Relationship method must return an object of type ' + .'Illuminate\Database\Eloquent\Relations\Relation'); + } + + return $this->relations[$method] = $relations->getResults(); + } + + /** + * Determine if a get mutator exists for an attribute. + * + * @param string $key + * @return bool + */ + public function hasGetMutator($key) + { + return method_exists($this, 'get'.Str::studly($key).'Attribute'); + } + + /** + * Get the value of an attribute using its mutator. + * + * @param string $key + * @param mixed $value + * @return mixed + */ + protected function mutateAttribute($key, $value) + { + return $this->{'get'.Str::studly($key).'Attribute'}($value); + } + + /** + * Get the value of an attribute using its mutator for array conversion. + * + * @param string $key + * @param mixed $value + * @return mixed + */ + protected function mutateAttributeForArray($key, $value) + { + $value = $this->mutateAttribute($key, $value); + + return $value instanceof Arrayable ? $value->toArray() : $value; + } + + /** + * Determine whether an attribute should be casted to a native type. + * + * @param string $key + * @return bool + */ + protected function hasCast($key) + { + return array_key_exists($key, $this->casts); + } + + /** + * Determine whether a value is Date / DateTime castable for inbound manipulation. + * + * @param string $key + * @return bool + */ + protected function isDateCastable($key) + { + return $this->hasCast($key) && + in_array($this->getCastType($key), ['date', 'datetime'], true); + } + + /** + * Determine whether a value is JSON castable for inbound manipulation. + * + * @param string $key + * @return bool + */ + protected function isJsonCastable($key) + { + return $this->hasCast($key) && + in_array($this->getCastType($key), ['array', 'json', 'object', 'collection'], true); + } + + /** + * Get the type of cast for a model attribute. + * + * @param string $key + * @return string + */ + protected function getCastType($key) + { + return trim(strtolower($this->casts[$key])); + } + + /** + * Cast an attribute to a native PHP type. + * + * @param string $key + * @param mixed $value + * @return mixed + */ + protected function castAttribute($key, $value) + { + if (is_null($value)) { + return $value; + } + + switch ($this->getCastType($key)) { + case 'int': + case 'integer': + return (int) $value; + case 'real': + case 'float': + case 'double': + return (float) $value; + case 'string': + return (string) $value; + case 'bool': + case 'boolean': + return (bool) $value; + case 'object': + return $this->fromJson($value, true); + case 'array': + case 'json': + return $this->fromJson($value); + case 'collection': + return new BaseCollection($this->fromJson($value)); + case 'date': + case 'datetime': + return $this->asDateTime($value); + default: + return $value; + } + } + + /** + * Set a given attribute on the model. + * + * @param string $key + * @param mixed $value + * @return $this + */ + public function setAttribute($key, $value) + { + // First we will check for the presence of a mutator for the set operation + // which simply lets the developers tweak the attribute as it is set on + // the model, such as "json_encoding" an listing of data for storage. + if ($this->hasSetMutator($key)) { + $method = 'set'.Str::studly($key).'Attribute'; + + return $this->{$method}($value); + } + + // If an attribute is listed as a "date", we'll convert it from a DateTime + // instance into a form proper for storage on the database tables using + // the connection grammar's date format. We will auto set the values. + elseif ($value && (in_array($key, $this->getDates()) || $this->isDateCastable($key))) { + $value = $this->fromDateTime($value); + } + + if ($this->isJsonCastable($key) && ! is_null($value)) { + $value = $this->asJson($value); + } + + $this->attributes[$key] = $value; + + return $this; + } + + /** + * Determine if a set mutator exists for an attribute. + * + * @param string $key + * @return bool + */ + public function hasSetMutator($key) + { + return method_exists($this, 'set'.Str::studly($key).'Attribute'); + } + + /** + * Get the attributes that should be converted to dates. + * + * @return array + */ + public function getDates() + { + $defaults = [static::CREATED_AT, static::UPDATED_AT]; + + return $this->timestamps ? array_merge($this->dates, $defaults) : $this->dates; + } + + /** + * Convert a DateTime to a storable string. + * + * @param \DateTime|int $value + * @return string + */ + public function fromDateTime($value) + { + $format = $this->getDateFormat(); + + $value = $this->asDateTime($value); + + return $value->format($format); + } + + /** + * Return a timestamp as DateTime object. + * + * @param mixed $value + * @return \Carbon\Carbon + */ + protected function asDateTime($value) + { + // If this value is already a Carbon instance, we shall just return it as is. + // This prevents us having to reinstantiate a Carbon instance when we know + // it already is one, which wouldn't be fulfilled by the DateTime check. + if ($value instanceof Carbon) { + return $value; + } + + // If the value is already a DateTime instance, we will just skip the rest of + // these checks since they will be a waste of time, and hinder performance + // when checking the field. We will just return the DateTime right away. + if ($value instanceof DateTime) { + return Carbon::instance($value); + } + + // If this value is an integer, we will assume it is a UNIX timestamp's value + // and format a Carbon object from this timestamp. This allows flexibility + // when defining your date fields as they might be UNIX timestamps here. + if (is_numeric($value)) { + return Carbon::createFromTimestamp($value); + } + + // If the value is in simply year, month, day format, we will instantiate the + // Carbon instances from that format. Again, this provides for simple date + // fields on the database, while still supporting Carbonized conversion. + if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $value)) { + return Carbon::createFromFormat('Y-m-d', $value)->startOfDay(); + } + + // Finally, we will just assume this date is in the format used by default on + // the database connection and use that format to create the Carbon object + // that is returned back out to the developers after we convert it here. + return Carbon::createFromFormat($this->getDateFormat(), $value); + } + + /** + * Prepare a date for array / JSON serialization. + * + * @param \DateTime $date + * @return string + */ + protected function serializeDate(DateTime $date) + { + return $date->format($this->getDateFormat()); + } + + /** + * Get the format for database stored dates. + * + * @return string + */ + protected function getDateFormat() + { + return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat(); + } + + /** + * Set the date format used by the model. + * + * @param string $format + * @return $this + */ + public function setDateFormat($format) + { + $this->dateFormat = $format; + + return $this; + } + + /** + * Encode the given value as JSON. + * + * @param mixed $value + * @return string + */ + protected function asJson($value) + { + return json_encode($value); + } + + /** + * Decode the given JSON back into an array or object. + * + * @param string $value + * @param bool $asObject + * @return mixed + */ + public function fromJson($value, $asObject = false) + { + return json_decode($value, ! $asObject); + } + + /** + * Clone the model into a new, non-existing instance. + * + * @param array $except + * @return \Illuminate\Database\Eloquent\Model + */ + public function replicate(array $except = null) + { + $except = $except ?: [ + $this->getKeyName(), + $this->getCreatedAtColumn(), + $this->getUpdatedAtColumn(), + ]; + + $attributes = array_except($this->attributes, $except); + + with($instance = new static)->setRawAttributes($attributes); + + return $instance->setRelations($this->relations); + } + + /** + * Get all of the current attributes on the model. + * + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * Set the array of model attributes. No checking is done. + * + * @param array $attributes + * @param bool $sync + * @return $this + */ + public function setRawAttributes(array $attributes, $sync = false) + { + $this->attributes = $attributes; + + if ($sync) { + $this->syncOriginal(); + } + + return $this; + } + + /** + * Get the model's original attribute values. + * + * @param string $key + * @param mixed $default + * @return array + */ + public function getOriginal($key = null, $default = null) + { + return Arr::get($this->original, $key, $default); + } + + /** + * Sync the original attributes with the current. + * + * @return $this + */ + public function syncOriginal() + { + $this->original = $this->attributes; + + return $this; + } + + /** + * Sync a single original attribute with its current value. + * + * @param string $attribute + * @return $this + */ + public function syncOriginalAttribute($attribute) + { + $this->original[$attribute] = $this->attributes[$attribute]; + + return $this; + } + + /** + * Determine if the model or given attribute(s) have been modified. + * + * @param array|string|null $attributes + * @return bool + */ + public function isDirty($attributes = null) + { + $dirty = $this->getDirty(); + + if (is_null($attributes)) { + return count($dirty) > 0; + } + + if (! is_array($attributes)) { + $attributes = func_get_args(); + } + + foreach ($attributes as $attribute) { + if (array_key_exists($attribute, $dirty)) { + return true; + } + } + + return false; + } + + /** + * Get the attributes that have been changed since last sync. + * + * @return array + */ + public function getDirty() + { + $dirty = []; + + foreach ($this->attributes as $key => $value) { + if (! array_key_exists($key, $this->original)) { + $dirty[$key] = $value; + } elseif ($value !== $this->original[$key] && + ! $this->originalIsNumericallyEquivalent($key)) { + $dirty[$key] = $value; + } + } + + return $dirty; + } + + /** + * Determine if the new and old values for a given key are numerically equivalent. + * + * @param string $key + * @return bool + */ + protected function originalIsNumericallyEquivalent($key) + { + $current = $this->attributes[$key]; + + $original = $this->original[$key]; + + return is_numeric($current) && is_numeric($original) && strcmp((string) $current, (string) $original) === 0; + } + + /** + * Get all the loaded relations for the instance. + * + * @return array + */ + public function getRelations() + { + return $this->relations; + } + + /** + * Get a specified relationship. + * + * @param string $relation + * @return mixed + */ + public function getRelation($relation) + { + return $this->relations[$relation]; + } + + /** + * Determine if the given relation is loaded. + * + * @param string $key + * @return bool + */ + public function relationLoaded($key) + { + return array_key_exists($key, $this->relations); + } + + /** + * Set the specific relationship in the model. + * + * @param string $relation + * @param mixed $value + * @return $this + */ + public function setRelation($relation, $value) + { + $this->relations[$relation] = $value; + + return $this; + } + + /** + * Set the entire relations array on the model. + * + * @param array $relations + * @return $this + */ + public function setRelations(array $relations) + { + $this->relations = $relations; + + return $this; + } + + /** + * Get the database connection for the model. + * + * @return \Illuminate\Database\Connection + */ + public function getConnection() + { + return static::resolveConnection($this->connection); + } + + /** + * Get the current connection name for the model. + * + * @return string + */ + public function getConnectionName() + { + return $this->connection; + } + + /** + * Set the connection associated with the model. + * + * @param string $name + * @return $this + */ + public function setConnection($name) + { + $this->connection = $name; + + return $this; + } + + /** + * Resolve a connection instance. + * + * @param string $connection + * @return \Illuminate\Database\Connection + */ + public static function resolveConnection($connection = null) + { + return static::$resolver->connection($connection); + } + + /** + * Get the connection resolver instance. + * + * @return \Illuminate\Database\ConnectionResolverInterface + */ + public static function getConnectionResolver() + { + return static::$resolver; + } + + /** + * Set the connection resolver instance. + * + * @param \Illuminate\Database\ConnectionResolverInterface $resolver + * @return void + */ + public static function setConnectionResolver(Resolver $resolver) + { + static::$resolver = $resolver; + } + + /** + * Unset the connection resolver for models. + * + * @return void + */ + public static function unsetConnectionResolver() + { + static::$resolver = null; + } + + /** + * Get the event dispatcher instance. + * + * @return \Illuminate\Contracts\Events\Dispatcher + */ + public static function getEventDispatcher() + { + return static::$dispatcher; + } + + /** + * Set the event dispatcher instance. + * + * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher + * @return void + */ + public static function setEventDispatcher(Dispatcher $dispatcher) + { + static::$dispatcher = $dispatcher; + } + + /** + * Unset the event dispatcher for models. + * + * @return void + */ + public static function unsetEventDispatcher() + { + static::$dispatcher = null; + } + + /** + * Get the mutated attributes for a given instance. + * + * @return array + */ + public function getMutatedAttributes() + { + $class = get_class($this); + + if (! isset(static::$mutatorCache[$class])) { + static::cacheMutatedAttributes($class); + } + + return static::$mutatorCache[$class]; + } + + /** + * Extract and cache all the mutated attributes of a class. + * + * @param string $class + * @return void + */ + public static function cacheMutatedAttributes($class) + { + $mutatedAttributes = []; + + // Here we will extract all of the mutated attributes so that we can quickly + // spin through them after we export models to their array form, which we + // need to be fast. This'll let us know the attributes that can mutate. + foreach (get_class_methods($class) as $method) { + if (strpos($method, 'Attribute') !== false && + preg_match('/^get(.+)Attribute$/', $method, $matches)) { + if (static::$snakeAttributes) { + $matches[1] = Str::snake($matches[1]); + } + + $mutatedAttributes[] = lcfirst($matches[1]); + } + } + + static::$mutatorCache[$class] = $mutatedAttributes; + } + + /** + * Dynamically retrieve attributes on the model. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + return $this->getAttribute($key); + } + + /** + * Dynamically set attributes on the model. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function __set($key, $value) + { + $this->setAttribute($key, $value); + } + + /** + * Determine if the given attribute exists. + * + * @param mixed $offset + * @return bool + */ + public function offsetExists($offset) + { + return isset($this->$offset); + } + + /** + * Get the value for a given offset. + * + * @param mixed $offset + * @return mixed + */ + public function offsetGet($offset) + { + return $this->$offset; + } + + /** + * Set the value for a given offset. + * + * @param mixed $offset + * @param mixed $value + * @return void + */ + public function offsetSet($offset, $value) + { + $this->$offset = $value; + } + + /** + * Unset the value for a given offset. + * + * @param mixed $offset + * @return void + */ + public function offsetUnset($offset) + { + unset($this->$offset); + } + + /** + * Determine if an attribute exists on the model. + * + * @param string $key + * @return bool + */ + public function __isset($key) + { + return (isset($this->attributes[$key]) || isset($this->relations[$key])) || + ($this->hasGetMutator($key) && ! is_null($this->getAttributeValue($key))); + } + + /** + * Unset an attribute on the model. + * + * @param string $key + * @return void + */ + public function __unset($key) + { + unset($this->attributes[$key], $this->relations[$key]); + } + + /** + * Handle dynamic method calls into the model. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if (in_array($method, ['increment', 'decrement'])) { + return call_user_func_array([$this, $method], $parameters); + } + + $query = $this->newQuery(); + + return call_user_func_array([$query, $method], $parameters); + } + + /** + * Handle dynamic static method calls into the method. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public static function __callStatic($method, $parameters) + { + $instance = new static; + + return call_user_func_array([$instance, $method], $parameters); + } + + /** + * Convert the model to its string representation. + * + * @return string + */ + public function __toString() + { + return $this->toJson(); + } + + /** + * When a model is being unserialized, check if it needs to be booted. + * + * @return void + */ + public function __wakeup() + { + $this->bootIfNotBooted(); + } +} diff --git a/vendor/illuminate/database/Eloquent/ModelNotFoundException.php b/vendor/illuminate/database/Eloquent/ModelNotFoundException.php new file mode 100755 index 0000000..102683a --- /dev/null +++ b/vendor/illuminate/database/Eloquent/ModelNotFoundException.php @@ -0,0 +1,40 @@ +model = $model; + + $this->message = "No query results for model [{$model}]."; + + return $this; + } + + /** + * Get the affected Eloquent model. + * + * @return string + */ + public function getModel() + { + return $this->model; + } +} diff --git a/vendor/illuminate/database/Eloquent/QueueEntityResolver.php b/vendor/illuminate/database/Eloquent/QueueEntityResolver.php new file mode 100644 index 0000000..0e630c7 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/QueueEntityResolver.php @@ -0,0 +1,27 @@ +find($id); + + if ($instance) { + return $instance; + } + + throw new EntityNotFoundException($type, $id); + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php b/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php new file mode 100755 index 0000000..5fa26a4 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php @@ -0,0 +1,306 @@ +otherKey = $otherKey; + $this->relation = $relation; + $this->foreignKey = $foreignKey; + + parent::__construct($query, $parent); + } + + /** + * Get the results of the relationship. + * + * @return mixed + */ + public function getResults() + { + return $this->query->first(); + } + + /** + * Set the base constraints on the relation query. + * + * @return void + */ + public function addConstraints() + { + if (static::$constraints) { + // For belongs to relationships, which are essentially the inverse of has one + // or has many relationships, we need to actually query on the primary key + // of the related models matching on the foreign key that's on a parent. + $table = $this->related->getTable(); + + $this->query->where($table.'.'.$this->otherKey, '=', $this->parent->{$this->foreignKey}); + } + } + + /** + * Add the constraints for a relationship count query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQuery(Builder $query, Builder $parent) + { + if ($parent->getQuery()->from == $query->getQuery()->from) { + return $this->getRelationCountQueryForSelfRelation($query, $parent); + } + + $query->select(new Expression('count(*)')); + + $otherKey = $this->wrap($query->getModel()->getTable().'.'.$this->otherKey); + + return $query->where($this->getQualifiedForeignKey(), '=', new Expression($otherKey)); + } + + /** + * Add the constraints for a relationship count query on the same table. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQueryForSelfRelation(Builder $query, Builder $parent) + { + $query->select(new Expression('count(*)')); + + $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash()); + + $key = $this->wrap($this->getQualifiedForeignKey()); + + return $query->where($hash.'.'.$query->getModel()->getKeyName(), '=', new Expression($key)); + } + + /** + * Get a relationship join table hash. + * + * @return string + */ + public function getRelationCountHash() + { + return 'self_'.md5(microtime(true)); + } + + /** + * Set the constraints for an eager load of the relation. + * + * @param array $models + * @return void + */ + public function addEagerConstraints(array $models) + { + // We'll grab the primary key name of the related models since it could be set to + // a non-standard name and not "id". We will then construct the constraint for + // our eagerly loading query so it returns the proper models from execution. + $key = $this->related->getTable().'.'.$this->otherKey; + + $this->query->whereIn($key, $this->getEagerModelKeys($models)); + } + + /** + * Gather the keys from an array of related models. + * + * @param array $models + * @return array + */ + protected function getEagerModelKeys(array $models) + { + $keys = []; + + // First we need to gather all of the keys from the parent models so we know what + // to query for via the eager loading query. We will add them to an array then + // execute a "where in" statement to gather up all of those related records. + foreach ($models as $model) { + if (! is_null($value = $model->{$this->foreignKey})) { + $keys[] = $value; + } + } + + // If there are no keys that were not null we will just return an array with 0 in + // it so the query doesn't fail, but will not return any results, which should + // be what this developer is expecting in a case where this happens to them. + if (count($keys) == 0) { + return [0]; + } + + return array_values(array_unique($keys)); + } + + /** + * Initialize the relation on a set of models. + * + * @param array $models + * @param string $relation + * @return array + */ + public function initRelation(array $models, $relation) + { + foreach ($models as $model) { + $model->setRelation($relation, null); + } + + return $models; + } + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function match(array $models, Collection $results, $relation) + { + $foreign = $this->foreignKey; + + $other = $this->otherKey; + + // First we will get to build a dictionary of the child models by their primary + // key of the relationship, then we can easily match the children back onto + // the parents using that dictionary and the primary key of the children. + $dictionary = []; + + foreach ($results as $result) { + $dictionary[$result->getAttribute($other)] = $result; + } + + // Once we have the dictionary constructed, we can loop through all the parents + // and match back onto their children using these keys of the dictionary and + // the primary key of the children to map them onto the correct instances. + foreach ($models as $model) { + if (isset($dictionary[$model->$foreign])) { + $model->setRelation($relation, $dictionary[$model->$foreign]); + } + } + + return $models; + } + + /** + * Associate the model instance to the given parent. + * + * @param \Illuminate\Database\Eloquent\Model|int $model + * @return \Illuminate\Database\Eloquent\Model + */ + public function associate($model) + { + $otherKey = ($model instanceof Model ? $model->getAttribute($this->otherKey) : $model); + + $this->parent->setAttribute($this->foreignKey, $otherKey); + + if ($model instanceof Model) { + $this->parent->setRelation($this->relation, $model); + } + + return $this->parent; + } + + /** + * Dissociate previously associated model from the given parent. + * + * @return \Illuminate\Database\Eloquent\Model + */ + public function dissociate() + { + $this->parent->setAttribute($this->foreignKey, null); + + return $this->parent->setRelation($this->relation, null); + } + + /** + * Update the parent model on the relationship. + * + * @param array $attributes + * @return mixed + */ + public function update(array $attributes) + { + $instance = $this->getResults(); + + return $instance->fill($attributes)->save(); + } + + /** + * Get the foreign key of the relationship. + * + * @return string + */ + public function getForeignKey() + { + return $this->foreignKey; + } + + /** + * Get the fully qualified foreign key of the relationship. + * + * @return string + */ + public function getQualifiedForeignKey() + { + return $this->parent->getTable().'.'.$this->foreignKey; + } + + /** + * Get the associated key of the relationship. + * + * @return string + */ + public function getOtherKey() + { + return $this->otherKey; + } + + /** + * Get the fully qualified associated key of the relationship. + * + * @return string + */ + public function getQualifiedOtherKeyName() + { + return $this->related->getTable().'.'.$this->otherKey; + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php b/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php new file mode 100755 index 0000000..0272c4d --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php @@ -0,0 +1,1251 @@ +table = $table; + $this->otherKey = $otherKey; + $this->foreignKey = $foreignKey; + $this->relationName = $relationName; + + parent::__construct($query, $parent); + } + + /** + * Get the results of the relationship. + * + * @return mixed + */ + public function getResults() + { + return $this->get(); + } + + /** + * Set a where clause for a pivot table column. + * + * @param string $column + * @param string $operator + * @param mixed $value + * @param string $boolean + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function wherePivot($column, $operator = null, $value = null, $boolean = 'and') + { + $this->pivotWheres[] = func_get_args(); + + return $this->where($this->table.'.'.$column, $operator, $value, $boolean); + } + + /** + * Set an or where clause for a pivot table column. + * + * @param string $column + * @param string $operator + * @param mixed $value + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function orWherePivot($column, $operator = null, $value = null) + { + return $this->wherePivot($column, $operator, $value, 'or'); + } + + /** + * Execute the query and get the first result. + * + * @param array $columns + * @return mixed + */ + public function first($columns = ['*']) + { + $results = $this->take(1)->get($columns); + + return count($results) > 0 ? $results->first() : null; + } + + /** + * Execute the query and get the first result or throw an exception. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|static + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function firstOrFail($columns = ['*']) + { + if (! is_null($model = $this->first($columns))) { + return $model; + } + + throw new ModelNotFoundException; + } + + /** + * Execute the query as a "select" statement. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection + */ + public function get($columns = ['*']) + { + // First we'll add the proper select columns onto the query so it is run with + // the proper columns. Then, we will get the results and hydrate out pivot + // models with the result of those columns as a separate model relation. + $columns = $this->query->getQuery()->columns ? [] : $columns; + + $select = $this->getSelectColumns($columns); + + $models = $this->query->addSelect($select)->getModels(); + + $this->hydratePivotRelation($models); + + // If we actually found models we will also eager load any relationships that + // have been specified as needing to be eager loaded. This will solve the + // n + 1 query problem for the developer and also increase performance. + if (count($models) > 0) { + $models = $this->query->eagerLoadRelations($models); + } + + return $this->related->newCollection($models); + } + + /** + * Get a paginator for the "select" statement. + * + * @param int $perPage + * @param array $columns + * @param string $pageName + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + */ + public function paginate($perPage = null, $columns = ['*'], $pageName = 'page') + { + $this->query->addSelect($this->getSelectColumns($columns)); + + $paginator = $this->query->paginate($perPage, $columns, $pageName); + + $this->hydratePivotRelation($paginator->items()); + + return $paginator; + } + + /** + * Paginate the given query into a simple paginator. + * + * @param int $perPage + * @param array $columns + * @return \Illuminate\Contracts\Pagination\Paginator + */ + public function simplePaginate($perPage = null, $columns = ['*']) + { + $this->query->addSelect($this->getSelectColumns($columns)); + + $paginator = $this->query->simplePaginate($perPage, $columns); + + $this->hydratePivotRelation($paginator->items()); + + return $paginator; + } + + /** + * Chunk the results of the query. + * + * @param int $count + * @param callable $callback + * @return void + */ + public function chunk($count, callable $callback) + { + $this->query->addSelect($this->getSelectColumns()); + + $this->query->chunk($count, function ($results) use ($callback) { + $this->hydratePivotRelation($results->all()); + + call_user_func($callback, $results); + }); + } + + /** + * Hydrate the pivot table relationship on the models. + * + * @param array $models + * @return void + */ + protected function hydratePivotRelation(array $models) + { + // To hydrate the pivot relationship, we will just gather the pivot attributes + // and create a new Pivot model, which is basically a dynamic model that we + // will set the attributes, table, and connections on so it they be used. + foreach ($models as $model) { + $pivot = $this->newExistingPivot($this->cleanPivotAttributes($model)); + + $model->setRelation('pivot', $pivot); + } + } + + /** + * Get the pivot attributes from a model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return array + */ + protected function cleanPivotAttributes(Model $model) + { + $values = []; + + foreach ($model->getAttributes() as $key => $value) { + // To get the pivots attributes we will just take any of the attributes which + // begin with "pivot_" and add those to this arrays, as well as unsetting + // them from the parent's models since they exist in a different table. + if (strpos($key, 'pivot_') === 0) { + $values[substr($key, 6)] = $value; + + unset($model->$key); + } + } + + return $values; + } + + /** + * Set the base constraints on the relation query. + * + * @return void + */ + public function addConstraints() + { + $this->setJoin(); + + if (static::$constraints) { + $this->setWhere(); + } + } + + /** + * Add the constraints for a relationship count query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQuery(Builder $query, Builder $parent) + { + if ($parent->getQuery()->from == $query->getQuery()->from) { + return $this->getRelationCountQueryForSelfJoin($query, $parent); + } + + $this->setJoin($query); + + return parent::getRelationCountQuery($query, $parent); + } + + /** + * Add the constraints for a relationship count query on the same table. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQueryForSelfJoin(Builder $query, Builder $parent) + { + $query->select(new Expression('count(*)')); + + $query->from($this->table.' as '.$hash = $this->getRelationCountHash()); + + $key = $this->wrap($this->getQualifiedParentKeyName()); + + return $query->where($hash.'.'.$this->foreignKey, '=', new Expression($key)); + } + + /** + * Get a relationship join table hash. + * + * @return string + */ + public function getRelationCountHash() + { + return 'self_'.md5(microtime(true)); + } + + /** + * Set the select clause for the relation query. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + protected function getSelectColumns(array $columns = ['*']) + { + if ($columns == ['*']) { + $columns = [$this->related->getTable().'.*']; + } + + return array_merge($columns, $this->getAliasedPivotColumns()); + } + + /** + * Get the pivot columns for the relation. + * + * @return array + */ + protected function getAliasedPivotColumns() + { + $defaults = [$this->foreignKey, $this->otherKey]; + + // We need to alias all of the pivot columns with the "pivot_" prefix so we + // can easily extract them out of the models and put them into the pivot + // relationships when they are retrieved and hydrated into the models. + $columns = []; + + foreach (array_merge($defaults, $this->pivotColumns) as $column) { + $columns[] = $this->table.'.'.$column.' as pivot_'.$column; + } + + return array_unique($columns); + } + + /** + * Determine whether the given column is defined as a pivot column. + * + * @param string $column + * @return bool + */ + protected function hasPivotColumn($column) + { + return in_array($column, $this->pivotColumns); + } + + /** + * Set the join clause for the relation query. + * + * @param \Illuminate\Database\Eloquent\Builder|null $query + * @return $this + */ + protected function setJoin($query = null) + { + $query = $query ?: $this->query; + + // We need to join to the intermediate table on the related model's primary + // key column with the intermediate table's foreign key for the related + // model instance. Then we can set the "where" for the parent models. + $baseTable = $this->related->getTable(); + + $key = $baseTable.'.'.$this->related->getKeyName(); + + $query->join($this->table, $key, '=', $this->getOtherKey()); + + return $this; + } + + /** + * Set the where clause for the relation query. + * + * @return $this + */ + protected function setWhere() + { + $foreign = $this->getForeignKey(); + + $this->query->where($foreign, '=', $this->parent->getKey()); + + return $this; + } + + /** + * Set the constraints for an eager load of the relation. + * + * @param array $models + * @return void + */ + public function addEagerConstraints(array $models) + { + $this->query->whereIn($this->getForeignKey(), $this->getKeys($models)); + } + + /** + * Initialize the relation on a set of models. + * + * @param array $models + * @param string $relation + * @return array + */ + public function initRelation(array $models, $relation) + { + foreach ($models as $model) { + $model->setRelation($relation, $this->related->newCollection()); + } + + return $models; + } + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function match(array $models, Collection $results, $relation) + { + $dictionary = $this->buildDictionary($results); + + // Once we have an array dictionary of child objects we can easily match the + // children back to their parent using the dictionary and the keys on the + // the parent models. Then we will return the hydrated models back out. + foreach ($models as $model) { + if (isset($dictionary[$key = $model->getKey()])) { + $collection = $this->related->newCollection($dictionary[$key]); + + $model->setRelation($relation, $collection); + } + } + + return $models; + } + + /** + * Build model dictionary keyed by the relation's foreign key. + * + * @param \Illuminate\Database\Eloquent\Collection $results + * @return array + */ + protected function buildDictionary(Collection $results) + { + $foreign = $this->foreignKey; + + // First we will build a dictionary of child models keyed by the foreign key + // of the relation so that we will easily and quickly match them to their + // parents without having a possibly slow inner loops for every models. + $dictionary = []; + + foreach ($results as $result) { + $dictionary[$result->pivot->$foreign][] = $result; + } + + return $dictionary; + } + + /** + * Touch all of the related models for the relationship. + * + * E.g.: Touch all roles associated with this user. + * + * @return void + */ + public function touch() + { + $key = $this->getRelated()->getKeyName(); + + $columns = $this->getRelatedFreshUpdate(); + + // If we actually have IDs for the relation, we will run the query to update all + // the related model's timestamps, to make sure these all reflect the changes + // to the parent models. This will help us keep any caching synced up here. + $ids = $this->getRelatedIds(); + + if (count($ids) > 0) { + $this->getRelated()->newQuery()->whereIn($key, $ids)->update($columns); + } + } + + /** + * Get all of the IDs for the related models. + * + * @return \Illuminate\Support\Collection + */ + public function getRelatedIds() + { + $related = $this->getRelated(); + + $fullKey = $related->getQualifiedKeyName(); + + return $this->getQuery()->select($fullKey)->lists($related->getKeyName()); + } + + /** + * Save a new model and attach it to the parent model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @param array $joining + * @param bool $touch + * @return \Illuminate\Database\Eloquent\Model + */ + public function save(Model $model, array $joining = [], $touch = true) + { + $model->save(['touch' => false]); + + $this->attach($model->getKey(), $joining, $touch); + + return $model; + } + + /** + * Save an array of new models and attach them to the parent model. + * + * @param array $models + * @param array $joinings + * @return array + */ + public function saveMany(array $models, array $joinings = []) + { + foreach ($models as $key => $model) { + $this->save($model, (array) Arr::get($joinings, $key), false); + } + + $this->touchIfTouching(); + + return $models; + } + + /** + * Find a related model by its primary key. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null + */ + public function find($id, $columns = ['*']) + { + if (is_array($id)) { + return $this->findMany($id, $columns); + } + + $this->where($this->getRelated()->getQualifiedKeyName(), '=', $id); + + return $this->first($columns); + } + + /** + * Find multiple related models by their primary keys. + * + * @param mixed $ids + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection + */ + public function findMany($ids, $columns = ['*']) + { + if (empty($ids)) { + return $this->getRelated()->newCollection(); + } + + $this->whereIn($this->getRelated()->getQualifiedKeyName(), $ids); + + return $this->get($columns); + } + + /** + * Find a related model by its primary key or throw an exception. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function findOrFail($id, $columns = ['*']) + { + $result = $this->find($id, $columns); + + if (is_array($id)) { + if (count($result) == count(array_unique($id))) { + return $result; + } + } elseif (! is_null($result)) { + return $result; + } + + throw (new ModelNotFoundException)->setModel(get_class($this->parent)); + } + + /** + * Find a related model by its primary key or return new instance of the related model. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model + */ + public function findOrNew($id, $columns = ['*']) + { + if (is_null($instance = $this->find($id, $columns))) { + $instance = $this->getRelated()->newInstance(); + } + + return $instance; + } + + /** + * Get the first related model record matching the attributes or instantiate it. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function firstOrNew(array $attributes) + { + if (is_null($instance = $this->where($attributes)->first())) { + $instance = $this->related->newInstance($attributes); + } + + return $instance; + } + + /** + * Get the first related record matching the attributes or create it. + * + * @param array $attributes + * @param array $joining + * @param bool $touch + * @return \Illuminate\Database\Eloquent\Model + */ + public function firstOrCreate(array $attributes, array $joining = [], $touch = true) + { + if (is_null($instance = $this->where($attributes)->first())) { + $instance = $this->create($attributes, $joining, $touch); + } + + return $instance; + } + + /** + * Create or update a related record matching the attributes, and fill it with values. + * + * @param array $attributes + * @param array $values + * @param array $joining + * @param bool $touch + * @return \Illuminate\Database\Eloquent\Model + */ + public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true) + { + if (is_null($instance = $this->where($attributes)->first())) { + return $this->create($values, $joining, $touch); + } + + $instance->fill($values); + + $instance->save(['touch' => false]); + + return $instance; + } + + /** + * Create a new instance of the related model. + * + * @param array $attributes + * @param array $joining + * @param bool $touch + * @return \Illuminate\Database\Eloquent\Model + */ + public function create(array $attributes, array $joining = [], $touch = true) + { + $instance = $this->related->newInstance($attributes); + + // Once we save the related model, we need to attach it to the base model via + // through intermediate table so we'll use the existing "attach" method to + // accomplish this which will insert the record and any more attributes. + $instance->save(['touch' => false]); + + $this->attach($instance->getKey(), $joining, $touch); + + return $instance; + } + + /** + * Create an array of new instances of the related models. + * + * @param array $records + * @param array $joinings + * @return array + */ + public function createMany(array $records, array $joinings = []) + { + $instances = []; + + foreach ($records as $key => $record) { + $instances[] = $this->create($record, (array) Arr::get($joinings, $key), false); + } + + $this->touchIfTouching(); + + return $instances; + } + + /** + * Sync the intermediate tables with a list of IDs or collection of models. + * + * @param \Illuminate\Database\Eloquent\Collection|array $ids + * @param bool $detaching + * @return array + */ + public function sync($ids, $detaching = true) + { + $changes = [ + 'attached' => [], 'detached' => [], 'updated' => [], + ]; + + if ($ids instanceof Collection) { + $ids = $ids->modelKeys(); + } + + // First we need to attach any of the associated models that are not currently + // in this joining table. We'll spin through the given IDs, checking to see + // if they exist in the array of current ones, and if not we will insert. + $current = $this->newPivotQuery()->lists($this->otherKey); + + $records = $this->formatSyncList($ids); + + $detach = array_diff($current, array_keys($records)); + + // Next, we will take the differences of the currents and given IDs and detach + // all of the entities that exist in the "current" array but are not in the + // the array of the IDs given to the method which will complete the sync. + if ($detaching && count($detach) > 0) { + $this->detach($detach); + + $changes['detached'] = (array) array_map(function ($v) { + return is_numeric($v) ? (int) $v : (string) $v; + }, $detach); + } + + // Now we are finally ready to attach the new records. Note that we'll disable + // touching until after the entire operation is complete so we don't fire a + // ton of touch operations until we are totally done syncing the records. + $changes = array_merge( + $changes, $this->attachNew($records, $current, false) + ); + + if (count($changes['attached']) || count($changes['updated'])) { + $this->touchIfTouching(); + } + + return $changes; + } + + /** + * Format the sync list so that it is keyed by ID. + * + * @param array $records + * @return array + */ + protected function formatSyncList(array $records) + { + $results = []; + + foreach ($records as $id => $attributes) { + if (! is_array($attributes)) { + list($id, $attributes) = [$attributes, []]; + } + + $results[$id] = $attributes; + } + + return $results; + } + + /** + * Attach all of the IDs that aren't in the current array. + * + * @param array $records + * @param array $current + * @param bool $touch + * @return array + */ + protected function attachNew(array $records, array $current, $touch = true) + { + $changes = ['attached' => [], 'updated' => []]; + + foreach ($records as $id => $attributes) { + // If the ID is not in the list of existing pivot IDs, we will insert a new pivot + // record, otherwise, we will just update this existing record on this joining + // table, so that the developers will easily update these records pain free. + if (! in_array($id, $current)) { + $this->attach($id, $attributes, $touch); + + $changes['attached'][] = is_numeric($id) ? (int) $id : (string) $id; + } + + // Now we'll try to update an existing pivot record with the attributes that were + // given to the method. If the model is actually updated we will add it to the + // list of updated pivot records so we return them back out to the consumer. + elseif (count($attributes) > 0 && + $this->updateExistingPivot($id, $attributes, $touch)) { + $changes['updated'][] = is_numeric($id) ? (int) $id : (string) $id; + } + } + + return $changes; + } + + /** + * Update an existing pivot record on the table. + * + * @param mixed $id + * @param array $attributes + * @param bool $touch + * @return int + */ + public function updateExistingPivot($id, array $attributes, $touch = true) + { + if (in_array($this->updatedAt(), $this->pivotColumns)) { + $attributes = $this->setTimestampsOnAttach($attributes, true); + } + + $updated = $this->newPivotStatementForId($id)->update($attributes); + + if ($touch) { + $this->touchIfTouching(); + } + + return $updated; + } + + /** + * Attach a model to the parent. + * + * @param mixed $id + * @param array $attributes + * @param bool $touch + * @return void + */ + public function attach($id, array $attributes = [], $touch = true) + { + if ($id instanceof Model) { + $id = $id->getKey(); + } + + $query = $this->newPivotStatement(); + + $query->insert($this->createAttachRecords((array) $id, $attributes)); + + if ($touch) { + $this->touchIfTouching(); + } + } + + /** + * Create an array of records to insert into the pivot table. + * + * @param array $ids + * @param array $attributes + * @return array + */ + protected function createAttachRecords($ids, array $attributes) + { + $records = []; + + $timed = ($this->hasPivotColumn($this->createdAt()) || + $this->hasPivotColumn($this->updatedAt())); + + // To create the attachment records, we will simply spin through the IDs given + // and create a new record to insert for each ID. Each ID may actually be a + // key in the array, with extra attributes to be placed in other columns. + foreach ($ids as $key => $value) { + $records[] = $this->attacher($key, $value, $attributes, $timed); + } + + return $records; + } + + /** + * Create a full attachment record payload. + * + * @param int $key + * @param mixed $value + * @param array $attributes + * @param bool $timed + * @return array + */ + protected function attacher($key, $value, $attributes, $timed) + { + list($id, $extra) = $this->getAttachId($key, $value, $attributes); + + // To create the attachment records, we will simply spin through the IDs given + // and create a new record to insert for each ID. Each ID may actually be a + // key in the array, with extra attributes to be placed in other columns. + $record = $this->createAttachRecord($id, $timed); + + return array_merge($record, $extra); + } + + /** + * Get the attach record ID and extra attributes. + * + * @param mixed $key + * @param mixed $value + * @param array $attributes + * @return array + */ + protected function getAttachId($key, $value, array $attributes) + { + if (is_array($value)) { + return [$key, array_merge($value, $attributes)]; + } + + return [$value, $attributes]; + } + + /** + * Create a new pivot attachment record. + * + * @param int $id + * @param bool $timed + * @return array + */ + protected function createAttachRecord($id, $timed) + { + $record[$this->foreignKey] = $this->parent->getKey(); + + $record[$this->otherKey] = $id; + + // If the record needs to have creation and update timestamps, we will make + // them by calling the parent model's "freshTimestamp" method which will + // provide us with a fresh timestamp in this model's preferred format. + if ($timed) { + $record = $this->setTimestampsOnAttach($record); + } + + return $record; + } + + /** + * Set the creation and update timestamps on an attach record. + * + * @param array $record + * @param bool $exists + * @return array + */ + protected function setTimestampsOnAttach(array $record, $exists = false) + { + $fresh = $this->parent->freshTimestamp(); + + if (! $exists && $this->hasPivotColumn($this->createdAt())) { + $record[$this->createdAt()] = $fresh; + } + + if ($this->hasPivotColumn($this->updatedAt())) { + $record[$this->updatedAt()] = $fresh; + } + + return $record; + } + + /** + * Detach models from the relationship. + * + * @param int|array $ids + * @param bool $touch + * @return int + */ + public function detach($ids = [], $touch = true) + { + if ($ids instanceof Model) { + $ids = (array) $ids->getKey(); + } + + $query = $this->newPivotQuery(); + + // If associated IDs were passed to the method we will only delete those + // associations, otherwise all of the association ties will be broken. + // We'll return the numbers of affected rows when we do the deletes. + $ids = (array) $ids; + + if (count($ids) > 0) { + $query->whereIn($this->otherKey, (array) $ids); + } + + // Once we have all of the conditions set on the statement, we are ready + // to run the delete on the pivot table. Then, if the touch parameter + // is true, we will go ahead and touch all related models to sync. + $results = $query->delete(); + + if ($touch) { + $this->touchIfTouching(); + } + + return $results; + } + + /** + * If we're touching the parent model, touch. + * + * @return void + */ + public function touchIfTouching() + { + if ($this->touchingParent()) { + $this->getParent()->touch(); + } + + if ($this->getParent()->touches($this->relationName)) { + $this->touch(); + } + } + + /** + * Determine if we should touch the parent on sync. + * + * @return bool + */ + protected function touchingParent() + { + return $this->getRelated()->touches($this->guessInverseRelation()); + } + + /** + * Attempt to guess the name of the inverse of the relation. + * + * @return string + */ + protected function guessInverseRelation() + { + return Str::camel(Str::plural(class_basename($this->getParent()))); + } + + /** + * Create a new query builder for the pivot table. + * + * @return \Illuminate\Database\Query\Builder + */ + protected function newPivotQuery() + { + $query = $this->newPivotStatement(); + + foreach ($this->pivotWheres as $whereArgs) { + call_user_func_array([$query, 'where'], $whereArgs); + } + + return $query->where($this->foreignKey, $this->parent->getKey()); + } + + /** + * Get a new plain query builder for the pivot table. + * + * @return \Illuminate\Database\Query\Builder + */ + public function newPivotStatement() + { + return $this->query->getQuery()->newQuery()->from($this->table); + } + + /** + * Get a new pivot statement for a given "other" ID. + * + * @param mixed $id + * @return \Illuminate\Database\Query\Builder + */ + public function newPivotStatementForId($id) + { + return $this->newPivotQuery()->where($this->otherKey, $id); + } + + /** + * Create a new pivot model instance. + * + * @param array $attributes + * @param bool $exists + * @return \Illuminate\Database\Eloquent\Relations\Pivot + */ + public function newPivot(array $attributes = [], $exists = false) + { + $pivot = $this->related->newPivot($this->parent, $attributes, $this->table, $exists); + + return $pivot->setPivotKeys($this->foreignKey, $this->otherKey); + } + + /** + * Create a new existing pivot model instance. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Relations\Pivot + */ + public function newExistingPivot(array $attributes = []) + { + return $this->newPivot($attributes, true); + } + + /** + * Set the columns on the pivot table to retrieve. + * + * @param array|mixed $columns + * @return $this + */ + public function withPivot($columns) + { + $columns = is_array($columns) ? $columns : func_get_args(); + + $this->pivotColumns = array_merge($this->pivotColumns, $columns); + + return $this; + } + + /** + * Specify that the pivot table has creation and update timestamps. + * + * @param mixed $createdAt + * @param mixed $updatedAt + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function withTimestamps($createdAt = null, $updatedAt = null) + { + $this->pivotCreatedAt = $createdAt; + $this->pivotUpdatedAt = $updatedAt; + + return $this->withPivot($this->createdAt(), $this->updatedAt()); + } + + /** + * Get the name of the "created at" column. + * + * @return string + */ + public function createdAt() + { + return $this->pivotCreatedAt ?: $this->parent->getCreatedAtColumn(); + } + + /** + * Get the name of the "updated at" column. + * + * @return string + */ + public function updatedAt() + { + return $this->pivotUpdatedAt ?: $this->parent->getUpdatedAtColumn(); + } + + /** + * Get the related model's updated at column name. + * + * @return string + */ + public function getRelatedFreshUpdate() + { + return [$this->related->getUpdatedAtColumn() => $this->related->freshTimestamp()]; + } + + /** + * Get the key for comparing against the parent key in "has" query. + * + * @return string + */ + public function getHasCompareKey() + { + return $this->getForeignKey(); + } + + /** + * Get the fully qualified foreign key for the relation. + * + * @return string + */ + public function getForeignKey() + { + return $this->table.'.'.$this->foreignKey; + } + + /** + * Get the fully qualified "other key" for the relation. + * + * @return string + */ + public function getOtherKey() + { + return $this->table.'.'.$this->otherKey; + } + + /** + * Get the intermediate table for the relationship. + * + * @return string + */ + public function getTable() + { + return $this->table; + } + + /** + * Get the relationship name for the relationship. + * + * @return string + */ + public function getRelationName() + { + return $this->relationName; + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/HasMany.php b/vendor/illuminate/database/Eloquent/Relations/HasMany.php new file mode 100755 index 0000000..6149e47 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/HasMany.php @@ -0,0 +1,47 @@ +query->get(); + } + + /** + * Initialize the relation on a set of models. + * + * @param array $models + * @param string $relation + * @return array + */ + public function initRelation(array $models, $relation) + { + foreach ($models as $model) { + $model->setRelation($relation, $this->related->newCollection()); + } + + return $models; + } + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function match(array $models, Collection $results, $relation) + { + return $this->matchMany($models, $results, $relation); + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php b/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php new file mode 100644 index 0000000..94cff1b --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php @@ -0,0 +1,408 @@ +localKey = $localKey; + $this->firstKey = $firstKey; + $this->secondKey = $secondKey; + $this->farParent = $farParent; + + parent::__construct($query, $parent); + } + + /** + * Set the base constraints on the relation query. + * + * @return void + */ + public function addConstraints() + { + $parentTable = $this->parent->getTable(); + + $localValue = $this->farParent[$this->localKey]; + + $this->setJoin(); + + if (static::$constraints) { + $this->query->where($parentTable.'.'.$this->firstKey, '=', $localValue); + } + } + + /** + * Add the constraints for a relationship count query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQuery(Builder $query, Builder $parent) + { + $parentTable = $this->parent->getTable(); + + $this->setJoin($query); + + $query->select(new Expression('count(*)')); + + $key = $this->wrap($parentTable.'.'.$this->firstKey); + + return $query->where($this->getHasCompareKey(), '=', new Expression($key)); + } + + /** + * Set the join clause on the query. + * + * @param \Illuminate\Database\Eloquent\Builder|null $query + * @return void + */ + protected function setJoin(Builder $query = null) + { + $query = $query ?: $this->query; + + $foreignKey = $this->related->getTable().'.'.$this->secondKey; + + $query->join($this->parent->getTable(), $this->getQualifiedParentKeyName(), '=', $foreignKey); + + if ($this->parentSoftDeletes()) { + $query->whereNull($this->parent->getQualifiedDeletedAtColumn()); + } + } + + /** + * Determine whether close parent of the relation uses Soft Deletes. + * + * @return bool + */ + public function parentSoftDeletes() + { + return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses_recursive(get_class($this->parent))); + } + + /** + * Set the constraints for an eager load of the relation. + * + * @param array $models + * @return void + */ + public function addEagerConstraints(array $models) + { + $table = $this->parent->getTable(); + + $this->query->whereIn($table.'.'.$this->firstKey, $this->getKeys($models)); + } + + /** + * Initialize the relation on a set of models. + * + * @param array $models + * @param string $relation + * @return array + */ + public function initRelation(array $models, $relation) + { + foreach ($models as $model) { + $model->setRelation($relation, $this->related->newCollection()); + } + + return $models; + } + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function match(array $models, Collection $results, $relation) + { + $dictionary = $this->buildDictionary($results); + + // Once we have the dictionary we can simply spin through the parent models to + // link them up with their children using the keyed dictionary to make the + // matching very convenient and easy work. Then we'll just return them. + foreach ($models as $model) { + $key = $model->getKey(); + + if (isset($dictionary[$key])) { + $value = $this->related->newCollection($dictionary[$key]); + + $model->setRelation($relation, $value); + } + } + + return $models; + } + + /** + * Build model dictionary keyed by the relation's foreign key. + * + * @param \Illuminate\Database\Eloquent\Collection $results + * @return array + */ + protected function buildDictionary(Collection $results) + { + $dictionary = []; + + $foreign = $this->firstKey; + + // First we will create a dictionary of models keyed by the foreign key of the + // relationship as this will allow us to quickly access all of the related + // models without having to do nested looping which will be quite slow. + foreach ($results as $result) { + $dictionary[$result->{$foreign}][] = $result; + } + + return $dictionary; + } + + /** + * Get the results of the relationship. + * + * @return mixed + */ + public function getResults() + { + return $this->get(); + } + + /** + * Execute the query and get the first related model. + * + * @param array $columns + * @return mixed + */ + public function first($columns = ['*']) + { + $results = $this->take(1)->get($columns); + + return count($results) > 0 ? $results->first() : null; + } + + /** + * Execute the query and get the first result or throw an exception. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|static + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function firstOrFail($columns = ['*']) + { + if (! is_null($model = $this->first($columns))) { + return $model; + } + + throw new ModelNotFoundException; + } + + /** + * Find a related model by its primary key. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null + */ + public function find($id, $columns = ['*']) + { + if (is_array($id)) { + return $this->findMany($id, $columns); + } + + $this->where($this->getRelated()->getQualifiedKeyName(), '=', $id); + + return $this->first($columns); + } + + /** + * Find multiple related models by their primary keys. + * + * @param mixed $ids + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection + */ + public function findMany($ids, $columns = ['*']) + { + if (empty($ids)) { + return $this->getRelated()->newCollection(); + } + + $this->whereIn($this->getRelated()->getQualifiedKeyName(), $ids); + + return $this->get($columns); + } + + /** + * Find a related model by its primary key or throw an exception. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function findOrFail($id, $columns = ['*']) + { + $result = $this->find($id, $columns); + + if (is_array($id)) { + if (count($result) == count(array_unique($id))) { + return $result; + } + } elseif (! is_null($result)) { + return $result; + } + + throw (new ModelNotFoundException)->setModel(get_class($this->parent)); + } + + /** + * Execute the query as a "select" statement. + * + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection + */ + public function get($columns = ['*']) + { + // First we'll add the proper select columns onto the query so it is run with + // the proper columns. Then, we will get the results and hydrate out pivot + // models with the result of those columns as a separate model relation. + $columns = $this->query->getQuery()->columns ? [] : $columns; + + $select = $this->getSelectColumns($columns); + + $models = $this->query->addSelect($select)->getModels(); + + // If we actually found models we will also eager load any relationships that + // have been specified as needing to be eager loaded. This will solve the + // n + 1 query problem for the developer and also increase performance. + if (count($models) > 0) { + $models = $this->query->eagerLoadRelations($models); + } + + return $this->related->newCollection($models); + } + + /** + * Set the select clause for the relation query. + * + * @param array $columns + * @return array + */ + protected function getSelectColumns(array $columns = ['*']) + { + if ($columns == ['*']) { + $columns = [$this->related->getTable().'.*']; + } + + return array_merge($columns, [$this->parent->getTable().'.'.$this->firstKey]); + } + + /** + * Get a paginator for the "select" statement. + * + * @param int $perPage + * @param array $columns + * @param string $pageName + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + */ + public function paginate($perPage = null, $columns = ['*'], $pageName = 'page') + { + $this->query->addSelect($this->getSelectColumns($columns)); + + return $this->query->paginate($perPage, $columns, $pageName); + } + + /** + * Paginate the given query into a simple paginator. + * + * @param int $perPage + * @param array $columns + * @return \Illuminate\Contracts\Pagination\Paginator + */ + public function simplePaginate($perPage = null, $columns = ['*']) + { + $this->query->addSelect($this->getSelectColumns($columns)); + + return $this->query->simplePaginate($perPage, $columns); + } + + /** + * Get the key for comparing against the parent key in "has" query. + * + * @return string + */ + public function getHasCompareKey() + { + return $this->farParent->getQualifiedKeyName(); + } + + /** + * Get the qualified foreign key on the related model. + * + * @return string + */ + public function getForeignKey() + { + return $this->related->getTable().'.'.$this->secondKey; + } + + /** + * Get the qualified foreign key on the "through" model. + * + * @return string + */ + public function getThroughKey() + { + return $this->parent->getTable().'.'.$this->firstKey; + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOne.php b/vendor/illuminate/database/Eloquent/Relations/HasOne.php new file mode 100755 index 0000000..52ad2a6 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/HasOne.php @@ -0,0 +1,47 @@ +query->first(); + } + + /** + * Initialize the relation on a set of models. + * + * @param array $models + * @param string $relation + * @return array + */ + public function initRelation(array $models, $relation) + { + foreach ($models as $model) { + $model->setRelation($relation, null); + } + + return $models; + } + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function match(array $models, Collection $results, $relation) + { + return $this->matchOne($models, $results, $relation); + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php b/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php new file mode 100755 index 0000000..8283099 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php @@ -0,0 +1,403 @@ +localKey = $localKey; + $this->foreignKey = $foreignKey; + + parent::__construct($query, $parent); + } + + /** + * Set the base constraints on the relation query. + * + * @return void + */ + public function addConstraints() + { + if (static::$constraints) { + $this->query->where($this->foreignKey, '=', $this->getParentKey()); + + $this->query->whereNotNull($this->foreignKey); + } + } + + /** + * Add the constraints for a relationship count query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQuery(Builder $query, Builder $parent) + { + if ($parent->getQuery()->from == $query->getQuery()->from) { + return $this->getRelationCountQueryForSelfRelation($query, $parent); + } + + return parent::getRelationCountQuery($query, $parent); + } + + /** + * Add the constraints for a relationship count query on the same table. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQueryForSelfRelation(Builder $query, Builder $parent) + { + $query->select(new Expression('count(*)')); + + $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash()); + + $key = $this->wrap($this->getQualifiedParentKeyName()); + + return $query->where($hash.'.'.$this->getPlainForeignKey(), '=', new Expression($key)); + } + + /** + * Get a relationship join table hash. + * + * @return string + */ + public function getRelationCountHash() + { + return 'self_'.md5(microtime(true)); + } + + /** + * Set the constraints for an eager load of the relation. + * + * @param array $models + * @return void + */ + public function addEagerConstraints(array $models) + { + $this->query->whereIn($this->foreignKey, $this->getKeys($models, $this->localKey)); + } + + /** + * Match the eagerly loaded results to their single parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function matchOne(array $models, Collection $results, $relation) + { + return $this->matchOneOrMany($models, $results, $relation, 'one'); + } + + /** + * Match the eagerly loaded results to their many parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function matchMany(array $models, Collection $results, $relation) + { + return $this->matchOneOrMany($models, $results, $relation, 'many'); + } + + /** + * Match the eagerly loaded results to their many parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @param string $type + * @return array + */ + protected function matchOneOrMany(array $models, Collection $results, $relation, $type) + { + $dictionary = $this->buildDictionary($results); + + // Once we have the dictionary we can simply spin through the parent models to + // link them up with their children using the keyed dictionary to make the + // matching very convenient and easy work. Then we'll just return them. + foreach ($models as $model) { + $key = $model->getAttribute($this->localKey); + + if (isset($dictionary[$key])) { + $value = $this->getRelationValue($dictionary, $key, $type); + + $model->setRelation($relation, $value); + } + } + + return $models; + } + + /** + * Get the value of a relationship by one or many type. + * + * @param array $dictionary + * @param string $key + * @param string $type + * @return mixed + */ + protected function getRelationValue(array $dictionary, $key, $type) + { + $value = $dictionary[$key]; + + return $type == 'one' ? reset($value) : $this->related->newCollection($value); + } + + /** + * Build model dictionary keyed by the relation's foreign key. + * + * @param \Illuminate\Database\Eloquent\Collection $results + * @return array + */ + protected function buildDictionary(Collection $results) + { + $dictionary = []; + + $foreign = $this->getPlainForeignKey(); + + // First we will create a dictionary of models keyed by the foreign key of the + // relationship as this will allow us to quickly access all of the related + // models without having to do nested looping which will be quite slow. + foreach ($results as $result) { + $dictionary[$result->{$foreign}][] = $result; + } + + return $dictionary; + } + + /** + * Attach a model instance to the parent model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return \Illuminate\Database\Eloquent\Model + */ + public function save(Model $model) + { + $model->setAttribute($this->getPlainForeignKey(), $this->getParentKey()); + + return $model->save() ? $model : false; + } + + /** + * Attach a collection of models to the parent instance. + * + * @param \Illuminate\Database\Eloquent\Collection|array $models + * @return \Illuminate\Database\Eloquent\Collection|array + */ + public function saveMany($models) + { + foreach ($models as $model) { + $this->save($model); + } + + return $models; + } + + /** + * Find a model by its primary key or return new instance of the related model. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model + */ + public function findOrNew($id, $columns = ['*']) + { + if (is_null($instance = $this->find($id, $columns))) { + $instance = $this->related->newInstance(); + + $instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey()); + } + + return $instance; + } + + /** + * Get the first related model record matching the attributes or instantiate it. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function firstOrNew(array $attributes) + { + if (is_null($instance = $this->where($attributes)->first())) { + $instance = $this->related->newInstance($attributes); + + $instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey()); + } + + return $instance; + } + + /** + * Get the first related record matching the attributes or create it. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function firstOrCreate(array $attributes) + { + if (is_null($instance = $this->where($attributes)->first())) { + $instance = $this->create($attributes); + } + + return $instance; + } + + /** + * Create or update a related record matching the attributes, and fill it with values. + * + * @param array $attributes + * @param array $values + * @return \Illuminate\Database\Eloquent\Model + */ + public function updateOrCreate(array $attributes, array $values = []) + { + $instance = $this->firstOrNew($attributes); + + $instance->fill($values); + + $instance->save(); + + return $instance; + } + + /** + * Create a new instance of the related model. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function create(array $attributes) + { + // Here we will set the raw attributes to avoid hitting the "fill" method so + // that we do not have to worry about a mass accessor rules blocking sets + // on the models. Otherwise, some of these attributes will not get set. + $instance = $this->related->newInstance($attributes); + + $instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey()); + + $instance->save(); + + return $instance; + } + + /** + * Create an array of new instances of the related model. + * + * @param array $records + * @return array + */ + public function createMany(array $records) + { + $instances = []; + + foreach ($records as $record) { + $instances[] = $this->create($record); + } + + return $instances; + } + + /** + * Perform an update on all the related models. + * + * @param array $attributes + * @return int + */ + public function update(array $attributes) + { + if ($this->related->usesTimestamps()) { + $attributes[$this->relatedUpdatedAt()] = $this->related->freshTimestampString(); + } + + return $this->query->update($attributes); + } + + /** + * Get the key for comparing against the parent key in "has" query. + * + * @return string + */ + public function getHasCompareKey() + { + return $this->getForeignKey(); + } + + /** + * Get the foreign key for the relationship. + * + * @return string + */ + public function getForeignKey() + { + return $this->foreignKey; + } + + /** + * Get the plain foreign key. + * + * @return string + */ + public function getPlainForeignKey() + { + $segments = explode('.', $this->getForeignKey()); + + return $segments[count($segments) - 1]; + } + + /** + * Get the key value of the parent's local key. + * + * @return mixed + */ + public function getParentKey() + { + return $this->parent->getAttribute($this->localKey); + } + + /** + * Get the fully qualified parent key name. + * + * @return string + */ + public function getQualifiedParentKeyName() + { + return $this->parent->getTable().'.'.$this->localKey; + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphMany.php new file mode 100755 index 0000000..e2a5c5a --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/MorphMany.php @@ -0,0 +1,47 @@ +query->get(); + } + + /** + * Initialize the relation on a set of models. + * + * @param array $models + * @param string $relation + * @return array + */ + public function initRelation(array $models, $relation) + { + foreach ($models as $model) { + $model->setRelation($relation, $this->related->newCollection()); + } + + return $models; + } + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function match(array $models, Collection $results, $relation) + { + return $this->matchMany($models, $results, $relation); + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphOne.php b/vendor/illuminate/database/Eloquent/Relations/MorphOne.php new file mode 100755 index 0000000..339a68c --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/MorphOne.php @@ -0,0 +1,47 @@ +query->first(); + } + + /** + * Initialize the relation on a set of models. + * + * @param array $models + * @param string $relation + * @return array + */ + public function initRelation(array $models, $relation) + { + foreach ($models as $model) { + $model->setRelation($relation, null); + } + + return $models; + } + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function match(array $models, Collection $results, $relation) + { + return $this->matchOne($models, $results, $relation); + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php new file mode 100755 index 0000000..658452c --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php @@ -0,0 +1,233 @@ +morphType = $type; + + $this->morphClass = $parent->getMorphClass(); + + parent::__construct($query, $parent, $id, $localKey); + } + + /** + * Set the base constraints on the relation query. + * + * @return void + */ + public function addConstraints() + { + if (static::$constraints) { + parent::addConstraints(); + + $this->query->where($this->morphType, $this->morphClass); + } + } + + /** + * Get the relationship count query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQuery(Builder $query, Builder $parent) + { + $query = parent::getRelationCountQuery($query, $parent); + + return $query->where($this->morphType, $this->morphClass); + } + + /** + * Set the constraints for an eager load of the relation. + * + * @param array $models + * @return void + */ + public function addEagerConstraints(array $models) + { + parent::addEagerConstraints($models); + + $this->query->where($this->morphType, $this->morphClass); + } + + /** + * Attach a model instance to the parent model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return \Illuminate\Database\Eloquent\Model + */ + public function save(Model $model) + { + $model->setAttribute($this->getPlainMorphType(), $this->morphClass); + + return parent::save($model); + } + + /** + * Find a related model by its primary key or return new instance of the related model. + * + * @param mixed $id + * @param array $columns + * @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model + */ + public function findOrNew($id, $columns = ['*']) + { + if (is_null($instance = $this->find($id, $columns))) { + $instance = $this->related->newInstance(); + + // When saving a polymorphic relationship, we need to set not only the foreign + // key, but also the foreign key type, which is typically the class name of + // the parent model. This makes the polymorphic item unique in the table. + $this->setForeignAttributesForCreate($instance); + } + + return $instance; + } + + /** + * Get the first related model record matching the attributes or instantiate it. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function firstOrNew(array $attributes) + { + if (is_null($instance = $this->where($attributes)->first())) { + $instance = $this->related->newInstance($attributes); + + // When saving a polymorphic relationship, we need to set not only the foreign + // key, but also the foreign key type, which is typically the class name of + // the parent model. This makes the polymorphic item unique in the table. + $this->setForeignAttributesForCreate($instance); + } + + return $instance; + } + + /** + * Get the first related record matching the attributes or create it. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function firstOrCreate(array $attributes) + { + if (is_null($instance = $this->where($attributes)->first())) { + $instance = $this->create($attributes); + } + + return $instance; + } + + /** + * Create or update a related record matching the attributes, and fill it with values. + * + * @param array $attributes + * @param array $values + * @return \Illuminate\Database\Eloquent\Model + */ + public function updateOrCreate(array $attributes, array $values = []) + { + $instance = $this->firstOrNew($attributes); + + $instance->fill($values); + + $instance->save(); + + return $instance; + } + + /** + * Create a new instance of the related model. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function create(array $attributes) + { + $instance = $this->related->newInstance($attributes); + + // When saving a polymorphic relationship, we need to set not only the foreign + // key, but also the foreign key type, which is typically the class name of + // the parent model. This makes the polymorphic item unique in the table. + $this->setForeignAttributesForCreate($instance); + + $instance->save(); + + return $instance; + } + + /** + * Set the foreign ID and type for creating a related model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return void + */ + protected function setForeignAttributesForCreate(Model $model) + { + $model->{$this->getPlainForeignKey()} = $this->getParentKey(); + + $model->{last(explode('.', $this->morphType))} = $this->morphClass; + } + + /** + * Get the foreign key "type" name. + * + * @return string + */ + public function getMorphType() + { + return $this->morphType; + } + + /** + * Get the plain morph type name without the table. + * + * @return string + */ + public function getPlainMorphType() + { + return last(explode('.', $this->morphType)); + } + + /** + * Get the class name of the parent model. + * + * @return string + */ + public function getMorphClass() + { + return $this->morphClass; + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php b/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php new file mode 100644 index 0000000..b7a2f34 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php @@ -0,0 +1,79 @@ +where($this->morphType, $this->morphClass); + + return parent::setKeysForSaveQuery($query); + } + + /** + * Delete the pivot model record from the database. + * + * @return int + */ + public function delete() + { + $query = $this->getDeleteQuery(); + + $query->where($this->morphType, $this->morphClass); + + return $query->delete(); + } + + /** + * Set the morph type for the pivot. + * + * @param string $morphType + * @return $this + */ + public function setMorphType($morphType) + { + $this->morphType = $morphType; + + return $this; + } + + /** + * Set the morph class for the pivot. + * + * @param string $morphClass + * @return \Illuminate\Database\Eloquent\Relations\MorphPivot + */ + public function setMorphClass($morphClass) + { + $this->morphClass = $morphClass; + + return $this; + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphTo.php b/vendor/illuminate/database/Eloquent/Relations/MorphTo.php new file mode 100644 index 0000000..06a488d --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/MorphTo.php @@ -0,0 +1,269 @@ +morphType = $type; + + parent::__construct($query, $parent, $foreignKey, $otherKey, $relation); + } + + /** + * Get the results of the relationship. + * + * @return mixed + */ + public function getResults() + { + if (! $this->otherKey) { + return; + } + + return $this->query->first(); + } + + /** + * Set the constraints for an eager load of the relation. + * + * @param array $models + * @return void + */ + public function addEagerConstraints(array $models) + { + $this->buildDictionary($this->models = Collection::make($models)); + } + + /** + * Build a dictionary with the models. + * + * @param \Illuminate\Database\Eloquent\Collection $models + * @return void + */ + protected function buildDictionary(Collection $models) + { + foreach ($models as $model) { + if ($model->{$this->morphType}) { + $this->dictionary[$model->{$this->morphType}][$model->{$this->foreignKey}][] = $model; + } + } + } + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + public function match(array $models, Collection $results, $relation) + { + return $models; + } + + /** + * Associate the model instance to the given parent. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return \Illuminate\Database\Eloquent\Model + */ + public function associate($model) + { + $this->parent->setAttribute($this->foreignKey, $model->getKey()); + + $this->parent->setAttribute($this->morphType, $model->getMorphClass()); + + return $this->parent->setRelation($this->relation, $model); + } + + /** + * Dissociate previously associated model from the given parent. + * + * @return \Illuminate\Database\Eloquent\Model + */ + public function dissociate() + { + $this->parent->setAttribute($this->foreignKey, null); + + $this->parent->setAttribute($this->morphType, null); + + return $this->parent->setRelation($this->relation, null); + } + + /** + * Get the results of the relationship. + * + * Called via eager load method of Eloquent query builder. + * + * @return mixed + */ + public function getEager() + { + foreach (array_keys($this->dictionary) as $type) { + $this->matchToMorphParents($type, $this->getResultsByType($type)); + } + + return $this->models; + } + + /** + * Match the results for a given type to their parents. + * + * @param string $type + * @param \Illuminate\Database\Eloquent\Collection $results + * @return void + */ + protected function matchToMorphParents($type, Collection $results) + { + foreach ($results as $result) { + if (isset($this->dictionary[$type][$result->getKey()])) { + foreach ($this->dictionary[$type][$result->getKey()] as $model) { + $model->setRelation($this->relation, $result); + } + } + } + } + + /** + * Get all of the relation results for a type. + * + * @param string $type + * @return \Illuminate\Database\Eloquent\Collection + */ + protected function getResultsByType($type) + { + $instance = $this->createModelByType($type); + + $key = $instance->getTable().'.'.$instance->getKeyName(); + + $query = $instance->newQuery(); + + $query = $this->useWithTrashed($query); + + return $query->whereIn($key, $this->gatherKeysByType($type)->all())->get(); + } + + /** + * Gather all of the foreign keys for a given type. + * + * @param string $type + * @return array + */ + protected function gatherKeysByType($type) + { + $foreign = $this->foreignKey; + + return collect($this->dictionary[$type])->map(function ($models) use ($foreign) { + return head($models)->{$foreign}; + + })->values()->unique(); + } + + /** + * Create a new model instance by type. + * + * @param string $type + * @return \Illuminate\Database\Eloquent\Model + */ + public function createModelByType($type) + { + $class = $this->parent->getActualClassNameForMorph($type); + + return new $class; + } + + /** + * Get the foreign key "type" name. + * + * @return string + */ + public function getMorphType() + { + return $this->morphType; + } + + /** + * Get the dictionary used by the relationship. + * + * @return array + */ + public function getDictionary() + { + return $this->dictionary; + } + + /** + * Fetch soft-deleted model instances with query. + * + * @return $this + */ + public function withTrashed() + { + $this->withTrashed = true; + + $this->query = $this->useWithTrashed($this->query); + + return $this; + } + + /** + * Return trashed models with query if told so. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @return \Illuminate\Database\Eloquent\Builder + */ + protected function useWithTrashed(Builder $query) + { + if ($this->withTrashed && $query->getMacro('withTrashed') !== null) { + return $query->withTrashed(); + } + + return $query; + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php new file mode 100644 index 0000000..373005d --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php @@ -0,0 +1,160 @@ +inverse = $inverse; + $this->morphType = $name.'_type'; + $this->morphClass = $inverse ? $query->getModel()->getMorphClass() : $parent->getMorphClass(); + + parent::__construct($query, $parent, $table, $foreignKey, $otherKey, $relationName); + } + + /** + * Set the where clause for the relation query. + * + * @return $this + */ + protected function setWhere() + { + parent::setWhere(); + + $this->query->where($this->table.'.'.$this->morphType, $this->morphClass); + + return $this; + } + + /** + * Add the constraints for a relationship count query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQuery(Builder $query, Builder $parent) + { + $query = parent::getRelationCountQuery($query, $parent); + + return $query->where($this->table.'.'.$this->morphType, $this->morphClass); + } + + /** + * Set the constraints for an eager load of the relation. + * + * @param array $models + * @return void + */ + public function addEagerConstraints(array $models) + { + parent::addEagerConstraints($models); + + $this->query->where($this->table.'.'.$this->morphType, $this->morphClass); + } + + /** + * Create a new pivot attachment record. + * + * @param int $id + * @param bool $timed + * @return array + */ + protected function createAttachRecord($id, $timed) + { + $record = parent::createAttachRecord($id, $timed); + + return Arr::add($record, $this->morphType, $this->morphClass); + } + + /** + * Create a new query builder for the pivot table. + * + * @return \Illuminate\Database\Query\Builder + */ + protected function newPivotQuery() + { + $query = parent::newPivotQuery(); + + return $query->where($this->morphType, $this->morphClass); + } + + /** + * Create a new pivot model instance. + * + * @param array $attributes + * @param bool $exists + * @return \Illuminate\Database\Eloquent\Relations\Pivot + */ + public function newPivot(array $attributes = [], $exists = false) + { + $pivot = new MorphPivot($this->parent, $attributes, $this->table, $exists); + + $pivot->setPivotKeys($this->foreignKey, $this->otherKey) + ->setMorphType($this->morphType) + ->setMorphClass($this->morphClass); + + return $pivot; + } + + /** + * Get the foreign key "type" name. + * + * @return string + */ + public function getMorphType() + { + return $this->morphType; + } + + /** + * Get the class name of the parent model. + * + * @return string + */ + public function getMorphClass() + { + return $this->morphClass; + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/Pivot.php b/vendor/illuminate/database/Eloquent/Relations/Pivot.php new file mode 100755 index 0000000..4d80279 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/Pivot.php @@ -0,0 +1,174 @@ +setTable($table); + + $this->setConnection($parent->getConnectionName()); + + $this->forceFill($attributes); + + $this->syncOriginal(); + + // We store off the parent instance so we will access the timestamp column names + // for the model, since the pivot model timestamps aren't easily configurable + // from the developer's point of view. We can use the parents to get these. + $this->parent = $parent; + + $this->exists = $exists; + + $this->timestamps = $this->hasTimestampAttributes(); + } + + /** + * Set the keys for a save update query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @return \Illuminate\Database\Eloquent\Builder + */ + protected function setKeysForSaveQuery(Builder $query) + { + $query->where($this->foreignKey, $this->getAttribute($this->foreignKey)); + + return $query->where($this->otherKey, $this->getAttribute($this->otherKey)); + } + + /** + * Delete the pivot model record from the database. + * + * @return int + */ + public function delete() + { + return $this->getDeleteQuery()->delete(); + } + + /** + * Get the query builder for a delete operation on the pivot. + * + * @return \Illuminate\Database\Eloquent\Builder + */ + protected function getDeleteQuery() + { + $foreign = $this->getAttribute($this->foreignKey); + + $query = $this->newQuery()->where($this->foreignKey, $foreign); + + return $query->where($this->otherKey, $this->getAttribute($this->otherKey)); + } + + /** + * Get the foreign key column name. + * + * @return string + */ + public function getForeignKey() + { + return $this->foreignKey; + } + + /** + * Get the "other key" column name. + * + * @return string + */ + public function getOtherKey() + { + return $this->otherKey; + } + + /** + * Set the key names for the pivot model instance. + * + * @param string $foreignKey + * @param string $otherKey + * @return $this + */ + public function setPivotKeys($foreignKey, $otherKey) + { + $this->foreignKey = $foreignKey; + + $this->otherKey = $otherKey; + + return $this; + } + + /** + * Determine if the pivot model has timestamp attributes. + * + * @return bool + */ + public function hasTimestampAttributes() + { + return array_key_exists($this->getCreatedAtColumn(), $this->attributes); + } + + /** + * Get the name of the "created at" column. + * + * @return string + */ + public function getCreatedAtColumn() + { + return $this->parent->getCreatedAtColumn(); + } + + /** + * Get the name of the "updated at" column. + * + * @return string + */ + public function getUpdatedAtColumn() + { + return $this->parent->getUpdatedAtColumn(); + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/Relation.php b/vendor/illuminate/database/Eloquent/Relations/Relation.php new file mode 100755 index 0000000..4d942a9 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Relations/Relation.php @@ -0,0 +1,339 @@ +query = $query; + $this->parent = $parent; + $this->related = $query->getModel(); + + $this->addConstraints(); + } + + /** + * Set the base constraints on the relation query. + * + * @return void + */ + abstract public function addConstraints(); + + /** + * Set the constraints for an eager load of the relation. + * + * @param array $models + * @return void + */ + abstract public function addEagerConstraints(array $models); + + /** + * Initialize the relation on a set of models. + * + * @param array $models + * @param string $relation + * @return array + */ + abstract public function initRelation(array $models, $relation); + + /** + * Match the eagerly loaded results to their parents. + * + * @param array $models + * @param \Illuminate\Database\Eloquent\Collection $results + * @param string $relation + * @return array + */ + abstract public function match(array $models, Collection $results, $relation); + + /** + * Get the results of the relationship. + * + * @return mixed + */ + abstract public function getResults(); + + /** + * Get the relationship for eager loading. + * + * @return \Illuminate\Database\Eloquent\Collection + */ + public function getEager() + { + return $this->get(); + } + + /** + * Touch all of the related models for the relationship. + * + * @return void + */ + public function touch() + { + $column = $this->getRelated()->getUpdatedAtColumn(); + + $this->rawUpdate([$column => $this->getRelated()->freshTimestampString()]); + } + + /** + * Run a raw update against the base query. + * + * @param array $attributes + * @return int + */ + public function rawUpdate(array $attributes = []) + { + return $this->query->update($attributes); + } + + /** + * Add the constraints for a relationship count query. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $parent + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getRelationCountQuery(Builder $query, Builder $parent) + { + $query->select(new Expression('count(*)')); + + $key = $this->wrap($this->getQualifiedParentKeyName()); + + return $query->where($this->getHasCompareKey(), '=', new Expression($key)); + } + + /** + * Run a callback with constraints disabled on the relation. + * + * @param \Closure $callback + * @return mixed + */ + public static function noConstraints(Closure $callback) + { + $previous = static::$constraints; + + static::$constraints = false; + + // When resetting the relation where clause, we want to shift the first element + // off of the bindings, leaving only the constraints that the developers put + // as "extra" on the relationships, and not original relation constraints. + try { + $results = call_user_func($callback); + } finally { + static::$constraints = $previous; + } + + return $results; + } + + /** + * Get all of the primary keys for an array of models. + * + * @param array $models + * @param string $key + * @return array + */ + protected function getKeys(array $models, $key = null) + { + return array_unique(array_values(array_map(function ($value) use ($key) { + return $key ? $value->getAttribute($key) : $value->getKey(); + + }, $models))); + } + + /** + * Get the underlying query for the relation. + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get the base query builder driving the Eloquent builder. + * + * @return \Illuminate\Database\Query\Builder + */ + public function getBaseQuery() + { + return $this->query->getQuery(); + } + + /** + * Get the parent model of the relation. + * + * @return \Illuminate\Database\Eloquent\Model + */ + public function getParent() + { + return $this->parent; + } + + /** + * Get the fully qualified parent key name. + * + * @return string + */ + public function getQualifiedParentKeyName() + { + return $this->parent->getQualifiedKeyName(); + } + + /** + * Get the related model of the relation. + * + * @return \Illuminate\Database\Eloquent\Model + */ + public function getRelated() + { + return $this->related; + } + + /** + * Get the name of the "created at" column. + * + * @return string + */ + public function createdAt() + { + return $this->parent->getCreatedAtColumn(); + } + + /** + * Get the name of the "updated at" column. + * + * @return string + */ + public function updatedAt() + { + return $this->parent->getUpdatedAtColumn(); + } + + /** + * Get the name of the related model's "updated at" column. + * + * @return string + */ + public function relatedUpdatedAt() + { + return $this->related->getUpdatedAtColumn(); + } + + /** + * Wrap the given value with the parent query's grammar. + * + * @param string $value + * @return string + */ + public function wrap($value) + { + return $this->parent->newQueryWithoutScopes()->getQuery()->getGrammar()->wrap($value); + } + + /** + * Set or get the morph map for polymorphic relations. + * + * @param array|null $map + * @param bool $merge + * @return array + */ + public static function morphMap(array $map = null, $merge = true) + { + $map = static::buildMorphMapFromModels($map); + + if (is_array($map)) { + static::$morphMap = $merge ? array_merge(static::$morphMap, $map) : $map; + } + + return static::$morphMap; + } + + /** + * Builds a table-keyed array from model class names. + * + * @param string[]|null $models + * @return array|null + */ + protected static function buildMorphMapFromModels(array $models = null) + { + if (is_null($models) || Arr::isAssoc($models)) { + return $models; + } + + $tables = array_map(function ($model) { + return (new $model)->getTable(); + }, $models); + + return array_combine($tables, $models); + } + + /** + * Handle dynamic method calls to the relationship. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + $result = call_user_func_array([$this->query, $method], $parameters); + + if ($result === $this->query) { + return $this; + } + + return $result; + } +} diff --git a/vendor/illuminate/database/Eloquent/ScopeInterface.php b/vendor/illuminate/database/Eloquent/ScopeInterface.php new file mode 100644 index 0000000..fac2ca2 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/ScopeInterface.php @@ -0,0 +1,25 @@ +forceDeleting = true; + + $this->delete(); + + $this->forceDeleting = false; + } + + /** + * Perform the actual delete query on this model instance. + * + * @return mixed + */ + protected function performDeleteOnModel() + { + if ($this->forceDeleting) { + return $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey())->forceDelete(); + } + + return $this->runSoftDelete(); + } + + /** + * Perform the actual delete query on this model instance. + * + * @return void + */ + protected function runSoftDelete() + { + $query = $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey()); + + $this->{$this->getDeletedAtColumn()} = $time = $this->freshTimestamp(); + + $query->update([$this->getDeletedAtColumn() => $this->fromDateTime($time)]); + } + + /** + * Restore a soft-deleted model instance. + * + * @return bool|null + */ + public function restore() + { + // If the restoring event does not return false, we will proceed with this + // restore operation. Otherwise, we bail out so the developer will stop + // the restore totally. We will clear the deleted timestamp and save. + if ($this->fireModelEvent('restoring') === false) { + return false; + } + + $this->{$this->getDeletedAtColumn()} = null; + + // Once we have saved the model, we will fire the "restored" event so this + // developer will do anything they need to after a restore operation is + // totally finished. Then we will return the result of the save call. + $this->exists = true; + + $result = $this->save(); + + $this->fireModelEvent('restored', false); + + return $result; + } + + /** + * Determine if the model instance has been soft-deleted. + * + * @return bool + */ + public function trashed() + { + return ! is_null($this->{$this->getDeletedAtColumn()}); + } + + /** + * Get a new query builder that includes soft deletes. + * + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public static function withTrashed() + { + return (new static)->newQueryWithoutScope(new SoftDeletingScope); + } + + /** + * Get a new query builder that only includes soft deletes. + * + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public static function onlyTrashed() + { + $instance = new static; + + $column = $instance->getQualifiedDeletedAtColumn(); + + return $instance->newQueryWithoutScope(new SoftDeletingScope)->whereNotNull($column); + } + + /** + * Register a restoring model event with the dispatcher. + * + * @param \Closure|string $callback + * @return void + */ + public static function restoring($callback) + { + static::registerModelEvent('restoring', $callback); + } + + /** + * Register a restored model event with the dispatcher. + * + * @param \Closure|string $callback + * @return void + */ + public static function restored($callback) + { + static::registerModelEvent('restored', $callback); + } + + /** + * Get the name of the "deleted at" column. + * + * @return string + */ + public function getDeletedAtColumn() + { + return defined('static::DELETED_AT') ? static::DELETED_AT : 'deleted_at'; + } + + /** + * Get the fully qualified "deleted at" column. + * + * @return string + */ + public function getQualifiedDeletedAtColumn() + { + return $this->getTable().'.'.$this->getDeletedAtColumn(); + } +} diff --git a/vendor/illuminate/database/Eloquent/SoftDeletingScope.php b/vendor/illuminate/database/Eloquent/SoftDeletingScope.php new file mode 100644 index 0000000..f8786cf --- /dev/null +++ b/vendor/illuminate/database/Eloquent/SoftDeletingScope.php @@ -0,0 +1,155 @@ +whereNull($model->getQualifiedDeletedAtColumn()); + + $this->extend($builder); + } + + /** + * Remove the scope from the given Eloquent query builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @param \Illuminate\Database\Eloquent\Model $model + * @return void + */ + public function remove(Builder $builder, Model $model) + { + $column = $model->getQualifiedDeletedAtColumn(); + + $query = $builder->getQuery(); + + $query->wheres = collect($query->wheres)->reject(function ($where) use ($column) { + return $this->isSoftDeleteConstraint($where, $column); + })->values()->all(); + } + + /** + * Extend the query builder with the needed functions. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + public function extend(Builder $builder) + { + foreach ($this->extensions as $extension) { + $this->{"add{$extension}"}($builder); + } + + $builder->onDelete(function (Builder $builder) { + $column = $this->getDeletedAtColumn($builder); + + return $builder->update([ + $column => $builder->getModel()->freshTimestampString(), + ]); + }); + } + + /** + * Get the "deleted at" column for the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return string + */ + protected function getDeletedAtColumn(Builder $builder) + { + if (count($builder->getQuery()->joins) > 0) { + return $builder->getModel()->getQualifiedDeletedAtColumn(); + } else { + return $builder->getModel()->getDeletedAtColumn(); + } + } + + /** + * Add the force delete extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addForceDelete(Builder $builder) + { + $builder->macro('forceDelete', function (Builder $builder) { + return $builder->getQuery()->delete(); + }); + } + + /** + * Add the restore extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addRestore(Builder $builder) + { + $builder->macro('restore', function (Builder $builder) { + $builder->withTrashed(); + + return $builder->update([$builder->getModel()->getDeletedAtColumn() => null]); + }); + } + + /** + * Add the with-trashed extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addWithTrashed(Builder $builder) + { + $builder->macro('withTrashed', function (Builder $builder) { + $this->remove($builder, $builder->getModel()); + + return $builder; + }); + } + + /** + * Add the only-trashed extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addOnlyTrashed(Builder $builder) + { + $builder->macro('onlyTrashed', function (Builder $builder) { + $model = $builder->getModel(); + + $this->remove($builder, $model); + + $builder->getQuery()->whereNotNull($model->getQualifiedDeletedAtColumn()); + + return $builder; + }); + } + + /** + * Determine if the given where clause is a soft delete constraint. + * + * @param array $where + * @param string $column + * @return bool + */ + protected function isSoftDeleteConstraint(array $where, $column) + { + return $where['type'] == 'Null' && $where['column'] == $column; + } +} diff --git a/vendor/illuminate/database/Grammar.php b/vendor/illuminate/database/Grammar.php new file mode 100755 index 0000000..a9985b5 --- /dev/null +++ b/vendor/illuminate/database/Grammar.php @@ -0,0 +1,188 @@ +isExpression($table)) { + return $this->getValue($table); + } + + return $this->wrap($this->tablePrefix.$table, true); + } + + /** + * Wrap a value in keyword identifiers. + * + * @param string|\Illuminate\Database\Query\Expression $value + * @param bool $prefixAlias + * @return string + */ + public function wrap($value, $prefixAlias = false) + { + if ($this->isExpression($value)) { + return $this->getValue($value); + } + + // If the value being wrapped has a column alias we will need to separate out + // the pieces so we can wrap each of the segments of the expression on it + // own, and then joins them both back together with the "as" connector. + if (strpos(strtolower($value), ' as ') !== false) { + $segments = explode(' ', $value); + + if ($prefixAlias) { + $segments[2] = $this->tablePrefix.$segments[2]; + } + + return $this->wrap($segments[0]).' as '.$this->wrapValue($segments[2]); + } + + $wrapped = []; + + $segments = explode('.', $value); + + // If the value is not an aliased table expression, we'll just wrap it like + // normal, so if there is more than one segment, we will wrap the first + // segments as if it was a table and the rest as just regular values. + foreach ($segments as $key => $segment) { + if ($key == 0 && count($segments) > 1) { + $wrapped[] = $this->wrapTable($segment); + } else { + $wrapped[] = $this->wrapValue($segment); + } + } + + return implode('.', $wrapped); + } + + /** + * Wrap a single string in keyword identifiers. + * + * @param string $value + * @return string + */ + protected function wrapValue($value) + { + if ($value === '*') { + return $value; + } + + return '"'.str_replace('"', '""', $value).'"'; + } + + /** + * Convert an array of column names into a delimited string. + * + * @param array $columns + * @return string + */ + public function columnize(array $columns) + { + return implode(', ', array_map([$this, 'wrap'], $columns)); + } + + /** + * Create query parameter place-holders for an array. + * + * @param array $values + * @return string + */ + public function parameterize(array $values) + { + return implode(', ', array_map([$this, 'parameter'], $values)); + } + + /** + * Get the appropriate query parameter place-holder for a value. + * + * @param mixed $value + * @return string + */ + public function parameter($value) + { + return $this->isExpression($value) ? $this->getValue($value) : '?'; + } + + /** + * Get the value of a raw expression. + * + * @param \Illuminate\Database\Query\Expression $expression + * @return string + */ + public function getValue($expression) + { + return $expression->getValue(); + } + + /** + * Determine if the given value is a raw expression. + * + * @param mixed $value + * @return bool + */ + public function isExpression($value) + { + return $value instanceof Expression; + } + + /** + * Get the format for database stored dates. + * + * @return string + */ + public function getDateFormat() + { + return 'Y-m-d H:i:s'; + } + + /** + * Get the grammar's table prefix. + * + * @return string + */ + public function getTablePrefix() + { + return $this->tablePrefix; + } + + /** + * Set the grammar's table prefix. + * + * @param string $prefix + * @return $this + */ + public function setTablePrefix($prefix) + { + $this->tablePrefix = $prefix; + + return $this; + } +} diff --git a/vendor/illuminate/database/MigrationServiceProvider.php b/vendor/illuminate/database/MigrationServiceProvider.php new file mode 100755 index 0000000..43b26ca --- /dev/null +++ b/vendor/illuminate/database/MigrationServiceProvider.php @@ -0,0 +1,221 @@ +registerRepository(); + + // Once we have registered the migrator instance we will go ahead and register + // all of the migration related commands that are used by the "Artisan" CLI + // so that they may be easily accessed for registering with the consoles. + $this->registerMigrator(); + + $this->registerCommands(); + } + + /** + * Register the migration repository service. + * + * @return void + */ + protected function registerRepository() + { + $this->app->singleton('migration.repository', function ($app) { + $table = $app['config']['database.migrations']; + + return new DatabaseMigrationRepository($app['db'], $table); + }); + } + + /** + * Register the migrator service. + * + * @return void + */ + protected function registerMigrator() + { + // The migrator is responsible for actually running and rollback the migration + // files in the application. We'll pass in our database connection resolver + // so the migrator can resolve any of these connections when it needs to. + $this->app->singleton('migrator', function ($app) { + $repository = $app['migration.repository']; + + return new Migrator($repository, $app['db'], $app['files']); + }); + } + + /** + * Register all of the migration commands. + * + * @return void + */ + protected function registerCommands() + { + $commands = ['Migrate', 'Rollback', 'Reset', 'Refresh', 'Install', 'Make', 'Status']; + + // We'll simply spin through the list of commands that are migration related + // and register each one of them with an application container. They will + // be resolved in the Artisan start file and registered on the console. + foreach ($commands as $command) { + $this->{'register'.$command.'Command'}(); + } + + // Once the commands are registered in the application IoC container we will + // register them with the Artisan start event so that these are available + // when the Artisan application actually starts up and is getting used. + $this->commands( + 'command.migrate', 'command.migrate.make', + 'command.migrate.install', 'command.migrate.rollback', + 'command.migrate.reset', 'command.migrate.refresh', + 'command.migrate.status' + ); + } + + /** + * Register the "migrate" migration command. + * + * @return void + */ + protected function registerMigrateCommand() + { + $this->app->singleton('command.migrate', function ($app) { + return new MigrateCommand($app['migrator']); + }); + } + + /** + * Register the "rollback" migration command. + * + * @return void + */ + protected function registerRollbackCommand() + { + $this->app->singleton('command.migrate.rollback', function ($app) { + return new RollbackCommand($app['migrator']); + }); + } + + /** + * Register the "reset" migration command. + * + * @return void + */ + protected function registerResetCommand() + { + $this->app->singleton('command.migrate.reset', function ($app) { + return new ResetCommand($app['migrator']); + }); + } + + /** + * Register the "refresh" migration command. + * + * @return void + */ + protected function registerRefreshCommand() + { + $this->app->singleton('command.migrate.refresh', function () { + return new RefreshCommand; + }); + } + + /** + * Register the "status" migration command. + * + * @return void + */ + protected function registerStatusCommand() + { + $this->app->singleton('command.migrate.status', function ($app) { + return new StatusCommand($app['migrator']); + }); + } + + /** + * Register the "install" migration command. + * + * @return void + */ + protected function registerInstallCommand() + { + $this->app->singleton('command.migrate.install', function ($app) { + return new InstallCommand($app['migration.repository']); + }); + } + + /** + * Register the "make" migration command. + * + * @return void + */ + protected function registerMakeCommand() + { + $this->registerCreator(); + + $this->app->singleton('command.migrate.make', function ($app) { + // Once we have the migration creator registered, we will create the command + // and inject the creator. The creator is responsible for the actual file + // creation of the migrations, and may be extended by these developers. + $creator = $app['migration.creator']; + + $composer = $app['composer']; + + return new MigrateMakeCommand($creator, $composer); + }); + } + + /** + * Register the migration creator. + * + * @return void + */ + protected function registerCreator() + { + $this->app->singleton('migration.creator', function ($app) { + return new MigrationCreator($app['files']); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'migrator', 'migration.repository', 'command.migrate', + 'command.migrate.rollback', 'command.migrate.reset', + 'command.migrate.refresh', 'command.migrate.install', + 'command.migrate.status', 'migration.creator', + 'command.migrate.make', + ]; + } +} diff --git a/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php b/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php new file mode 100755 index 0000000..13f3da4 --- /dev/null +++ b/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php @@ -0,0 +1,184 @@ +table = $table; + $this->resolver = $resolver; + } + + /** + * Get the ran migrations. + * + * @return array + */ + public function getRan() + { + return $this->table() + ->orderBy('batch', 'asc') + ->orderBy('migration', 'asc') + ->lists('migration'); + } + + /** + * Get the last migration batch. + * + * @return array + */ + public function getLast() + { + $query = $this->table()->where('batch', $this->getLastBatchNumber()); + + return $query->orderBy('migration', 'desc')->get(); + } + + /** + * Log that a migration was run. + * + * @param string $file + * @param int $batch + * @return void + */ + public function log($file, $batch) + { + $record = ['migration' => $file, 'batch' => $batch]; + + $this->table()->insert($record); + } + + /** + * Remove a migration from the log. + * + * @param object $migration + * @return void + */ + public function delete($migration) + { + $this->table()->where('migration', $migration->migration)->delete(); + } + + /** + * Get the next migration batch number. + * + * @return int + */ + public function getNextBatchNumber() + { + return $this->getLastBatchNumber() + 1; + } + + /** + * Get the last migration batch number. + * + * @return int + */ + public function getLastBatchNumber() + { + return $this->table()->max('batch'); + } + + /** + * Create the migration repository data store. + * + * @return void + */ + public function createRepository() + { + $schema = $this->getConnection()->getSchemaBuilder(); + + $schema->create($this->table, function ($table) { + // The migrations table is responsible for keeping track of which of the + // migrations have actually run for the application. We'll create the + // table to hold the migration file's path as well as the batch ID. + $table->string('migration'); + + $table->integer('batch'); + }); + } + + /** + * Determine if the migration repository exists. + * + * @return bool + */ + public function repositoryExists() + { + $schema = $this->getConnection()->getSchemaBuilder(); + + return $schema->hasTable($this->table); + } + + /** + * Get a query builder for the migration table. + * + * @return \Illuminate\Database\Query\Builder + */ + protected function table() + { + return $this->getConnection()->table($this->table); + } + + /** + * Get the connection resolver instance. + * + * @return \Illuminate\Database\ConnectionResolverInterface + */ + public function getConnectionResolver() + { + return $this->resolver; + } + + /** + * Resolve the database connection instance. + * + * @return \Illuminate\Database\Connection + */ + public function getConnection() + { + return $this->resolver->connection($this->connection); + } + + /** + * Set the information source to gather data. + * + * @param string $name + * @return void + */ + public function setSource($name) + { + $this->connection = $name; + } +} diff --git a/vendor/illuminate/database/Migrations/Migration.php b/vendor/illuminate/database/Migrations/Migration.php new file mode 100755 index 0000000..699154c --- /dev/null +++ b/vendor/illuminate/database/Migrations/Migration.php @@ -0,0 +1,23 @@ +connection; + } +} diff --git a/vendor/illuminate/database/Migrations/MigrationCreator.php b/vendor/illuminate/database/Migrations/MigrationCreator.php new file mode 100755 index 0000000..beacfe1 --- /dev/null +++ b/vendor/illuminate/database/Migrations/MigrationCreator.php @@ -0,0 +1,181 @@ +files = $files; + } + + /** + * Create a new migration at the given path. + * + * @param string $name + * @param string $path + * @param string $table + * @param bool $create + * @return string + */ + public function create($name, $path, $table = null, $create = false) + { + $path = $this->getPath($name, $path); + + // First we will get the stub file for the migration, which serves as a type + // of template for the migration. Once we have those we will populate the + // various place-holders, save the file, and run the post create event. + $stub = $this->getStub($table, $create); + + $this->files->put($path, $this->populateStub($name, $stub, $table)); + + $this->firePostCreateHooks(); + + return $path; + } + + /** + * Get the migration stub file. + * + * @param string $table + * @param bool $create + * @return string + */ + protected function getStub($table, $create) + { + if (is_null($table)) { + return $this->files->get($this->getStubPath().'/blank.stub'); + } + + // We also have stubs for creating new tables and modifying existing tables + // to save the developer some typing when they are creating a new tables + // or modifying existing tables. We'll grab the appropriate stub here. + else { + $stub = $create ? 'create.stub' : 'update.stub'; + + return $this->files->get($this->getStubPath()."/{$stub}"); + } + } + + /** + * Populate the place-holders in the migration stub. + * + * @param string $name + * @param string $stub + * @param string $table + * @return string + */ + protected function populateStub($name, $stub, $table) + { + $stub = str_replace('DummyClass', $this->getClassName($name), $stub); + + // Here we will replace the table place-holders with the table specified by + // the developer, which is useful for quickly creating a tables creation + // or update migration from the console instead of typing it manually. + if (! is_null($table)) { + $stub = str_replace('DummyTable', $table, $stub); + } + + return $stub; + } + + /** + * Get the class name of a migration name. + * + * @param string $name + * @return string + */ + protected function getClassName($name) + { + return Str::studly($name); + } + + /** + * Fire the registered post create hooks. + * + * @return void + */ + protected function firePostCreateHooks() + { + foreach ($this->postCreate as $callback) { + call_user_func($callback); + } + } + + /** + * Register a post migration create hook. + * + * @param \Closure $callback + * @return void + */ + public function afterCreate(Closure $callback) + { + $this->postCreate[] = $callback; + } + + /** + * Get the full path name to the migration. + * + * @param string $name + * @param string $path + * @return string + */ + protected function getPath($name, $path) + { + return $path.'/'.$this->getDatePrefix().'_'.$name.'.php'; + } + + /** + * Get the date prefix for the migration. + * + * @return string + */ + protected function getDatePrefix() + { + return date('Y_m_d_His'); + } + + /** + * Get the path to the stubs. + * + * @return string + */ + public function getStubPath() + { + return __DIR__.'/stubs'; + } + + /** + * Get the filesystem instance. + * + * @return \Illuminate\Filesystem\Filesystem + */ + public function getFilesystem() + { + return $this->files; + } +} diff --git a/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php b/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php new file mode 100755 index 0000000..5450a7a --- /dev/null +++ b/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php @@ -0,0 +1,66 @@ +files = $files; + $this->resolver = $resolver; + $this->repository = $repository; + } + + /** + * Run the outstanding migrations at a given path. + * + * @param string $path + * @param bool $pretend + * @return void + */ + public function run($path, $pretend = false) + { + $this->notes = []; + + $files = $this->getMigrationFiles($path); + + // Once we grab all of the migration files for the path, we will compare them + // against the migrations that have already been run for this package then + // run each of the outstanding migrations against a database connection. + $ran = $this->repository->getRan(); + + $migrations = array_diff($files, $ran); + + $this->requireFiles($path, $migrations); + + $this->runMigrationList($migrations, $pretend); + } + + /** + * Run an array of migrations. + * + * @param array $migrations + * @param bool $pretend + * @return void + */ + public function runMigrationList($migrations, $pretend = false) + { + // First we will just make sure that there are any migrations to run. If there + // aren't, we will just make a note of it to the developer so they're aware + // that all of the migrations have been run against this database system. + if (count($migrations) == 0) { + $this->note('Nothing to migrate.'); + + return; + } + + $batch = $this->repository->getNextBatchNumber(); + + // Once we have the array of migrations, we will spin through them and run the + // migrations "up" so the changes are made to the databases. We'll then log + // that the migration was run so we don't repeat it next time we execute. + foreach ($migrations as $file) { + $this->runUp($file, $batch, $pretend); + } + } + + /** + * Run "up" a migration instance. + * + * @param string $file + * @param int $batch + * @param bool $pretend + * @return void + */ + protected function runUp($file, $batch, $pretend) + { + // First we will resolve a "real" instance of the migration class from this + // migration file name. Once we have the instances we can run the actual + // command such as "up" or "down", or we can just simulate the action. + $migration = $this->resolve($file); + + if ($pretend) { + return $this->pretendToRun($migration, 'up'); + } + + $migration->up(); + + // Once we have run a migrations class, we will log that it was run in this + // repository so that we don't try to run it next time we do a migration + // in the application. A migration repository keeps the migrate order. + $this->repository->log($file, $batch); + + $this->note("Migrated: $file"); + } + + /** + * Rollback the last migration operation. + * + * @param bool $pretend + * @return int + */ + public function rollback($pretend = false) + { + $this->notes = []; + + // We want to pull in the last batch of migrations that ran on the previous + // migration operation. We'll then reverse those migrations and run each + // of them "down" to reverse the last migration "operation" which ran. + $migrations = $this->repository->getLast(); + + $count = count($migrations); + + if ($count === 0) { + $this->note('Nothing to rollback.'); + } else { + // We need to reverse these migrations so that they are "downed" in reverse + // to what they run on "up". It lets us backtrack through the migrations + // and properly reverse the entire database schema operation that ran. + foreach ($migrations as $migration) { + $this->runDown((object) $migration, $pretend); + } + } + + return $count; + } + + /** + * Rolls all of the currently applied migrations back. + * + * @param bool $pretend + * @return int + */ + public function reset($pretend = false) + { + $this->notes = []; + + $migrations = array_reverse($this->repository->getRan()); + + $count = count($migrations); + + if ($count === 0) { + $this->note('Nothing to rollback.'); + } else { + foreach ($migrations as $migration) { + $this->runDown((object) ['migration' => $migration], $pretend); + } + } + + return $count; + } + + /** + * Run "down" a migration instance. + * + * @param object $migration + * @param bool $pretend + * @return void + */ + protected function runDown($migration, $pretend) + { + $file = $migration->migration; + + // First we will get the file name of the migration so we can resolve out an + // instance of the migration. Once we get an instance we can either run a + // pretend execution of the migration or we can run the real migration. + $instance = $this->resolve($file); + + if ($pretend) { + return $this->pretendToRun($instance, 'down'); + } + + $instance->down(); + + // Once we have successfully run the migration "down" we will remove it from + // the migration repository so it will be considered to have not been run + // by the application then will be able to fire by any later operation. + $this->repository->delete($migration); + + $this->note("Rolled back: $file"); + } + + /** + * Get all of the migration files in a given path. + * + * @param string $path + * @return array + */ + public function getMigrationFiles($path) + { + $files = $this->files->glob($path.'/*_*.php'); + + // Once we have the array of files in the directory we will just remove the + // extension and take the basename of the file which is all we need when + // finding the migrations that haven't been run against the databases. + if ($files === false) { + return []; + } + + $files = array_map(function ($file) { + return str_replace('.php', '', basename($file)); + + }, $files); + + // Once we have all of the formatted file names we will sort them and since + // they all start with a timestamp this should give us the migrations in + // the order they were actually created by the application developers. + sort($files); + + return $files; + } + + /** + * Require in all the migration files in a given path. + * + * @param string $path + * @param array $files + * @return void + */ + public function requireFiles($path, array $files) + { + foreach ($files as $file) { + $this->files->requireOnce($path.'/'.$file.'.php'); + } + } + + /** + * Pretend to run the migrations. + * + * @param object $migration + * @param string $method + * @return void + */ + protected function pretendToRun($migration, $method) + { + foreach ($this->getQueries($migration, $method) as $query) { + $name = get_class($migration); + + $this->note("{$name}: {$query['query']}"); + } + } + + /** + * Get all of the queries that would be run for a migration. + * + * @param object $migration + * @param string $method + * @return array + */ + protected function getQueries($migration, $method) + { + $connection = $migration->getConnection(); + + // Now that we have the connections we can resolve it and pretend to run the + // queries against the database returning the array of raw SQL statements + // that would get fired against the database system for this migration. + $db = $this->resolveConnection($connection); + + return $db->pretend(function () use ($migration, $method) { + $migration->$method(); + }); + } + + /** + * Resolve a migration instance from a file. + * + * @param string $file + * @return object + */ + public function resolve($file) + { + $file = implode('_', array_slice(explode('_', $file), 4)); + + $class = Str::studly($file); + + return new $class; + } + + /** + * Raise a note event for the migrator. + * + * @param string $message + * @return void + */ + protected function note($message) + { + $this->notes[] = $message; + } + + /** + * Get the notes for the last operation. + * + * @return array + */ + public function getNotes() + { + return $this->notes; + } + + /** + * Resolve the database connection instance. + * + * @param string $connection + * @return \Illuminate\Database\Connection + */ + public function resolveConnection($connection) + { + return $this->resolver->connection($connection); + } + + /** + * Set the default connection name. + * + * @param string $name + * @return void + */ + public function setConnection($name) + { + if (! is_null($name)) { + $this->resolver->setDefaultConnection($name); + } + + $this->repository->setSource($name); + + $this->connection = $name; + } + + /** + * Get the migration repository instance. + * + * @return \Illuminate\Database\Migrations\MigrationRepositoryInterface + */ + public function getRepository() + { + return $this->repository; + } + + /** + * Determine if the migration repository exists. + * + * @return bool + */ + public function repositoryExists() + { + return $this->repository->repositoryExists(); + } + + /** + * Get the file system instance. + * + * @return \Illuminate\Filesystem\Filesystem + */ + public function getFilesystem() + { + return $this->files; + } +} diff --git a/vendor/illuminate/database/Migrations/stubs/blank.stub b/vendor/illuminate/database/Migrations/stubs/blank.stub new file mode 100755 index 0000000..4ff5ee5 --- /dev/null +++ b/vendor/illuminate/database/Migrations/stubs/blank.stub @@ -0,0 +1,27 @@ +increments('id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('DummyTable'); + } +} diff --git a/vendor/illuminate/database/Migrations/stubs/update.stub b/vendor/illuminate/database/Migrations/stubs/update.stub new file mode 100755 index 0000000..8114a81 --- /dev/null +++ b/vendor/illuminate/database/Migrations/stubs/update.stub @@ -0,0 +1,31 @@ +schemaGrammar)) { + $this->useDefaultSchemaGrammar(); + } + + return new MySqlBuilder($this); + } + + /** + * Get the default query grammar instance. + * + * @return \Illuminate\Database\Query\Grammars\MySqlGrammar + */ + protected function getDefaultQueryGrammar() + { + return $this->withTablePrefix(new QueryGrammar); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\MySqlGrammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\MySqlProcessor + */ + protected function getDefaultPostProcessor() + { + return new MySqlProcessor; + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Doctrine\DBAL\Driver\PDOMySql\Driver + */ + protected function getDoctrineDriver() + { + return new DoctrineDriver; + } +} diff --git a/vendor/illuminate/database/PostgresConnection.php b/vendor/illuminate/database/PostgresConnection.php new file mode 100755 index 0000000..f12ec89 --- /dev/null +++ b/vendor/illuminate/database/PostgresConnection.php @@ -0,0 +1,51 @@ +withTablePrefix(new QueryGrammar); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\PostgresGrammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\PostgresProcessor + */ + protected function getDefaultPostProcessor() + { + return new PostgresProcessor; + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Doctrine\DBAL\Driver\PDOPgSql\Driver + */ + protected function getDoctrineDriver() + { + return new DoctrineDriver; + } +} diff --git a/vendor/illuminate/database/Query/Builder.php b/vendor/illuminate/database/Query/Builder.php new file mode 100755 index 0000000..a4a9a23 --- /dev/null +++ b/vendor/illuminate/database/Query/Builder.php @@ -0,0 +1,2073 @@ + [], + 'join' => [], + 'where' => [], + 'having' => [], + 'order' => [], + 'union' => [], + ]; + + /** + * An aggregate function and column to be run. + * + * @var array + */ + public $aggregate; + + /** + * The columns that should be returned. + * + * @var array + */ + public $columns; + + /** + * Indicates if the query returns distinct results. + * + * @var bool + */ + public $distinct = false; + + /** + * The table which the query is targeting. + * + * @var string + */ + public $from; + + /** + * The table joins for the query. + * + * @var array + */ + public $joins; + + /** + * The where constraints for the query. + * + * @var array + */ + public $wheres; + + /** + * The groupings for the query. + * + * @var array + */ + public $groups; + + /** + * The having constraints for the query. + * + * @var array + */ + public $havings; + + /** + * The orderings for the query. + * + * @var array + */ + public $orders; + + /** + * The maximum number of records to return. + * + * @var int + */ + public $limit; + + /** + * The number of records to skip. + * + * @var int + */ + public $offset; + + /** + * The query union statements. + * + * @var array + */ + public $unions; + + /** + * The maximum number of union records to return. + * + * @var int + */ + public $unionLimit; + + /** + * The number of union records to skip. + * + * @var int + */ + public $unionOffset; + + /** + * The orderings for the union query. + * + * @var array + */ + public $unionOrders; + + /** + * Indicates whether row locking is being used. + * + * @var string|bool + */ + public $lock; + + /** + * The field backups currently in use. + * + * @var array + */ + protected $backups = []; + + /** + * The binding backups currently in use. + * + * @var array + */ + protected $bindingBackups = []; + + /** + * All of the available clause operators. + * + * @var array + */ + protected $operators = [ + '=', '<', '>', '<=', '>=', '<>', '!=', + 'like', 'like binary', 'not like', 'between', 'ilike', + '&', '|', '^', '<<', '>>', + 'rlike', 'regexp', 'not regexp', + '~', '~*', '!~', '!~*', 'similar to', + 'not similar to', + ]; + + /** + * Whether use write pdo for select. + * + * @var bool + */ + protected $useWritePdo = false; + + /** + * Create a new query builder instance. + * + * @param \Illuminate\Database\ConnectionInterface $connection + * @param \Illuminate\Database\Query\Grammars\Grammar $grammar + * @param \Illuminate\Database\Query\Processors\Processor $processor + * @return void + */ + public function __construct(ConnectionInterface $connection, + Grammar $grammar, + Processor $processor) + { + $this->grammar = $grammar; + $this->processor = $processor; + $this->connection = $connection; + } + + /** + * Set the columns to be selected. + * + * @param array|mixed $columns + * @return $this + */ + public function select($columns = ['*']) + { + $this->columns = is_array($columns) ? $columns : func_get_args(); + + return $this; + } + + /** + * Add a new "raw" select expression to the query. + * + * @param string $expression + * @param array $bindings + * @return \Illuminate\Database\Query\Builder|static + */ + public function selectRaw($expression, array $bindings = []) + { + $this->addSelect(new Expression($expression)); + + if ($bindings) { + $this->addBinding($bindings, 'select'); + } + + return $this; + } + + /** + * Add a subselect expression to the query. + * + * @param \Closure|\Illuminate\Database\Query\Builder|string $query + * @param string $as + * @return \Illuminate\Database\Query\Builder|static + */ + public function selectSub($query, $as) + { + if ($query instanceof Closure) { + $callback = $query; + + $callback($query = $this->newQuery()); + } + + if ($query instanceof self) { + $bindings = $query->getBindings(); + + $query = $query->toSql(); + } elseif (is_string($query)) { + $bindings = []; + } else { + throw new InvalidArgumentException; + } + + return $this->selectRaw('('.$query.') as '.$this->grammar->wrap($as), $bindings); + } + + /** + * Add a new select column to the query. + * + * @param array|mixed $column + * @return $this + */ + public function addSelect($column) + { + $column = is_array($column) ? $column : func_get_args(); + + $this->columns = array_merge((array) $this->columns, $column); + + return $this; + } + + /** + * Force the query to only return distinct results. + * + * @return $this + */ + public function distinct() + { + $this->distinct = true; + + return $this; + } + + /** + * Set the table which the query is targeting. + * + * @param string $table + * @return $this + */ + public function from($table) + { + $this->from = $table; + + return $this; + } + + /** + * Add a join clause to the query. + * + * @param string $table + * @param string $one + * @param string $operator + * @param string $two + * @param string $type + * @param bool $where + * @return $this + */ + public function join($table, $one, $operator = null, $two = null, $type = 'inner', $where = false) + { + // If the first "column" of the join is really a Closure instance the developer + // is trying to build a join with a complex "on" clause containing more than + // one condition, so we'll add the join and call a Closure with the query. + if ($one instanceof Closure) { + $join = new JoinClause($type, $table); + + call_user_func($one, $join); + + $this->joins[] = $join; + + $this->addBinding($join->bindings, 'join'); + } + + // If the column is simply a string, we can assume the join simply has a basic + // "on" clause with a single condition. So we will just build the join with + // this simple join clauses attached to it. There is not a join callback. + else { + $join = new JoinClause($type, $table); + + $this->joins[] = $join->on( + $one, $operator, $two, 'and', $where + ); + + $this->addBinding($join->bindings, 'join'); + } + + return $this; + } + + /** + * Add a "join where" clause to the query. + * + * @param string $table + * @param string $one + * @param string $operator + * @param string $two + * @param string $type + * @return \Illuminate\Database\Query\Builder|static + */ + public function joinWhere($table, $one, $operator, $two, $type = 'inner') + { + return $this->join($table, $one, $operator, $two, $type, true); + } + + /** + * Add a left join to the query. + * + * @param string $table + * @param string $first + * @param string $operator + * @param string $second + * @return \Illuminate\Database\Query\Builder|static + */ + public function leftJoin($table, $first, $operator = null, $second = null) + { + return $this->join($table, $first, $operator, $second, 'left'); + } + + /** + * Add a "join where" clause to the query. + * + * @param string $table + * @param string $one + * @param string $operator + * @param string $two + * @return \Illuminate\Database\Query\Builder|static + */ + public function leftJoinWhere($table, $one, $operator, $two) + { + return $this->joinWhere($table, $one, $operator, $two, 'left'); + } + + /** + * Add a right join to the query. + * + * @param string $table + * @param string $first + * @param string $operator + * @param string $second + * @return \Illuminate\Database\Query\Builder|static + */ + public function rightJoin($table, $first, $operator = null, $second = null) + { + return $this->join($table, $first, $operator, $second, 'right'); + } + + /** + * Add a "right join where" clause to the query. + * + * @param string $table + * @param string $one + * @param string $operator + * @param string $two + * @return \Illuminate\Database\Query\Builder|static + */ + public function rightJoinWhere($table, $one, $operator, $two) + { + return $this->joinWhere($table, $one, $operator, $two, 'right'); + } + + /** + * Add a basic where clause to the query. + * + * @param string|array|\Closure $column + * @param string $operator + * @param mixed $value + * @param string $boolean + * @return $this + * + * @throws \InvalidArgumentException + */ + public function where($column, $operator = null, $value = null, $boolean = 'and') + { + // If the column is an array, we will assume it is an array of key-value pairs + // and can add them each as a where clause. We will maintain the boolean we + // received when the method was called and pass it into the nested where. + if (is_array($column)) { + return $this->whereNested(function ($query) use ($column) { + foreach ($column as $key => $value) { + $query->where($key, '=', $value); + } + }, $boolean); + } + + // Here we will make some assumptions about the operator. If only 2 values are + // passed to the method, we will assume that the operator is an equals sign + // and keep going. Otherwise, we'll require the operator to be passed in. + if (func_num_args() == 2) { + list($value, $operator) = [$operator, '=']; + } elseif ($this->invalidOperatorAndValue($operator, $value)) { + throw new InvalidArgumentException('Illegal operator and value combination.'); + } + + // If the columns is actually a Closure instance, we will assume the developer + // wants to begin a nested where statement which is wrapped in parenthesis. + // We'll add that Closure to the query then return back out immediately. + if ($column instanceof Closure) { + return $this->whereNested($column, $boolean); + } + + // If the given operator is not found in the list of valid operators we will + // assume that the developer is just short-cutting the '=' operators and + // we will set the operators to '=' and set the values appropriately. + if (! in_array(strtolower($operator), $this->operators, true)) { + list($value, $operator) = [$operator, '=']; + } + + // If the value is a Closure, it means the developer is performing an entire + // sub-select within the query and we will need to compile the sub-select + // within the where clause to get the appropriate query record results. + if ($value instanceof Closure) { + return $this->whereSub($column, $operator, $value, $boolean); + } + + // If the value is "null", we will just assume the developer wants to add a + // where null clause to the query. So, we will allow a short-cut here to + // that method for convenience so the developer doesn't have to check. + if (is_null($value)) { + return $this->whereNull($column, $boolean, $operator != '='); + } + + // Now that we are working with just a simple query we can put the elements + // in our array and add the query binding to our array of bindings that + // will be bound to each SQL statements when it is finally executed. + $type = 'Basic'; + + $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean'); + + if (! $value instanceof Expression) { + $this->addBinding($value, 'where'); + } + + return $this; + } + + /** + * Add an "or where" clause to the query. + * + * @param string $column + * @param string $operator + * @param mixed $value + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhere($column, $operator = null, $value = null) + { + return $this->where($column, $operator, $value, 'or'); + } + + /** + * Determine if the given operator and value combination is legal. + * + * @param string $operator + * @param mixed $value + * @return bool + */ + protected function invalidOperatorAndValue($operator, $value) + { + $isOperator = in_array($operator, $this->operators); + + return $isOperator && $operator != '=' && is_null($value); + } + + /** + * Add a raw where clause to the query. + * + * @param string $sql + * @param array $bindings + * @param string $boolean + * @return $this + */ + public function whereRaw($sql, array $bindings = [], $boolean = 'and') + { + $type = 'raw'; + + $this->wheres[] = compact('type', 'sql', 'boolean'); + + $this->addBinding($bindings, 'where'); + + return $this; + } + + /** + * Add a raw or where clause to the query. + * + * @param string $sql + * @param array $bindings + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereRaw($sql, array $bindings = []) + { + return $this->whereRaw($sql, $bindings, 'or'); + } + + /** + * Add a where between statement to the query. + * + * @param string $column + * @param array $values + * @param string $boolean + * @param bool $not + * @return $this + */ + public function whereBetween($column, array $values, $boolean = 'and', $not = false) + { + $type = 'between'; + + $this->wheres[] = compact('column', 'type', 'boolean', 'not'); + + $this->addBinding($values, 'where'); + + return $this; + } + + /** + * Add an or where between statement to the query. + * + * @param string $column + * @param array $values + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereBetween($column, array $values) + { + return $this->whereBetween($column, $values, 'or'); + } + + /** + * Add a where not between statement to the query. + * + * @param string $column + * @param array $values + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereNotBetween($column, array $values, $boolean = 'and') + { + return $this->whereBetween($column, $values, $boolean, true); + } + + /** + * Add an or where not between statement to the query. + * + * @param string $column + * @param array $values + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereNotBetween($column, array $values) + { + return $this->whereNotBetween($column, $values, 'or'); + } + + /** + * Add a nested where statement to the query. + * + * @param \Closure $callback + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereNested(Closure $callback, $boolean = 'and') + { + // To handle nested queries we'll actually create a brand new query instance + // and pass it off to the Closure that we have. The Closure can simply do + // do whatever it wants to a query then we will store it for compiling. + $query = $this->newQuery(); + + $query->from($this->from); + + call_user_func($callback, $query); + + return $this->addNestedWhereQuery($query, $boolean); + } + + /** + * Add another query builder as a nested where to the query builder. + * + * @param \Illuminate\Database\Query\Builder|static $query + * @param string $boolean + * @return $this + */ + public function addNestedWhereQuery($query, $boolean = 'and') + { + if (count($query->wheres)) { + $type = 'Nested'; + + $this->wheres[] = compact('type', 'query', 'boolean'); + + $this->addBinding($query->getBindings(), 'where'); + } + + return $this; + } + + /** + * Add a full sub-select to the query. + * + * @param string $column + * @param string $operator + * @param \Closure $callback + * @param string $boolean + * @return $this + */ + protected function whereSub($column, $operator, Closure $callback, $boolean) + { + $type = 'Sub'; + + $query = $this->newQuery(); + + // Once we have the query instance we can simply execute it so it can add all + // of the sub-select's conditions to itself, and then we can cache it off + // in the array of where clauses for the "main" parent query instance. + call_user_func($callback, $query); + + $this->wheres[] = compact('type', 'column', 'operator', 'query', 'boolean'); + + $this->addBinding($query->getBindings(), 'where'); + + return $this; + } + + /** + * Add an exists clause to the query. + * + * @param \Closure $callback + * @param string $boolean + * @param bool $not + * @return $this + */ + public function whereExists(Closure $callback, $boolean = 'and', $not = false) + { + $type = $not ? 'NotExists' : 'Exists'; + + $query = $this->newQuery(); + + // Similar to the sub-select clause, we will create a new query instance so + // the developer may cleanly specify the entire exists query and we will + // compile the whole thing in the grammar and insert it into the SQL. + call_user_func($callback, $query); + + $this->wheres[] = compact('type', 'operator', 'query', 'boolean'); + + $this->addBinding($query->getBindings(), 'where'); + + return $this; + } + + /** + * Add an or exists clause to the query. + * + * @param \Closure $callback + * @param bool $not + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereExists(Closure $callback, $not = false) + { + return $this->whereExists($callback, 'or', $not); + } + + /** + * Add a where not exists clause to the query. + * + * @param \Closure $callback + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereNotExists(Closure $callback, $boolean = 'and') + { + return $this->whereExists($callback, $boolean, true); + } + + /** + * Add a where not exists clause to the query. + * + * @param \Closure $callback + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereNotExists(Closure $callback) + { + return $this->orWhereExists($callback, true); + } + + /** + * Add a "where in" clause to the query. + * + * @param string $column + * @param mixed $values + * @param string $boolean + * @param bool $not + * @return $this + */ + public function whereIn($column, $values, $boolean = 'and', $not = false) + { + $type = $not ? 'NotIn' : 'In'; + + // If the value of the where in clause is actually a Closure, we will assume that + // the developer is using a full sub-select for this "in" statement, and will + // execute those Closures, then we can re-construct the entire sub-selects. + if ($values instanceof Closure) { + return $this->whereInSub($column, $values, $boolean, $not); + } + + if ($values instanceof Arrayable) { + $values = $values->toArray(); + } + + $this->wheres[] = compact('type', 'column', 'values', 'boolean'); + + $this->addBinding($values, 'where'); + + return $this; + } + + /** + * Add an "or where in" clause to the query. + * + * @param string $column + * @param mixed $values + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereIn($column, $values) + { + return $this->whereIn($column, $values, 'or'); + } + + /** + * Add a "where not in" clause to the query. + * + * @param string $column + * @param mixed $values + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereNotIn($column, $values, $boolean = 'and') + { + return $this->whereIn($column, $values, $boolean, true); + } + + /** + * Add an "or where not in" clause to the query. + * + * @param string $column + * @param mixed $values + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereNotIn($column, $values) + { + return $this->whereNotIn($column, $values, 'or'); + } + + /** + * Add a where in with a sub-select to the query. + * + * @param string $column + * @param \Closure $callback + * @param string $boolean + * @param bool $not + * @return $this + */ + protected function whereInSub($column, Closure $callback, $boolean, $not) + { + $type = $not ? 'NotInSub' : 'InSub'; + + // To create the exists sub-select, we will actually create a query and call the + // provided callback with the query so the developer may set any of the query + // conditions they want for the in clause, then we'll put it in this array. + call_user_func($callback, $query = $this->newQuery()); + + $this->wheres[] = compact('type', 'column', 'query', 'boolean'); + + $this->addBinding($query->getBindings(), 'where'); + + return $this; + } + + /** + * Add a "where null" clause to the query. + * + * @param string $column + * @param string $boolean + * @param bool $not + * @return $this + */ + public function whereNull($column, $boolean = 'and', $not = false) + { + $type = $not ? 'NotNull' : 'Null'; + + $this->wheres[] = compact('type', 'column', 'boolean'); + + return $this; + } + + /** + * Add an "or where null" clause to the query. + * + * @param string $column + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereNull($column) + { + return $this->whereNull($column, 'or'); + } + + /** + * Add a "where not null" clause to the query. + * + * @param string $column + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereNotNull($column, $boolean = 'and') + { + return $this->whereNull($column, $boolean, true); + } + + /** + * Add an "or where not null" clause to the query. + * + * @param string $column + * @return \Illuminate\Database\Query\Builder|static + */ + public function orWhereNotNull($column) + { + return $this->whereNotNull($column, 'or'); + } + + /** + * Add a "where date" statement to the query. + * + * @param string $column + * @param string $operator + * @param int $value + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereDate($column, $operator, $value, $boolean = 'and') + { + return $this->addDateBasedWhere('Date', $column, $operator, $value, $boolean); + } + + /** + * Add a "where day" statement to the query. + * + * @param string $column + * @param string $operator + * @param int $value + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereDay($column, $operator, $value, $boolean = 'and') + { + return $this->addDateBasedWhere('Day', $column, $operator, $value, $boolean); + } + + /** + * Add a "where month" statement to the query. + * + * @param string $column + * @param string $operator + * @param int $value + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereMonth($column, $operator, $value, $boolean = 'and') + { + return $this->addDateBasedWhere('Month', $column, $operator, $value, $boolean); + } + + /** + * Add a "where year" statement to the query. + * + * @param string $column + * @param string $operator + * @param int $value + * @param string $boolean + * @return \Illuminate\Database\Query\Builder|static + */ + public function whereYear($column, $operator, $value, $boolean = 'and') + { + return $this->addDateBasedWhere('Year', $column, $operator, $value, $boolean); + } + + /** + * Add a date based (year, month, day) statement to the query. + * + * @param string $type + * @param string $column + * @param string $operator + * @param int $value + * @param string $boolean + * @return $this + */ + protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and') + { + $this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value'); + + $this->addBinding($value, 'where'); + + return $this; + } + + /** + * Handles dynamic "where" clauses to the query. + * + * @param string $method + * @param string $parameters + * @return $this + */ + public function dynamicWhere($method, $parameters) + { + $finder = substr($method, 5); + + $segments = preg_split('/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE); + + // The connector variable will determine which connector will be used for the + // query condition. We will change it as we come across new boolean values + // in the dynamic method strings, which could contain a number of these. + $connector = 'and'; + + $index = 0; + + foreach ($segments as $segment) { + // If the segment is not a boolean connector, we can assume it is a column's name + // and we will add it to the query as a new constraint as a where clause, then + // we can keep iterating through the dynamic method string's segments again. + if ($segment != 'And' && $segment != 'Or') { + $this->addDynamic($segment, $connector, $parameters, $index); + + $index++; + } + + // Otherwise, we will store the connector so we know how the next where clause we + // find in the query should be connected to the previous ones, meaning we will + // have the proper boolean connector to connect the next where clause found. + else { + $connector = $segment; + } + } + + return $this; + } + + /** + * Add a single dynamic where clause statement to the query. + * + * @param string $segment + * @param string $connector + * @param array $parameters + * @param int $index + * @return void + */ + protected function addDynamic($segment, $connector, $parameters, $index) + { + // Once we have parsed out the columns and formatted the boolean operators we + // are ready to add it to this query as a where clause just like any other + // clause on the query. Then we'll increment the parameter index values. + $bool = strtolower($connector); + + $this->where(Str::snake($segment), '=', $parameters[$index], $bool); + } + + /** + * Add a "group by" clause to the query. + * + * @param array|string $column,... + * @return $this + */ + public function groupBy() + { + foreach (func_get_args() as $arg) { + $this->groups = array_merge((array) $this->groups, is_array($arg) ? $arg : [$arg]); + } + + return $this; + } + + /** + * Add a "having" clause to the query. + * + * @param string $column + * @param string $operator + * @param string $value + * @param string $boolean + * @return $this + */ + public function having($column, $operator = null, $value = null, $boolean = 'and') + { + $type = 'basic'; + + $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean'); + + if (! $value instanceof Expression) { + $this->addBinding($value, 'having'); + } + + return $this; + } + + /** + * Add a "or having" clause to the query. + * + * @param string $column + * @param string $operator + * @param string $value + * @return \Illuminate\Database\Query\Builder|static + */ + public function orHaving($column, $operator = null, $value = null) + { + return $this->having($column, $operator, $value, 'or'); + } + + /** + * Add a raw having clause to the query. + * + * @param string $sql + * @param array $bindings + * @param string $boolean + * @return $this + */ + public function havingRaw($sql, array $bindings = [], $boolean = 'and') + { + $type = 'raw'; + + $this->havings[] = compact('type', 'sql', 'boolean'); + + $this->addBinding($bindings, 'having'); + + return $this; + } + + /** + * Add a raw or having clause to the query. + * + * @param string $sql + * @param array $bindings + * @return \Illuminate\Database\Query\Builder|static + */ + public function orHavingRaw($sql, array $bindings = []) + { + return $this->havingRaw($sql, $bindings, 'or'); + } + + /** + * Add an "order by" clause to the query. + * + * @param string $column + * @param string $direction + * @return $this + */ + public function orderBy($column, $direction = 'asc') + { + $property = $this->unions ? 'unionOrders' : 'orders'; + $direction = strtolower($direction) == 'asc' ? 'asc' : 'desc'; + + $this->{$property}[] = compact('column', 'direction'); + + return $this; + } + + /** + * Add an "order by" clause for a timestamp to the query. + * + * @param string $column + * @return \Illuminate\Database\Query\Builder|static + */ + public function latest($column = 'created_at') + { + return $this->orderBy($column, 'desc'); + } + + /** + * Add an "order by" clause for a timestamp to the query. + * + * @param string $column + * @return \Illuminate\Database\Query\Builder|static + */ + public function oldest($column = 'created_at') + { + return $this->orderBy($column, 'asc'); + } + + /** + * Add a raw "order by" clause to the query. + * + * @param string $sql + * @param array $bindings + * @return $this + */ + public function orderByRaw($sql, $bindings = []) + { + $property = $this->unions ? 'unionOrders' : 'orders'; + + $type = 'raw'; + + $this->{$property}[] = compact('type', 'sql'); + + $this->addBinding($bindings, 'order'); + + return $this; + } + + /** + * Set the "offset" value of the query. + * + * @param int $value + * @return $this + */ + public function offset($value) + { + $property = $this->unions ? 'unionOffset' : 'offset'; + + $this->$property = max(0, $value); + + return $this; + } + + /** + * Alias to set the "offset" value of the query. + * + * @param int $value + * @return \Illuminate\Database\Query\Builder|static + */ + public function skip($value) + { + return $this->offset($value); + } + + /** + * Set the "limit" value of the query. + * + * @param int $value + * @return $this + */ + public function limit($value) + { + $property = $this->unions ? 'unionLimit' : 'limit'; + + if ($value > 0) { + $this->$property = $value; + } + + return $this; + } + + /** + * Alias to set the "limit" value of the query. + * + * @param int $value + * @return \Illuminate\Database\Query\Builder|static + */ + public function take($value) + { + return $this->limit($value); + } + + /** + * Set the limit and offset for a given page. + * + * @param int $page + * @param int $perPage + * @return \Illuminate\Database\Query\Builder|static + */ + public function forPage($page, $perPage = 15) + { + return $this->skip(($page - 1) * $perPage)->take($perPage); + } + + /** + * Add a union statement to the query. + * + * @param \Illuminate\Database\Query\Builder|\Closure $query + * @param bool $all + * @return \Illuminate\Database\Query\Builder|static + */ + public function union($query, $all = false) + { + if ($query instanceof Closure) { + call_user_func($query, $query = $this->newQuery()); + } + + $this->unions[] = compact('query', 'all'); + + $this->addBinding($query->getBindings(), 'union'); + + return $this; + } + + /** + * Add a union all statement to the query. + * + * @param \Illuminate\Database\Query\Builder|\Closure $query + * @return \Illuminate\Database\Query\Builder|static + */ + public function unionAll($query) + { + return $this->union($query, true); + } + + /** + * Lock the selected rows in the table. + * + * @param bool $value + * @return $this + */ + public function lock($value = true) + { + $this->lock = $value; + + if ($this->lock) { + $this->useWritePdo(); + } + + return $this; + } + + /** + * Lock the selected rows in the table for updating. + * + * @return \Illuminate\Database\Query\Builder + */ + public function lockForUpdate() + { + return $this->lock(true); + } + + /** + * Share lock the selected rows in the table. + * + * @return \Illuminate\Database\Query\Builder + */ + public function sharedLock() + { + return $this->lock(false); + } + + /** + * Get the SQL representation of the query. + * + * @return string + */ + public function toSql() + { + return $this->grammar->compileSelect($this); + } + + /** + * Execute a query for a single record by ID. + * + * @param int $id + * @param array $columns + * @return mixed|static + */ + public function find($id, $columns = ['*']) + { + return $this->where('id', '=', $id)->first($columns); + } + + /** + * Get a single column's value from the first result of a query. + * + * @param string $column + * @return mixed + */ + public function value($column) + { + $result = (array) $this->first([$column]); + + return count($result) > 0 ? reset($result) : null; + } + + /** + * Get a single column's value from the first result of a query. + * + * This is an alias for the "value" method. + * + * @param string $column + * @return mixed + * + * @deprecated since version 5.1. + */ + public function pluck($column) + { + return $this->value($column); + } + + /** + * Execute the query and get the first result. + * + * @param array $columns + * @return mixed|static + */ + public function first($columns = ['*']) + { + $results = $this->take(1)->get($columns); + + return count($results) > 0 ? reset($results) : null; + } + + /** + * Execute the query as a "select" statement. + * + * @param array $columns + * @return array|static[] + */ + public function get($columns = ['*']) + { + if (is_null($this->columns)) { + $this->columns = $columns; + } + + return $this->processor->processSelect($this, $this->runSelect()); + } + + /** + * Execute the query as a fresh "select" statement. + * + * @param array $columns + * @return array|static[] + * + * @deprecated since version 5.1. Use get instead. + */ + public function getFresh($columns = ['*']) + { + return $this->get($columns); + } + + /** + * Run the query as a "select" statement against the connection. + * + * @return array + */ + protected function runSelect() + { + return $this->connection->select($this->toSql(), $this->getBindings(), ! $this->useWritePdo); + } + + /** + * Paginate the given query into a simple paginator. + * + * @param int $perPage + * @param array $columns + * @param string $pageName + * @param int|null $page + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + */ + public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null) + { + $page = $page ?: Paginator::resolveCurrentPage($pageName); + + $total = $this->getCountForPagination($columns); + + $results = $this->forPage($page, $perPage)->get($columns); + + return new LengthAwarePaginator($results, $total, $perPage, $page, [ + 'path' => Paginator::resolveCurrentPath(), + 'pageName' => $pageName, + ]); + } + + /** + * Get a paginator only supporting simple next and previous links. + * + * This is more efficient on larger data-sets, etc. + * + * @param int $perPage + * @param array $columns + * @param string $pageName + * @return \Illuminate\Contracts\Pagination\Paginator + */ + public function simplePaginate($perPage = 15, $columns = ['*'], $pageName = 'page') + { + $page = Paginator::resolveCurrentPage($pageName); + + $this->skip(($page - 1) * $perPage)->take($perPage + 1); + + return new Paginator($this->get($columns), $perPage, $page, [ + 'path' => Paginator::resolveCurrentPath(), + 'pageName' => $pageName, + ]); + } + + /** + * Get the count of the total records for the paginator. + * + * @param array $columns + * @return int + */ + public function getCountForPagination($columns = ['*']) + { + $this->backupFieldsForCount(); + + $this->aggregate = ['function' => 'count', 'columns' => $this->clearSelectAliases($columns)]; + + $results = $this->get(); + + $this->aggregate = null; + + $this->restoreFieldsForCount(); + + if (isset($this->groups)) { + return count($results); + } + + return isset($results[0]) ? (int) array_change_key_case((array) $results[0])['aggregate'] : 0; + } + + /** + * Backup some fields for the pagination count. + * + * @return void + */ + protected function backupFieldsForCount() + { + foreach (['orders', 'limit', 'offset', 'columns'] as $field) { + $this->backups[$field] = $this->{$field}; + + $this->{$field} = null; + } + + foreach (['order', 'select'] as $key) { + $this->bindingBackups[$key] = $this->bindings[$key]; + + $this->bindings[$key] = []; + } + } + + /** + * Remove the column aliases since they will break count queries. + * + * @param array $columns + * @return array + */ + protected function clearSelectAliases(array $columns) + { + return array_map(function ($column) { + return is_string($column) && ($aliasPosition = strpos(strtolower($column), ' as ')) !== false + ? substr($column, 0, $aliasPosition) : $column; + }, $columns); + } + + /** + * Restore some fields after the pagination count. + * + * @return void + */ + protected function restoreFieldsForCount() + { + foreach (['orders', 'limit', 'offset', 'columns'] as $field) { + $this->{$field} = $this->backups[$field]; + } + + foreach (['order', 'select'] as $key) { + $this->bindings[$key] = $this->bindingBackups[$key]; + } + + $this->backups = []; + $this->bindingBackups = []; + } + + /** + * Chunk the results of the query. + * + * @param int $count + * @param callable $callback + * @return bool + */ + public function chunk($count, callable $callback) + { + $results = $this->forPage($page = 1, $count)->get(); + + while (count($results) > 0) { + // On each chunk result set, we will pass them to the callback and then let the + // developer take care of everything within the callback, which allows us to + // keep the memory low for spinning through large result sets for working. + if (call_user_func($callback, $results) === false) { + return false; + } + + $page++; + + $results = $this->forPage($page, $count)->get(); + } + + return true; + } + + /** + * Get an array with the values of a given column. + * + * @param string $column + * @param string $key + * @return array + */ + public function lists($column, $key = null) + { + $columns = $this->getListSelect($column, $key); + + $results = new Collection($this->get($columns)); + + return $results->pluck($columns[0], Arr::get($columns, 1))->all(); + } + + /** + * Get the columns that should be used in a list array. + * + * @param string $column + * @param string $key + * @return array + */ + protected function getListSelect($column, $key) + { + $select = is_null($key) ? [$column] : [$column, $key]; + + // If the selected column contains a "dot", we will remove it so that the list + // operation can run normally. Specifying the table is not needed, since we + // really want the names of the columns as it is in this resulting array. + return array_map(function ($column) { + $dot = strpos($column, '.'); + + return $dot === false ? $column : substr($column, $dot + 1); + }, $select); + } + + /** + * Concatenate values of a given column as a string. + * + * @param string $column + * @param string $glue + * @return string + */ + public function implode($column, $glue = '') + { + return implode($glue, $this->lists($column)); + } + + /** + * Determine if any rows exist for the current query. + * + * @return bool|null + */ + public function exists() + { + $sql = $this->grammar->compileExists($this); + + $results = $this->connection->select($sql, $this->getBindings(), ! $this->useWritePdo); + + if (isset($results[0])) { + $results = (array) $results[0]; + + return (bool) $results['exists']; + } + } + + /** + * Retrieve the "count" result of the query. + * + * @param string $columns + * @return int + */ + public function count($columns = '*') + { + if (! is_array($columns)) { + $columns = [$columns]; + } + + return (int) $this->aggregate(__FUNCTION__, $columns); + } + + /** + * Retrieve the minimum value of a given column. + * + * @param string $column + * @return float|int + */ + public function min($column) + { + return $this->aggregate(__FUNCTION__, [$column]); + } + + /** + * Retrieve the maximum value of a given column. + * + * @param string $column + * @return float|int + */ + public function max($column) + { + return $this->aggregate(__FUNCTION__, [$column]); + } + + /** + * Retrieve the sum of the values of a given column. + * + * @param string $column + * @return float|int + */ + public function sum($column) + { + $result = $this->aggregate(__FUNCTION__, [$column]); + + return $result ?: 0; + } + + /** + * Retrieve the average of the values of a given column. + * + * @param string $column + * @return float|int + */ + public function avg($column) + { + return $this->aggregate(__FUNCTION__, [$column]); + } + + /** + * Alias for the "avg" method. + * + * @param string $column + * @return float|int + */ + public function average($column) + { + return $this->avg($column); + } + + /** + * Execute an aggregate function on the database. + * + * @param string $function + * @param array $columns + * @return float|int + */ + public function aggregate($function, $columns = ['*']) + { + $this->aggregate = compact('function', 'columns'); + + $previousColumns = $this->columns; + + // We will also back up the select bindings since the select clause will be + // removed when performing the aggregate function. Once the query is run + // we will add the bindings back onto this query so they can get used. + $previousSelectBindings = $this->bindings['select']; + + $this->bindings['select'] = []; + + $results = $this->get($columns); + + // Once we have executed the query, we will reset the aggregate property so + // that more select queries can be executed against the database without + // the aggregate value getting in the way when the grammar builds it. + $this->aggregate = null; + + $this->columns = $previousColumns; + + $this->bindings['select'] = $previousSelectBindings; + + if (isset($results[0])) { + $result = array_change_key_case((array) $results[0]); + + return $result['aggregate']; + } + } + + /** + * Insert a new record into the database. + * + * @param array $values + * @return bool + */ + public function insert(array $values) + { + if (empty($values)) { + return true; + } + + // Since every insert gets treated like a batch insert, we will make sure the + // bindings are structured in a way that is convenient for building these + // inserts statements by verifying the elements are actually an array. + if (! is_array(reset($values))) { + $values = [$values]; + } + + // Since every insert gets treated like a batch insert, we will make sure the + // bindings are structured in a way that is convenient for building these + // inserts statements by verifying the elements are actually an array. + else { + foreach ($values as $key => $value) { + ksort($value); + $values[$key] = $value; + } + } + + // We'll treat every insert like a batch insert so we can easily insert each + // of the records into the database consistently. This will make it much + // easier on the grammars to just handle one type of record insertion. + $bindings = []; + + foreach ($values as $record) { + foreach ($record as $value) { + $bindings[] = $value; + } + } + + $sql = $this->grammar->compileInsert($this, $values); + + // Once we have compiled the insert statement's SQL we can execute it on the + // connection and return a result as a boolean success indicator as that + // is the same type of result returned by the raw connection instance. + $bindings = $this->cleanBindings($bindings); + + return $this->connection->insert($sql, $bindings); + } + + /** + * Insert a new record and get the value of the primary key. + * + * @param array $values + * @param string $sequence + * @return int + */ + public function insertGetId(array $values, $sequence = null) + { + $sql = $this->grammar->compileInsertGetId($this, $values, $sequence); + + $values = $this->cleanBindings($values); + + return $this->processor->processInsertGetId($this, $sql, $values, $sequence); + } + + /** + * Update a record in the database. + * + * @param array $values + * @return int + */ + public function update(array $values) + { + $bindings = array_values(array_merge($values, $this->getBindings())); + + $sql = $this->grammar->compileUpdate($this, $values); + + return $this->connection->update($sql, $this->cleanBindings($bindings)); + } + + /** + * Increment a column's value by a given amount. + * + * @param string $column + * @param int $amount + * @param array $extra + * @return int + */ + public function increment($column, $amount = 1, array $extra = []) + { + $wrapped = $this->grammar->wrap($column); + + $columns = array_merge([$column => $this->raw("$wrapped + $amount")], $extra); + + return $this->update($columns); + } + + /** + * Decrement a column's value by a given amount. + * + * @param string $column + * @param int $amount + * @param array $extra + * @return int + */ + public function decrement($column, $amount = 1, array $extra = []) + { + $wrapped = $this->grammar->wrap($column); + + $columns = array_merge([$column => $this->raw("$wrapped - $amount")], $extra); + + return $this->update($columns); + } + + /** + * Delete a record from the database. + * + * @param mixed $id + * @return int + */ + public function delete($id = null) + { + // If an ID is passed to the method, we will set the where clause to check + // the ID to allow developers to simply and quickly remove a single row + // from their database without manually specifying the where clauses. + if (! is_null($id)) { + $this->where('id', '=', $id); + } + + $sql = $this->grammar->compileDelete($this); + + return $this->connection->delete($sql, $this->getBindings()); + } + + /** + * Run a truncate statement on the table. + * + * @return void + */ + public function truncate() + { + foreach ($this->grammar->compileTruncate($this) as $sql => $bindings) { + $this->connection->statement($sql, $bindings); + } + } + + /** + * Get a new instance of the query builder. + * + * @return \Illuminate\Database\Query\Builder + */ + public function newQuery() + { + return new static($this->connection, $this->grammar, $this->processor); + } + + /** + * Merge an array of where clauses and bindings. + * + * @param array $wheres + * @param array $bindings + * @return void + */ + public function mergeWheres($wheres, $bindings) + { + $this->wheres = array_merge((array) $this->wheres, (array) $wheres); + + $this->bindings['where'] = array_values(array_merge($this->bindings['where'], (array) $bindings)); + } + + /** + * Remove all of the expressions from a list of bindings. + * + * @param array $bindings + * @return array + */ + protected function cleanBindings(array $bindings) + { + return array_values(array_filter($bindings, function ($binding) { + return ! $binding instanceof Expression; + })); + } + + /** + * Create a raw database expression. + * + * @param mixed $value + * @return \Illuminate\Database\Query\Expression + */ + public function raw($value) + { + return $this->connection->raw($value); + } + + /** + * Get the current query value bindings in a flattened array. + * + * @return array + */ + public function getBindings() + { + return Arr::flatten($this->bindings); + } + + /** + * Get the raw array of bindings. + * + * @return array + */ + public function getRawBindings() + { + return $this->bindings; + } + + /** + * Set the bindings on the query builder. + * + * @param array $bindings + * @param string $type + * @return $this + * + * @throws \InvalidArgumentException + */ + public function setBindings(array $bindings, $type = 'where') + { + if (! array_key_exists($type, $this->bindings)) { + throw new InvalidArgumentException("Invalid binding type: {$type}."); + } + + $this->bindings[$type] = $bindings; + + return $this; + } + + /** + * Add a binding to the query. + * + * @param mixed $value + * @param string $type + * @return $this + * + * @throws \InvalidArgumentException + */ + public function addBinding($value, $type = 'where') + { + if (! array_key_exists($type, $this->bindings)) { + throw new InvalidArgumentException("Invalid binding type: {$type}."); + } + + if (is_array($value)) { + $this->bindings[$type] = array_values(array_merge($this->bindings[$type], $value)); + } else { + $this->bindings[$type][] = $value; + } + + return $this; + } + + /** + * Merge an array of bindings into our bindings. + * + * @param \Illuminate\Database\Query\Builder $query + * @return $this + */ + public function mergeBindings(Builder $query) + { + $this->bindings = array_merge_recursive($this->bindings, $query->bindings); + + return $this; + } + + /** + * Get the database connection instance. + * + * @return \Illuminate\Database\ConnectionInterface + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Get the database query processor instance. + * + * @return \Illuminate\Database\Query\Processors\Processor + */ + public function getProcessor() + { + return $this->processor; + } + + /** + * Get the query grammar instance. + * + * @return \Illuminate\Database\Query\Grammars\Grammar + */ + public function getGrammar() + { + return $this->grammar; + } + + /** + * Use the write pdo for query. + * + * @return $this + */ + public function useWritePdo() + { + $this->useWritePdo = true; + + return $this; + } + + /** + * Handle dynamic method calls into the method. + * + * @param string $method + * @param array $parameters + * @return mixed + * + * @throws \BadMethodCallException + */ + public function __call($method, $parameters) + { + if (static::hasMacro($method)) { + return $this->macroCall($method, $parameters); + } + + if (Str::startsWith($method, 'where')) { + return $this->dynamicWhere($method, $parameters); + } + + $className = get_class($this); + + throw new BadMethodCallException("Call to undefined method {$className}::{$method}()"); + } +} diff --git a/vendor/illuminate/database/Query/Expression.php b/vendor/illuminate/database/Query/Expression.php new file mode 100755 index 0000000..de69029 --- /dev/null +++ b/vendor/illuminate/database/Query/Expression.php @@ -0,0 +1,44 @@ +value = $value; + } + + /** + * Get the value of the expression. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Get the value of the expression. + * + * @return string + */ + public function __toString() + { + return (string) $this->getValue(); + } +} diff --git a/vendor/illuminate/database/Query/Grammars/Grammar.php b/vendor/illuminate/database/Query/Grammars/Grammar.php new file mode 100755 index 0000000..6d5e161 --- /dev/null +++ b/vendor/illuminate/database/Query/Grammars/Grammar.php @@ -0,0 +1,800 @@ +columns)) { + $query->columns = ['*']; + } + + return trim($this->concatenate($this->compileComponents($query))); + } + + /** + * Compile the components necessary for a select clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @return array + */ + protected function compileComponents(Builder $query) + { + $sql = []; + + foreach ($this->selectComponents as $component) { + // To compile the query, we'll spin through each component of the query and + // see if that component exists. If it does we'll just call the compiler + // function for the component which is responsible for making the SQL. + if (! is_null($query->$component)) { + $method = 'compile'.ucfirst($component); + + $sql[$component] = $this->$method($query, $query->$component); + } + } + + return $sql; + } + + /** + * Compile an aggregated select clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $aggregate + * @return string + */ + protected function compileAggregate(Builder $query, $aggregate) + { + $column = $this->columnize($aggregate['columns']); + + // If the query has a "distinct" constraint and we're not asking for all columns + // we need to prepend "distinct" onto the column name so that the query takes + // it into account when it performs the aggregating operations on the data. + if ($query->distinct && $column !== '*') { + $column = 'distinct '.$column; + } + + return 'select '.$aggregate['function'].'('.$column.') as aggregate'; + } + + /** + * Compile the "select *" portion of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $columns + * @return string|null + */ + protected function compileColumns(Builder $query, $columns) + { + // If the query is actually performing an aggregating select, we will let that + // compiler handle the building of the select clauses, as it will need some + // more syntax that is best handled by that function to keep things neat. + if (! is_null($query->aggregate)) { + return; + } + + $select = $query->distinct ? 'select distinct ' : 'select '; + + return $select.$this->columnize($columns); + } + + /** + * Compile the "from" portion of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param string $table + * @return string + */ + protected function compileFrom(Builder $query, $table) + { + return 'from '.$this->wrapTable($table); + } + + /** + * Compile the "join" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $joins + * @return string + */ + protected function compileJoins(Builder $query, $joins) + { + $sql = []; + + foreach ($joins as $join) { + $table = $this->wrapTable($join->table); + + // First we need to build all of the "on" clauses for the join. There may be many + // of these clauses so we will need to iterate through each one and build them + // separately, then we'll join them up into a single string when we're done. + $clauses = []; + + foreach ($join->clauses as $clause) { + $clauses[] = $this->compileJoinConstraint($clause); + } + + // Once we have constructed the clauses, we'll need to take the boolean connector + // off of the first clause as it obviously will not be required on that clause + // because it leads the rest of the clauses, thus not requiring any boolean. + $clauses[0] = $this->removeLeadingBoolean($clauses[0]); + + $clauses = implode(' ', $clauses); + + $type = $join->type; + + // Once we have everything ready to go, we will just concatenate all the parts to + // build the final join statement SQL for the query and we can then return the + // final clause back to the callers as a single, stringified join statement. + $sql[] = "$type join $table on $clauses"; + } + + return implode(' ', $sql); + } + + /** + * Create a join clause constraint segment. + * + * @param array $clause + * @return string + */ + protected function compileJoinConstraint(array $clause) + { + $first = $this->wrap($clause['first']); + + if ($clause['where']) { + if ($clause['operator'] === 'in' || $clause['operator'] === 'not in') { + $second = '('.implode(', ', array_fill(0, $clause['second'], '?')).')'; + } else { + $second = '?'; + } + } else { + $second = $this->wrap($clause['second']); + } + + return "{$clause['boolean']} $first {$clause['operator']} $second"; + } + + /** + * Compile the "where" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + protected function compileWheres(Builder $query) + { + $sql = []; + + if (is_null($query->wheres)) { + return ''; + } + + // Each type of where clauses has its own compiler function which is responsible + // for actually creating the where clauses SQL. This helps keep the code nice + // and maintainable since each clause has a very small method that it uses. + foreach ($query->wheres as $where) { + $method = "where{$where['type']}"; + + $sql[] = $where['boolean'].' '.$this->$method($query, $where); + } + + // If we actually have some where clauses, we will strip off the first boolean + // operator, which is added by the query builders for convenience so we can + // avoid checking for the first clauses in each of the compilers methods. + if (count($sql) > 0) { + $sql = implode(' ', $sql); + + return 'where '.$this->removeLeadingBoolean($sql); + } + + return ''; + } + + /** + * Compile a nested where clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereNested(Builder $query, $where) + { + $nested = $where['query']; + + return '('.substr($this->compileWheres($nested), 6).')'; + } + + /** + * Compile a where condition with a sub-select. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereSub(Builder $query, $where) + { + $select = $this->compileSelect($where['query']); + + return $this->wrap($where['column']).' '.$where['operator']." ($select)"; + } + + /** + * Compile a basic where clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereBasic(Builder $query, $where) + { + $value = $this->parameter($where['value']); + + return $this->wrap($where['column']).' '.$where['operator'].' '.$value; + } + + /** + * Compile a "between" where clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereBetween(Builder $query, $where) + { + $between = $where['not'] ? 'not between' : 'between'; + + return $this->wrap($where['column']).' '.$between.' ? and ?'; + } + + /** + * Compile a where exists clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereExists(Builder $query, $where) + { + return 'exists ('.$this->compileSelect($where['query']).')'; + } + + /** + * Compile a where exists clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereNotExists(Builder $query, $where) + { + return 'not exists ('.$this->compileSelect($where['query']).')'; + } + + /** + * Compile a "where in" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereIn(Builder $query, $where) + { + if (empty($where['values'])) { + return '0 = 1'; + } + + $values = $this->parameterize($where['values']); + + return $this->wrap($where['column']).' in ('.$values.')'; + } + + /** + * Compile a "where not in" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereNotIn(Builder $query, $where) + { + if (empty($where['values'])) { + return '1 = 1'; + } + + $values = $this->parameterize($where['values']); + + return $this->wrap($where['column']).' not in ('.$values.')'; + } + + /** + * Compile a where in sub-select clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereInSub(Builder $query, $where) + { + $select = $this->compileSelect($where['query']); + + return $this->wrap($where['column']).' in ('.$select.')'; + } + + /** + * Compile a where not in sub-select clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereNotInSub(Builder $query, $where) + { + $select = $this->compileSelect($where['query']); + + return $this->wrap($where['column']).' not in ('.$select.')'; + } + + /** + * Compile a "where null" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereNull(Builder $query, $where) + { + return $this->wrap($where['column']).' is null'; + } + + /** + * Compile a "where not null" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereNotNull(Builder $query, $where) + { + return $this->wrap($where['column']).' is not null'; + } + + /** + * Compile a "where date" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereDate(Builder $query, $where) + { + return $this->dateBasedWhere('date', $query, $where); + } + + /** + * Compile a "where day" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereDay(Builder $query, $where) + { + return $this->dateBasedWhere('day', $query, $where); + } + + /** + * Compile a "where month" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereMonth(Builder $query, $where) + { + return $this->dateBasedWhere('month', $query, $where); + } + + /** + * Compile a "where year" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereYear(Builder $query, $where) + { + return $this->dateBasedWhere('year', $query, $where); + } + + /** + * Compile a date based where clause. + * + * @param string $type + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function dateBasedWhere($type, Builder $query, $where) + { + $value = $this->parameter($where['value']); + + return $type.'('.$this->wrap($where['column']).') '.$where['operator'].' '.$value; + } + + /** + * Compile a raw where clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereRaw(Builder $query, $where) + { + return $where['sql']; + } + + /** + * Compile the "group by" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $groups + * @return string + */ + protected function compileGroups(Builder $query, $groups) + { + return 'group by '.$this->columnize($groups); + } + + /** + * Compile the "having" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $havings + * @return string + */ + protected function compileHavings(Builder $query, $havings) + { + $sql = implode(' ', array_map([$this, 'compileHaving'], $havings)); + + return 'having '.$this->removeLeadingBoolean($sql); + } + + /** + * Compile a single having clause. + * + * @param array $having + * @return string + */ + protected function compileHaving(array $having) + { + // If the having clause is "raw", we can just return the clause straight away + // without doing any more processing on it. Otherwise, we will compile the + // clause into SQL based on the components that make it up from builder. + if ($having['type'] === 'raw') { + return $having['boolean'].' '.$having['sql']; + } + + return $this->compileBasicHaving($having); + } + + /** + * Compile a basic having clause. + * + * @param array $having + * @return string + */ + protected function compileBasicHaving($having) + { + $column = $this->wrap($having['column']); + + $parameter = $this->parameter($having['value']); + + return $having['boolean'].' '.$column.' '.$having['operator'].' '.$parameter; + } + + /** + * Compile the "order by" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $orders + * @return string + */ + protected function compileOrders(Builder $query, $orders) + { + return 'order by '.implode(', ', array_map(function ($order) { + if (isset($order['sql'])) { + return $order['sql']; + } + + return $this->wrap($order['column']).' '.$order['direction']; + }, $orders)); + } + + /** + * Compile the "limit" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param int $limit + * @return string + */ + protected function compileLimit(Builder $query, $limit) + { + return 'limit '.(int) $limit; + } + + /** + * Compile the "offset" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param int $offset + * @return string + */ + protected function compileOffset(Builder $query, $offset) + { + return 'offset '.(int) $offset; + } + + /** + * Compile the "union" queries attached to the main query. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + protected function compileUnions(Builder $query) + { + $sql = ''; + + foreach ($query->unions as $union) { + $sql .= $this->compileUnion($union); + } + + if (isset($query->unionOrders)) { + $sql .= ' '.$this->compileOrders($query, $query->unionOrders); + } + + if (isset($query->unionLimit)) { + $sql .= ' '.$this->compileLimit($query, $query->unionLimit); + } + + if (isset($query->unionOffset)) { + $sql .= ' '.$this->compileOffset($query, $query->unionOffset); + } + + return ltrim($sql); + } + + /** + * Compile a single union statement. + * + * @param array $union + * @return string + */ + protected function compileUnion(array $union) + { + $joiner = $union['all'] ? ' union all ' : ' union '; + + return $joiner.$union['query']->toSql(); + } + + /** + * Compile an exists statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + public function compileExists(Builder $query) + { + $select = $this->compileSelect($query); + + return "select exists($select) as {$this->wrap('exists')}"; + } + + /** + * Compile an insert statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileInsert(Builder $query, array $values) + { + // Essentially we will force every insert to be treated as a batch insert which + // simply makes creating the SQL easier for us since we can utilize the same + // basic routine regardless of an amount of records given to us to insert. + $table = $this->wrapTable($query->from); + + if (! is_array(reset($values))) { + $values = [$values]; + } + + $columns = $this->columnize(array_keys(reset($values))); + + // We need to build a list of parameter place-holders of values that are bound + // to the query. Each insert should have the exact same amount of parameter + // bindings so we will loop through the record and parameterize them all. + $parameters = []; + + foreach ($values as $record) { + $parameters[] = '('.$this->parameterize($record).')'; + } + + $parameters = implode(', ', $parameters); + + return "insert into $table ($columns) values $parameters"; + } + + /** + * Compile an insert and get ID statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @param string $sequence + * @return string + */ + public function compileInsertGetId(Builder $query, $values, $sequence) + { + return $this->compileInsert($query, $values); + } + + /** + * Compile an update statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileUpdate(Builder $query, $values) + { + $table = $this->wrapTable($query->from); + + // Each one of the columns in the update statements needs to be wrapped in the + // keyword identifiers, also a place-holder needs to be created for each of + // the values in the list of bindings so we can make the sets statements. + $columns = []; + + foreach ($values as $key => $value) { + $columns[] = $this->wrap($key).' = '.$this->parameter($value); + } + + $columns = implode(', ', $columns); + + // If the query has any "join" clauses, we will setup the joins on the builder + // and compile them so we can attach them to this update, as update queries + // can get join statements to attach to other tables when they're needed. + if (isset($query->joins)) { + $joins = ' '.$this->compileJoins($query, $query->joins); + } else { + $joins = ''; + } + + // Of course, update queries may also be constrained by where clauses so we'll + // need to compile the where clauses and attach it to the query so only the + // intended records are updated by the SQL statements we generate to run. + $where = $this->compileWheres($query); + + return trim("update {$table}{$joins} set $columns $where"); + } + + /** + * Compile a delete statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + public function compileDelete(Builder $query) + { + $table = $this->wrapTable($query->from); + + $where = is_array($query->wheres) ? $this->compileWheres($query) : ''; + + return trim("delete from $table ".$where); + } + + /** + * Compile a truncate table statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return array + */ + public function compileTruncate(Builder $query) + { + return ['truncate '.$this->wrapTable($query->from) => []]; + } + + /** + * Compile the lock into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param bool|string $value + * @return string + */ + protected function compileLock(Builder $query, $value) + { + return is_string($value) ? $value : ''; + } + + /** + * Determine if the grammar supports savepoints. + * + * @return bool + */ + public function supportsSavepoints() + { + return true; + } + + /** + * Compile the SQL statement to define a savepoint. + * + * @param string $name + * @return string + */ + public function compileSavepoint($name) + { + return 'SAVEPOINT '.$name; + } + + /** + * Compile the SQL statement to execute a savepoint rollback. + * + * @param string $name + * @return string + */ + public function compileSavepointRollBack($name) + { + return 'ROLLBACK TO SAVEPOINT '.$name; + } + + /** + * Concatenate an array of segments, removing empties. + * + * @param array $segments + * @return string + */ + protected function concatenate($segments) + { + return implode(' ', array_filter($segments, function ($value) { + return (string) $value !== ''; + })); + } + + /** + * Remove the leading boolean from a statement. + * + * @param string $value + * @return string + */ + protected function removeLeadingBoolean($value) + { + return preg_replace('/and |or /i', '', $value, 1); + } +} diff --git a/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php b/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php new file mode 100755 index 0000000..41f5c85 --- /dev/null +++ b/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php @@ -0,0 +1,141 @@ +unions) { + $sql = '('.$sql.') '.$this->compileUnions($query); + } + + return $sql; + } + + /** + * Compile a single union statement. + * + * @param array $union + * @return string + */ + protected function compileUnion(array $union) + { + $joiner = $union['all'] ? ' union all ' : ' union '; + + return $joiner.'('.$union['query']->toSql().')'; + } + + /** + * Compile the lock into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param bool|string $value + * @return string + */ + protected function compileLock(Builder $query, $value) + { + if (is_string($value)) { + return $value; + } + + return $value ? 'for update' : 'lock in share mode'; + } + + /** + * Compile an update statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileUpdate(Builder $query, $values) + { + $sql = parent::compileUpdate($query, $values); + + if (isset($query->orders)) { + $sql .= ' '.$this->compileOrders($query, $query->orders); + } + + if (isset($query->limit)) { + $sql .= ' '.$this->compileLimit($query, $query->limit); + } + + return rtrim($sql); + } + + /** + * Compile a delete statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + public function compileDelete(Builder $query) + { + $table = $this->wrapTable($query->from); + + $where = is_array($query->wheres) ? $this->compileWheres($query) : ''; + + if (isset($query->joins)) { + $joins = ' '.$this->compileJoins($query, $query->joins); + + $sql = trim("delete $table from {$table}{$joins} $where"); + } else { + $sql = trim("delete from $table $where"); + } + + if (isset($query->orders)) { + $sql .= ' '.$this->compileOrders($query, $query->orders); + } + + if (isset($query->limit)) { + $sql .= ' '.$this->compileLimit($query, $query->limit); + } + + return $sql; + } + + /** + * Wrap a single string in keyword identifiers. + * + * @param string $value + * @return string + */ + protected function wrapValue($value) + { + if ($value === '*') { + return $value; + } + + return '`'.str_replace('`', '``', $value).'`'; + } +} diff --git a/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php b/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php new file mode 100755 index 0000000..2c8f553 --- /dev/null +++ b/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php @@ -0,0 +1,180 @@ +', '<=', '>=', '<>', '!=', + 'like', 'not like', 'between', 'ilike', + '&', '|', '#', '<<', '>>', + ]; + + /** + * Compile the lock into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param bool|string $value + * @return string + */ + protected function compileLock(Builder $query, $value) + { + if (is_string($value)) { + return $value; + } + + return $value ? 'for update' : 'for share'; + } + + /** + * Compile an update statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileUpdate(Builder $query, $values) + { + $table = $this->wrapTable($query->from); + + // Each one of the columns in the update statements needs to be wrapped in the + // keyword identifiers, also a place-holder needs to be created for each of + // the values in the list of bindings so we can make the sets statements. + $columns = $this->compileUpdateColumns($values); + + $from = $this->compileUpdateFrom($query); + + $where = $this->compileUpdateWheres($query); + + return trim("update {$table} set {$columns}{$from} $where"); + } + + /** + * Compile the columns for the update statement. + * + * @param array $values + * @return string + */ + protected function compileUpdateColumns($values) + { + $columns = []; + + // When gathering the columns for an update statement, we'll wrap each of the + // columns and convert it to a parameter value. Then we will concatenate a + // list of the columns that can be added into this update query clauses. + foreach ($values as $key => $value) { + $columns[] = $this->wrap($key).' = '.$this->parameter($value); + } + + return implode(', ', $columns); + } + + /** + * Compile the "from" clause for an update with a join. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string|null + */ + protected function compileUpdateFrom(Builder $query) + { + if (! isset($query->joins)) { + return ''; + } + + $froms = []; + + // When using Postgres, updates with joins list the joined tables in the from + // clause, which is different than other systems like MySQL. Here, we will + // compile out the tables that are joined and add them to a from clause. + foreach ($query->joins as $join) { + $froms[] = $this->wrapTable($join->table); + } + + if (count($froms) > 0) { + return ' from '.implode(', ', $froms); + } + } + + /** + * Compile the additional where clauses for updates with joins. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + protected function compileUpdateWheres(Builder $query) + { + $baseWhere = $this->compileWheres($query); + + if (! isset($query->joins)) { + return $baseWhere; + } + + // Once we compile the join constraints, we will either use them as the where + // clause or append them to the existing base where clauses. If we need to + // strip the leading boolean we will do so when using as the only where. + $joinWhere = $this->compileUpdateJoinWheres($query); + + if (trim($baseWhere) == '') { + return 'where '.$this->removeLeadingBoolean($joinWhere); + } + + return $baseWhere.' '.$joinWhere; + } + + /** + * Compile the "join" clauses for an update. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + protected function compileUpdateJoinWheres(Builder $query) + { + $joinWheres = []; + + // Here we will just loop through all of the join constraints and compile them + // all out then implode them. This should give us "where" like syntax after + // everything has been built and then we will join it to the real wheres. + foreach ($query->joins as $join) { + foreach ($join->clauses as $clause) { + $joinWheres[] = $this->compileJoinConstraint($clause); + } + } + + return implode(' ', $joinWheres); + } + + /** + * Compile an insert and get ID statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @param string $sequence + * @return string + */ + public function compileInsertGetId(Builder $query, $values, $sequence) + { + if (is_null($sequence)) { + $sequence = 'id'; + } + + return $this->compileInsert($query, $values).' returning '.$this->wrap($sequence); + } + + /** + * Compile a truncate table statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return array + */ + public function compileTruncate(Builder $query) + { + return ['truncate '.$this->wrapTable($query->from).' restart identity' => []]; + } +} diff --git a/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php b/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php new file mode 100755 index 0000000..dd1f9c0 --- /dev/null +++ b/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php @@ -0,0 +1,140 @@ +', '<=', '>=', '<>', '!=', + 'like', 'not like', 'between', 'ilike', + '&', '|', '<<', '>>', + ]; + + /** + * Compile an insert statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileInsert(Builder $query, array $values) + { + // Essentially we will force every insert to be treated as a batch insert which + // simply makes creating the SQL easier for us since we can utilize the same + // basic routine regardless of an amount of records given to us to insert. + $table = $this->wrapTable($query->from); + + if (! is_array(reset($values))) { + $values = [$values]; + } + + // If there is only one record being inserted, we will just use the usual query + // grammar insert builder because no special syntax is needed for the single + // row inserts in SQLite. However, if there are multiples, we'll continue. + if (count($values) == 1) { + return parent::compileInsert($query, reset($values)); + } + + $names = $this->columnize(array_keys(reset($values))); + + $columns = []; + + // SQLite requires us to build the multi-row insert as a listing of select with + // unions joining them together. So we'll build out this list of columns and + // then join them all together with select unions to complete the queries. + foreach (array_keys(reset($values)) as $column) { + $columns[] = '? as '.$this->wrap($column); + } + + $columns = array_fill(0, count($values), implode(', ', $columns)); + + return "insert into $table ($names) select ".implode(' union all select ', $columns); + } + + /** + * Compile a truncate table statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return array + */ + public function compileTruncate(Builder $query) + { + $sql = ['delete from sqlite_sequence where name = ?' => [$query->from]]; + + $sql['delete from '.$this->wrapTable($query->from)] = []; + + return $sql; + } + + /** + * Compile a "where date" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereDate(Builder $query, $where) + { + return $this->dateBasedWhere('%Y-%m-%d', $query, $where); + } + + /** + * Compile a "where day" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereDay(Builder $query, $where) + { + return $this->dateBasedWhere('%d', $query, $where); + } + + /** + * Compile a "where month" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereMonth(Builder $query, $where) + { + return $this->dateBasedWhere('%m', $query, $where); + } + + /** + * Compile a "where year" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereYear(Builder $query, $where) + { + return $this->dateBasedWhere('%Y', $query, $where); + } + + /** + * Compile a date based where clause. + * + * @param string $type + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function dateBasedWhere($type, Builder $query, $where) + { + $value = str_pad($where['value'], 2, '0', STR_PAD_LEFT); + + $value = $this->parameter($value); + + return 'strftime(\''.$type.'\', '.$this->wrap($where['column']).') '.$where['operator'].' '.$value; + } +} diff --git a/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php b/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php new file mode 100755 index 0000000..04f7b9d --- /dev/null +++ b/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php @@ -0,0 +1,267 @@ +', '<=', '>=', '!<', '!>', '<>', '!=', + 'like', 'not like', 'between', 'ilike', + '&', '&=', '|', '|=', '^', '^=', + ]; + + /** + * Compile a select query into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + public function compileSelect(Builder $query) + { + if (is_null($query->columns)) { + $query->columns = ['*']; + } + + $components = $this->compileComponents($query); + + // If an offset is present on the query, we will need to wrap the query in + // a big "ANSI" offset syntax block. This is very nasty compared to the + // other database systems but is necessary for implementing features. + if ($query->offset > 0) { + return $this->compileAnsiOffset($query, $components); + } + + return $this->concatenate($components); + } + + /** + * Compile the "select *" portion of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $columns + * @return string|null + */ + protected function compileColumns(Builder $query, $columns) + { + if (! is_null($query->aggregate)) { + return; + } + + $select = $query->distinct ? 'select distinct ' : 'select '; + + // If there is a limit on the query, but not an offset, we will add the top + // clause to the query, which serves as a "limit" type clause within the + // SQL Server system similar to the limit keywords available in MySQL. + if ($query->limit > 0 && $query->offset <= 0) { + $select .= 'top '.$query->limit.' '; + } + + return $select.$this->columnize($columns); + } + + /** + * Compile the "from" portion of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param string $table + * @return string + */ + protected function compileFrom(Builder $query, $table) + { + $from = parent::compileFrom($query, $table); + + if (is_string($query->lock)) { + return $from.' '.$query->lock; + } + + if (! is_null($query->lock)) { + return $from.' with(rowlock,'.($query->lock ? 'updlock,' : '').'holdlock)'; + } + + return $from; + } + + /** + * Create a full ANSI offset clause for the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $components + * @return string + */ + protected function compileAnsiOffset(Builder $query, $components) + { + // An ORDER BY clause is required to make this offset query work, so if one does + // not exist we'll just create a dummy clause to trick the database and so it + // does not complain about the queries for not having an "order by" clause. + if (! isset($components['orders'])) { + $components['orders'] = 'order by (select 0)'; + } + + // We need to add the row number to the query so we can compare it to the offset + // and limit values given for the statements. So we will add an expression to + // the "select" that will give back the row numbers on each of the records. + $orderings = $components['orders']; + + $components['columns'] .= $this->compileOver($orderings); + + unset($components['orders']); + + // Next we need to calculate the constraints that should be placed on the query + // to get the right offset and limit from our query but if there is no limit + // set we will just handle the offset only since that is all that matters. + $constraint = $this->compileRowConstraint($query); + + $sql = $this->concatenate($components); + + // We are now ready to build the final SQL query so we'll create a common table + // expression from the query and get the records with row numbers within our + // given limit and offset value that we just put on as a query constraint. + return $this->compileTableExpression($sql, $constraint); + } + + /** + * Compile the over statement for a table expression. + * + * @param string $orderings + * @return string + */ + protected function compileOver($orderings) + { + return ", row_number() over ({$orderings}) as row_num"; + } + + /** + * Compile the limit / offset row constraint for a query. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + protected function compileRowConstraint($query) + { + $start = $query->offset + 1; + + if ($query->limit > 0) { + $finish = $query->offset + $query->limit; + + return "between {$start} and {$finish}"; + } + + return ">= {$start}"; + } + + /** + * Compile a common table expression for a query. + * + * @param string $sql + * @param string $constraint + * @return string + */ + protected function compileTableExpression($sql, $constraint) + { + return "select * from ({$sql}) as temp_table where row_num {$constraint}"; + } + + /** + * Compile the "limit" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param int $limit + * @return string + */ + protected function compileLimit(Builder $query, $limit) + { + return ''; + } + + /** + * Compile the "offset" portions of the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param int $offset + * @return string + */ + protected function compileOffset(Builder $query, $offset) + { + return ''; + } + + /** + * Compile a truncate table statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return array + */ + public function compileTruncate(Builder $query) + { + return ['truncate table '.$this->wrapTable($query->from) => []]; + } + + /** + * Compile an exists statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @return string + */ + public function compileExists(Builder $query) + { + $select = $this->compileSelect($query); + + return "select cast(case when exists($select) then 1 else 0 end as bit) as {$this->wrap('exists')}"; + } + + /** + * Compile a "where date" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereDate(Builder $query, $where) + { + $value = $this->parameter($where['value']); + + return 'cast('.$this->wrap($where['column']).' as date) '.$where['operator'].' '.$value; + } + + /** + * Determine if the grammar supports savepoints. + * + * @return bool + */ + public function supportsSavepoints() + { + return false; + } + + /** + * Get the format for database stored dates. + * + * @return string + */ + public function getDateFormat() + { + return 'Y-m-d H:i:s.000'; + } + + /** + * Wrap a single string in keyword identifiers. + * + * @param string $value + * @return string + */ + protected function wrapValue($value) + { + if ($value === '*') { + return $value; + } + + return '['.str_replace(']', ']]', $value).']'; + } +} diff --git a/vendor/illuminate/database/Query/JoinClause.php b/vendor/illuminate/database/Query/JoinClause.php new file mode 100755 index 0000000..fc1a657 --- /dev/null +++ b/vendor/illuminate/database/Query/JoinClause.php @@ -0,0 +1,215 @@ +type = $type; + $this->table = $table; + } + + /** + * Add an "on" clause to the join. + * + * On clauses can be chained, e.g. + * + * $join->on('contacts.user_id', '=', 'users.id') + * ->on('contacts.info_id', '=', 'info.id') + * + * will produce the following SQL: + * + * on `contacts`.`user_id` = `users`.`id` and `contacts`.`info_id` = `info`.`id` + * + * @param string $first + * @param string $operator + * @param string $second + * @param string $boolean + * @param bool $where + * @return $this + */ + public function on($first, $operator, $second, $boolean = 'and', $where = false) + { + if ($where) { + $this->bindings[] = $second; + } + + if ($where && ($operator === 'in' || $operator === 'not in') && is_array($second)) { + $second = count($second); + } + + $this->clauses[] = compact('first', 'operator', 'second', 'boolean', 'where'); + + return $this; + } + + /** + * Add an "or on" clause to the join. + * + * @param string $first + * @param string $operator + * @param string $second + * @return \Illuminate\Database\Query\JoinClause + */ + public function orOn($first, $operator, $second) + { + return $this->on($first, $operator, $second, 'or'); + } + + /** + * Add an "on where" clause to the join. + * + * @param string $first + * @param string $operator + * @param string $second + * @param string $boolean + * @return \Illuminate\Database\Query\JoinClause + */ + public function where($first, $operator, $second, $boolean = 'and') + { + return $this->on($first, $operator, $second, $boolean, true); + } + + /** + * Add an "or on where" clause to the join. + * + * @param string $first + * @param string $operator + * @param string $second + * @return \Illuminate\Database\Query\JoinClause + */ + public function orWhere($first, $operator, $second) + { + return $this->on($first, $operator, $second, 'or', true); + } + + /** + * Add an "on where is null" clause to the join. + * + * @param string $column + * @param string $boolean + * @return \Illuminate\Database\Query\JoinClause + */ + public function whereNull($column, $boolean = 'and') + { + return $this->on($column, 'is', new Expression('null'), $boolean, false); + } + + /** + * Add an "or on where is null" clause to the join. + * + * @param string $column + * @return \Illuminate\Database\Query\JoinClause + */ + public function orWhereNull($column) + { + return $this->whereNull($column, 'or'); + } + + /** + * Add an "on where is not null" clause to the join. + * + * @param string $column + * @param string $boolean + * @return \Illuminate\Database\Query\JoinClause + */ + public function whereNotNull($column, $boolean = 'and') + { + return $this->on($column, 'is', new Expression('not null'), $boolean, false); + } + + /** + * Add an "or on where is not null" clause to the join. + * + * @param string $column + * @return \Illuminate\Database\Query\JoinClause + */ + public function orWhereNotNull($column) + { + return $this->whereNotNull($column, 'or'); + } + + /** + * Add an "on where in (...)" clause to the join. + * + * @param string $column + * @param array $values + * @return \Illuminate\Database\Query\JoinClause + */ + public function whereIn($column, array $values) + { + return $this->on($column, 'in', $values, 'and', true); + } + + /** + * Add an "on where not in (...)" clause to the join. + * + * @param string $column + * @param array $values + * @return \Illuminate\Database\Query\JoinClause + */ + public function whereNotIn($column, array $values) + { + return $this->on($column, 'not in', $values, 'and', true); + } + + /** + * Add an "or on where in (...)" clause to the join. + * + * @param string $column + * @param array $values + * @return \Illuminate\Database\Query\JoinClause + */ + public function orWhereIn($column, array $values) + { + return $this->on($column, 'in', $values, 'or', true); + } + + /** + * Add an "or on where not in (...)" clause to the join. + * + * @param string $column + * @param array $values + * @return \Illuminate\Database\Query\JoinClause + */ + public function orWhereNotIn($column, array $values) + { + return $this->on($column, 'not in', $values, 'or', true); + } +} diff --git a/vendor/illuminate/database/Query/Processors/MySqlProcessor.php b/vendor/illuminate/database/Query/Processors/MySqlProcessor.php new file mode 100644 index 0000000..a8a9a6c --- /dev/null +++ b/vendor/illuminate/database/Query/Processors/MySqlProcessor.php @@ -0,0 +1,23 @@ +column_name; + }; + + return array_map($mapping, $results); + } +} diff --git a/vendor/illuminate/database/Query/Processors/PostgresProcessor.php b/vendor/illuminate/database/Query/Processors/PostgresProcessor.php new file mode 100755 index 0000000..ab350cb --- /dev/null +++ b/vendor/illuminate/database/Query/Processors/PostgresProcessor.php @@ -0,0 +1,47 @@ +getConnection()->selectFromWriteConnection($sql, $values); + + $sequence = $sequence ?: 'id'; + + $result = (array) $results[0]; + + $id = $result[$sequence]; + + return is_numeric($id) ? (int) $id : $id; + } + + /** + * Process the results of a column listing query. + * + * @param array $results + * @return array + */ + public function processColumnListing($results) + { + $mapping = function ($r) { + $r = (object) $r; + + return $r->column_name; + }; + + return array_map($mapping, $results); + } +} diff --git a/vendor/illuminate/database/Query/Processors/Processor.php b/vendor/illuminate/database/Query/Processors/Processor.php new file mode 100755 index 0000000..f78429f --- /dev/null +++ b/vendor/illuminate/database/Query/Processors/Processor.php @@ -0,0 +1,49 @@ +getConnection()->insert($sql, $values); + + $id = $query->getConnection()->getPdo()->lastInsertId($sequence); + + return is_numeric($id) ? (int) $id : $id; + } + + /** + * Process the results of a column listing query. + * + * @param array $results + * @return array + */ + public function processColumnListing($results) + { + return $results; + } +} diff --git a/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php b/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php new file mode 100644 index 0000000..e4a8950 --- /dev/null +++ b/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php @@ -0,0 +1,23 @@ +name; + }; + + return array_map($mapping, $results); + } +} diff --git a/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php b/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php new file mode 100755 index 0000000..447a9c6 --- /dev/null +++ b/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php @@ -0,0 +1,43 @@ +getConnection()->insert($sql, $values); + + $id = $query->getConnection()->getPdo()->lastInsertId(); + + return is_numeric($id) ? (int) $id : $id; + } + + /** + * Process the results of a column listing query. + * + * @param array $results + * @return array + */ + public function processColumnListing($results) + { + $mapping = function ($r) { + $r = (object) $r; + + return $r->name; + }; + + return array_map($mapping, $results); + } +} diff --git a/vendor/illuminate/database/QueryException.php b/vendor/illuminate/database/QueryException.php new file mode 100644 index 0000000..922570b --- /dev/null +++ b/vendor/illuminate/database/QueryException.php @@ -0,0 +1,78 @@ +sql = $sql; + $this->bindings = $bindings; + $this->previous = $previous; + $this->code = $previous->getCode(); + $this->message = $this->formatMessage($sql, $bindings, $previous); + + if ($previous instanceof PDOException) { + $this->errorInfo = $previous->errorInfo; + } + } + + /** + * Format the SQL error message. + * + * @param string $sql + * @param array $bindings + * @param \Exception $previous + * @return string + */ + protected function formatMessage($sql, $bindings, $previous) + { + return $previous->getMessage().' (SQL: '.str_replace_array('\?', $bindings, $sql).')'; + } + + /** + * Get the SQL for the query. + * + * @return string + */ + public function getSql() + { + return $this->sql; + } + + /** + * Get the bindings for the query. + * + * @return array + */ + public function getBindings() + { + return $this->bindings; + } +} diff --git a/vendor/illuminate/database/README.md b/vendor/illuminate/database/README.md new file mode 100755 index 0000000..1675a93 --- /dev/null +++ b/vendor/illuminate/database/README.md @@ -0,0 +1,70 @@ +## Illuminate Database + +The Illuminate Database component is a full database toolkit for PHP, providing an expressive query builder, ActiveRecord style ORM, and schema builder. It currently supports MySQL, Postgres, SQL Server, and SQLite. It also serves as the database layer of the Laravel PHP framework. + +### Usage Instructions + +First, create a new "Capsule" manager instance. Capsule aims to make configuring the library for usage outside of the Laravel framework as easy as possible. + +```PHP +use Illuminate\Database\Capsule\Manager as Capsule; + +$capsule = new Capsule; + +$capsule->addConnection([ + 'driver' => 'mysql', + 'host' => 'localhost', + 'database' => 'database', + 'username' => 'root', + 'password' => 'password', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', +]); + +// Set the event dispatcher used by Eloquent models... (optional) +use Illuminate\Events\Dispatcher; +use Illuminate\Container\Container; +$capsule->setEventDispatcher(new Dispatcher(new Container)); + +// Make this Capsule instance available globally via static methods... (optional) +$capsule->setAsGlobal(); + +// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher()) +$capsule->bootEloquent(); +``` + +> `composer require "illuminate/events"` required when you need to use observers with Eloquent. + +Once the Capsule instance has been registered. You may use it like so: + +**Using The Query Builder** + +```PHP +$users = Capsule::table('users')->where('votes', '>', 100)->get(); +``` +Other core methods may be accessed directly from the Capsule in the same manner as from the DB facade: +```PHP +$results = Capsule::select('select * from users where id = ?', array(1)); +``` + +**Using The Schema Builder** + +```PHP +Capsule::schema()->create('users', function($table) +{ + $table->increments('id'); + $table->string('email')->unique(); + $table->timestamps(); +}); +``` + +**Using The Eloquent ORM** + +```PHP +class User extends Illuminate\Database\Eloquent\Model {} + +$users = User::where('votes', '>', 1)->get(); +``` + +For further documentation on using the various database facilities this library provides, consult the [Laravel framework documentation](http://laravel.com/docs). diff --git a/vendor/illuminate/database/SQLiteConnection.php b/vendor/illuminate/database/SQLiteConnection.php new file mode 100755 index 0000000..b32786c --- /dev/null +++ b/vendor/illuminate/database/SQLiteConnection.php @@ -0,0 +1,51 @@ +withTablePrefix(new QueryGrammar); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\SQLiteGrammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\SQLiteProcessor + */ + protected function getDefaultPostProcessor() + { + return new SQLiteProcessor; + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Doctrine\DBAL\Driver\PDOSqlite\Driver + */ + protected function getDoctrineDriver() + { + return new DoctrineDriver; + } +} diff --git a/vendor/illuminate/database/Schema/Blueprint.php b/vendor/illuminate/database/Schema/Blueprint.php new file mode 100755 index 0000000..69412e4 --- /dev/null +++ b/vendor/illuminate/database/Schema/Blueprint.php @@ -0,0 +1,1023 @@ +table = $table; + + if (! is_null($callback)) { + $callback($this); + } + } + + /** + * Execute the blueprint against the database. + * + * @param \Illuminate\Database\Connection $connection + * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar + * @return void + */ + public function build(Connection $connection, Grammar $grammar) + { + foreach ($this->toSql($connection, $grammar) as $statement) { + $connection->statement($statement); + } + } + + /** + * Get the raw SQL statements for the blueprint. + * + * @param \Illuminate\Database\Connection $connection + * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar + * @return array + */ + public function toSql(Connection $connection, Grammar $grammar) + { + $this->addImpliedCommands(); + + $statements = []; + + // Each type of command has a corresponding compiler function on the schema + // grammar which is used to build the necessary SQL statements to build + // the blueprint element, so we'll just call that compilers function. + foreach ($this->commands as $command) { + $method = 'compile'.ucfirst($command->name); + + if (method_exists($grammar, $method)) { + if (! is_null($sql = $grammar->$method($this, $command, $connection))) { + $statements = array_merge($statements, (array) $sql); + } + } + } + + return $statements; + } + + /** + * Add the commands that are implied by the blueprint. + * + * @return void + */ + protected function addImpliedCommands() + { + if (count($this->getAddedColumns()) > 0 && ! $this->creating()) { + array_unshift($this->commands, $this->createCommand('add')); + } + + if (count($this->getChangedColumns()) > 0 && ! $this->creating()) { + array_unshift($this->commands, $this->createCommand('change')); + } + + $this->addFluentIndexes(); + } + + /** + * Add the index commands fluently specified on columns. + * + * @return void + */ + protected function addFluentIndexes() + { + foreach ($this->columns as $column) { + foreach (['primary', 'unique', 'index'] as $index) { + // If the index has been specified on the given column, but is simply + // equal to "true" (boolean), no name has been specified for this + // index, so we will simply call the index methods without one. + if ($column->$index === true) { + $this->$index($column->name); + + continue 2; + } + + // If the index has been specified on the column and it is something + // other than boolean true, we will assume a name was provided on + // the index specification, and pass in the name to the method. + elseif (isset($column->$index)) { + $this->$index($column->name, $column->$index); + + continue 2; + } + } + } + } + + /** + * Determine if the blueprint has a create command. + * + * @return bool + */ + protected function creating() + { + foreach ($this->commands as $command) { + if ($command->name == 'create') { + return true; + } + } + + return false; + } + + /** + * Indicate that the table needs to be created. + * + * @return \Illuminate\Support\Fluent + */ + public function create() + { + return $this->addCommand('create'); + } + + /** + * Indicate that the table should be dropped. + * + * @return \Illuminate\Support\Fluent + */ + public function drop() + { + return $this->addCommand('drop'); + } + + /** + * Indicate that the table should be dropped if it exists. + * + * @return \Illuminate\Support\Fluent + */ + public function dropIfExists() + { + return $this->addCommand('dropIfExists'); + } + + /** + * Indicate that the given columns should be dropped. + * + * @param array|mixed $columns + * @return \Illuminate\Support\Fluent + */ + public function dropColumn($columns) + { + $columns = is_array($columns) ? $columns : (array) func_get_args(); + + return $this->addCommand('dropColumn', compact('columns')); + } + + /** + * Indicate that the given columns should be renamed. + * + * @param string $from + * @param string $to + * @return \Illuminate\Support\Fluent + */ + public function renameColumn($from, $to) + { + return $this->addCommand('renameColumn', compact('from', 'to')); + } + + /** + * Indicate that the given primary key should be dropped. + * + * @param string|array $index + * @return \Illuminate\Support\Fluent + */ + public function dropPrimary($index = null) + { + return $this->dropIndexCommand('dropPrimary', 'primary', $index); + } + + /** + * Indicate that the given unique key should be dropped. + * + * @param string|array $index + * @return \Illuminate\Support\Fluent + */ + public function dropUnique($index) + { + return $this->dropIndexCommand('dropUnique', 'unique', $index); + } + + /** + * Indicate that the given index should be dropped. + * + * @param string|array $index + * @return \Illuminate\Support\Fluent + */ + public function dropIndex($index) + { + return $this->dropIndexCommand('dropIndex', 'index', $index); + } + + /** + * Indicate that the given foreign key should be dropped. + * + * @param string $index + * @return \Illuminate\Support\Fluent + */ + public function dropForeign($index) + { + return $this->dropIndexCommand('dropForeign', 'foreign', $index); + } + + /** + * Indicate that the timestamp columns should be dropped. + * + * @return void + */ + public function dropTimestamps() + { + $this->dropColumn('created_at', 'updated_at'); + } + + /** + * Indicate that the timestamp columns should be dropped. + * + * @return void + */ + public function dropTimestampsTz() + { + $this->dropTimestamps(); + } + + /** + * Indicate that the soft delete column should be dropped. + * + * @return void + */ + public function dropSoftDeletes() + { + $this->dropColumn('deleted_at'); + } + + /** + * Indicate that the remember token column should be dropped. + * + * @return void + */ + public function dropRememberToken() + { + $this->dropColumn('remember_token'); + } + + /** + * Rename the table to a given name. + * + * @param string $to + * @return \Illuminate\Support\Fluent + */ + public function rename($to) + { + return $this->addCommand('rename', compact('to')); + } + + /** + * Specify the primary key(s) for the table. + * + * @param string|array $columns + * @param string $name + * @return \Illuminate\Support\Fluent + */ + public function primary($columns, $name = null) + { + return $this->indexCommand('primary', $columns, $name); + } + + /** + * Specify a unique index for the table. + * + * @param string|array $columns + * @param string $name + * @return \Illuminate\Support\Fluent + */ + public function unique($columns, $name = null) + { + return $this->indexCommand('unique', $columns, $name); + } + + /** + * Specify an index for the table. + * + * @param string|array $columns + * @param string $name + * @return \Illuminate\Support\Fluent + */ + public function index($columns, $name = null) + { + return $this->indexCommand('index', $columns, $name); + } + + /** + * Specify a foreign key for the table. + * + * @param string|array $columns + * @param string $name + * @return \Illuminate\Support\Fluent + */ + public function foreign($columns, $name = null) + { + return $this->indexCommand('foreign', $columns, $name); + } + + /** + * Create a new auto-incrementing integer (4-byte) column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function increments($column) + { + return $this->unsignedInteger($column, true); + } + + /** + * Create a new auto-incrementing small integer (2-byte) column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function smallIncrements($column) + { + return $this->unsignedSmallInteger($column, true); + } + + /** + * Create a new auto-incrementing medium integer (3-byte) column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function mediumIncrements($column) + { + return $this->unsignedMediumInteger($column, true); + } + + /** + * Create a new auto-incrementing big integer (8-byte) column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function bigIncrements($column) + { + return $this->unsignedBigInteger($column, true); + } + + /** + * Create a new char column on the table. + * + * @param string $column + * @param int $length + * @return \Illuminate\Support\Fluent + */ + public function char($column, $length = 255) + { + return $this->addColumn('char', $column, compact('length')); + } + + /** + * Create a new string column on the table. + * + * @param string $column + * @param int $length + * @return \Illuminate\Support\Fluent + */ + public function string($column, $length = 255) + { + return $this->addColumn('string', $column, compact('length')); + } + + /** + * Create a new text column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function text($column) + { + return $this->addColumn('text', $column); + } + + /** + * Create a new medium text column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function mediumText($column) + { + return $this->addColumn('mediumText', $column); + } + + /** + * Create a new long text column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function longText($column) + { + return $this->addColumn('longText', $column); + } + + /** + * Create a new integer (4-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @param bool $unsigned + * @return \Illuminate\Support\Fluent + */ + public function integer($column, $autoIncrement = false, $unsigned = false) + { + return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned')); + } + + /** + * Create a new tiny integer (1-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @param bool $unsigned + * @return \Illuminate\Support\Fluent + */ + public function tinyInteger($column, $autoIncrement = false, $unsigned = false) + { + return $this->addColumn('tinyInteger', $column, compact('autoIncrement', 'unsigned')); + } + + /** + * Create a new small integer (2-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @param bool $unsigned + * @return \Illuminate\Support\Fluent + */ + public function smallInteger($column, $autoIncrement = false, $unsigned = false) + { + return $this->addColumn('smallInteger', $column, compact('autoIncrement', 'unsigned')); + } + + /** + * Create a new medium integer (3-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @param bool $unsigned + * @return \Illuminate\Support\Fluent + */ + public function mediumInteger($column, $autoIncrement = false, $unsigned = false) + { + return $this->addColumn('mediumInteger', $column, compact('autoIncrement', 'unsigned')); + } + + /** + * Create a new big integer (8-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @param bool $unsigned + * @return \Illuminate\Support\Fluent + */ + public function bigInteger($column, $autoIncrement = false, $unsigned = false) + { + return $this->addColumn('bigInteger', $column, compact('autoIncrement', 'unsigned')); + } + + /** + * Create a new unsigned tiny integer (1-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @return \Illuminate\Support\Fluent + */ + public function unsignedTinyInteger($column, $autoIncrement = false) + { + return $this->tinyInteger($column, $autoIncrement, true); + } + + /** + * Create a new unsigned small integer (2-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @return \Illuminate\Support\Fluent + */ + public function unsignedSmallInteger($column, $autoIncrement = false) + { + return $this->smallInteger($column, $autoIncrement, true); + } + + /** + * Create a new unsigned medium integer (3-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @return \Illuminate\Support\Fluent + */ + public function unsignedMediumInteger($column, $autoIncrement = false) + { + return $this->mediumInteger($column, $autoIncrement, true); + } + + /** + * Create a new unsigned integer (4-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @return \Illuminate\Support\Fluent + */ + public function unsignedInteger($column, $autoIncrement = false) + { + return $this->integer($column, $autoIncrement, true); + } + + /** + * Create a new unsigned big integer (8-byte) column on the table. + * + * @param string $column + * @param bool $autoIncrement + * @return \Illuminate\Support\Fluent + */ + public function unsignedBigInteger($column, $autoIncrement = false) + { + return $this->bigInteger($column, $autoIncrement, true); + } + + /** + * Create a new float column on the table. + * + * @param string $column + * @param int $total + * @param int $places + * @return \Illuminate\Support\Fluent + */ + public function float($column, $total = 8, $places = 2) + { + return $this->addColumn('float', $column, compact('total', 'places')); + } + + /** + * Create a new double column on the table. + * + * @param string $column + * @param int|null $total + * @param int|null $places + * @return \Illuminate\Support\Fluent + */ + public function double($column, $total = null, $places = null) + { + return $this->addColumn('double', $column, compact('total', 'places')); + } + + /** + * Create a new decimal column on the table. + * + * @param string $column + * @param int $total + * @param int $places + * @return \Illuminate\Support\Fluent + */ + public function decimal($column, $total = 8, $places = 2) + { + return $this->addColumn('decimal', $column, compact('total', 'places')); + } + + /** + * Create a new boolean column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function boolean($column) + { + return $this->addColumn('boolean', $column); + } + + /** + * Create a new enum column on the table. + * + * @param string $column + * @param array $allowed + * @return \Illuminate\Support\Fluent + */ + public function enum($column, array $allowed) + { + return $this->addColumn('enum', $column, compact('allowed')); + } + + /** + * Create a new json column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function json($column) + { + return $this->addColumn('json', $column); + } + + /** + * Create a new jsonb column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function jsonb($column) + { + return $this->addColumn('jsonb', $column); + } + + /** + * Create a new date column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function date($column) + { + return $this->addColumn('date', $column); + } + + /** + * Create a new date-time column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function dateTime($column) + { + return $this->addColumn('dateTime', $column); + } + + /** + * Create a new date-time column (with time zone) on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function dateTimeTz($column) + { + return $this->addColumn('dateTimeTz', $column); + } + + /** + * Create a new time column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function time($column) + { + return $this->addColumn('time', $column); + } + + /** + * Create a new time column (with time zone) on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function timeTz($column) + { + return $this->addColumn('timeTz', $column); + } + + /** + * Create a new timestamp column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function timestamp($column) + { + return $this->addColumn('timestamp', $column); + } + + /** + * Create a new timestamp (with time zone) column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function timestampTz($column) + { + return $this->addColumn('timestampTz', $column); + } + + /** + * Add nullable creation and update timestamps to the table. + * + * @return void + */ + public function nullableTimestamps() + { + $this->timestamp('created_at')->nullable(); + + $this->timestamp('updated_at')->nullable(); + } + + /** + * Add creation and update timestamps to the table. + * + * @return void + */ + public function timestamps() + { + $this->timestamp('created_at'); + + $this->timestamp('updated_at'); + } + + /** + * Add creation and update timestampTz columns to the table. + * + * @return void + */ + public function timestampsTz() + { + $this->timestampTz('created_at'); + + $this->timestampTz('updated_at'); + } + + /** + * Add a "deleted at" timestamp for the table. + * + * @return \Illuminate\Support\Fluent + */ + public function softDeletes() + { + return $this->timestamp('deleted_at')->nullable(); + } + + /** + * Create a new binary column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function binary($column) + { + return $this->addColumn('binary', $column); + } + + /** + * Create a new uuid column on the table. + * + * @param string $column + * @return \Illuminate\Support\Fluent + */ + public function uuid($column) + { + return $this->addColumn('uuid', $column); + } + + /** + * Add the proper columns for a polymorphic table. + * + * @param string $name + * @param string|null $indexName + * @return void + */ + public function morphs($name, $indexName = null) + { + $this->unsignedInteger("{$name}_id"); + + $this->string("{$name}_type"); + + $this->index(["{$name}_id", "{$name}_type"], $indexName); + } + + /** + * Adds the `remember_token` column to the table. + * + * @return \Illuminate\Support\Fluent + */ + public function rememberToken() + { + return $this->string('remember_token', 100)->nullable(); + } + + /** + * Create a new drop index command on the blueprint. + * + * @param string $command + * @param string $type + * @param string|array $index + * @return \Illuminate\Support\Fluent + */ + protected function dropIndexCommand($command, $type, $index) + { + $columns = []; + + // If the given "index" is actually an array of columns, the developer means + // to drop an index merely by specifying the columns involved without the + // conventional name, so we will build the index name from the columns. + if (is_array($index)) { + $columns = $index; + + $index = $this->createIndexName($type, $columns); + } + + return $this->indexCommand($command, $columns, $index); + } + + /** + * Add a new index command to the blueprint. + * + * @param string $type + * @param string|array $columns + * @param string $index + * @return \Illuminate\Support\Fluent + */ + protected function indexCommand($type, $columns, $index) + { + $columns = (array) $columns; + + // If no name was specified for this index, we will create one using a basic + // convention of the table name, followed by the columns, followed by an + // index type, such as primary or index, which makes the index unique. + if (is_null($index)) { + $index = $this->createIndexName($type, $columns); + } + + return $this->addCommand($type, compact('index', 'columns')); + } + + /** + * Create a default index name for the table. + * + * @param string $type + * @param array $columns + * @return string + */ + protected function createIndexName($type, array $columns) + { + $index = strtolower($this->table.'_'.implode('_', $columns).'_'.$type); + + return str_replace(['-', '.'], '_', $index); + } + + /** + * Add a new column to the blueprint. + * + * @param string $type + * @param string $name + * @param array $parameters + * @return \Illuminate\Support\Fluent + */ + protected function addColumn($type, $name, array $parameters = []) + { + $attributes = array_merge(compact('type', 'name'), $parameters); + + $this->columns[] = $column = new Fluent($attributes); + + return $column; + } + + /** + * Remove a column from the schema blueprint. + * + * @param string $name + * @return $this + */ + public function removeColumn($name) + { + $this->columns = array_values(array_filter($this->columns, function ($c) use ($name) { + return $c['attributes']['name'] != $name; + })); + + return $this; + } + + /** + * Add a new command to the blueprint. + * + * @param string $name + * @param array $parameters + * @return \Illuminate\Support\Fluent + */ + protected function addCommand($name, array $parameters = []) + { + $this->commands[] = $command = $this->createCommand($name, $parameters); + + return $command; + } + + /** + * Create a new Fluent command. + * + * @param string $name + * @param array $parameters + * @return \Illuminate\Support\Fluent + */ + protected function createCommand($name, array $parameters = []) + { + return new Fluent(array_merge(compact('name'), $parameters)); + } + + /** + * Get the table the blueprint describes. + * + * @return string + */ + public function getTable() + { + return $this->table; + } + + /** + * Get the columns on the blueprint. + * + * @return array + */ + public function getColumns() + { + return $this->columns; + } + + /** + * Get the commands on the blueprint. + * + * @return array + */ + public function getCommands() + { + return $this->commands; + } + + /** + * Get the columns on the blueprint that should be added. + * + * @return array + */ + public function getAddedColumns() + { + return array_filter($this->columns, function ($column) { + return ! $column->change; + }); + } + + /** + * Get the columns on the blueprint that should be changed. + * + * @return array + */ + public function getChangedColumns() + { + return array_filter($this->columns, function ($column) { + return ! ! $column->change; + }); + } +} diff --git a/vendor/illuminate/database/Schema/Builder.php b/vendor/illuminate/database/Schema/Builder.php new file mode 100755 index 0000000..5e10b42 --- /dev/null +++ b/vendor/illuminate/database/Schema/Builder.php @@ -0,0 +1,243 @@ +connection = $connection; + $this->grammar = $connection->getSchemaGrammar(); + } + + /** + * Determine if the given table exists. + * + * @param string $table + * @return bool + */ + public function hasTable($table) + { + $sql = $this->grammar->compileTableExists(); + + $table = $this->connection->getTablePrefix().$table; + + return count($this->connection->select($sql, [$table])) > 0; + } + + /** + * Determine if the given table has a given column. + * + * @param string $table + * @param string $column + * @return bool + */ + public function hasColumn($table, $column) + { + $column = strtolower($column); + + return in_array($column, array_map('strtolower', $this->getColumnListing($table))); + } + + /** + * Determine if the given table has given columns. + * + * @param string $table + * @param array $columns + * @return bool + */ + public function hasColumns($table, array $columns) + { + $tableColumns = array_map('strtolower', $this->getColumnListing($table)); + + foreach ($columns as $column) { + if (! in_array(strtolower($column), $tableColumns)) { + return false; + } + } + + return true; + } + + /** + * Get the column listing for a given table. + * + * @param string $table + * @return array + */ + public function getColumnListing($table) + { + $table = $this->connection->getTablePrefix().$table; + + $results = $this->connection->select($this->grammar->compileColumnExists($table)); + + return $this->connection->getPostProcessor()->processColumnListing($results); + } + + /** + * Modify a table on the schema. + * + * @param string $table + * @param \Closure $callback + * @return \Illuminate\Database\Schema\Blueprint + */ + public function table($table, Closure $callback) + { + $this->build($this->createBlueprint($table, $callback)); + } + + /** + * Create a new table on the schema. + * + * @param string $table + * @param \Closure $callback + * @return \Illuminate\Database\Schema\Blueprint + */ + public function create($table, Closure $callback) + { + $blueprint = $this->createBlueprint($table); + + $blueprint->create(); + + $callback($blueprint); + + $this->build($blueprint); + } + + /** + * Drop a table from the schema. + * + * @param string $table + * @return \Illuminate\Database\Schema\Blueprint + */ + public function drop($table) + { + $blueprint = $this->createBlueprint($table); + + $blueprint->drop(); + + $this->build($blueprint); + } + + /** + * Drop a table from the schema if it exists. + * + * @param string $table + * @return \Illuminate\Database\Schema\Blueprint + */ + public function dropIfExists($table) + { + $blueprint = $this->createBlueprint($table); + + $blueprint->dropIfExists(); + + $this->build($blueprint); + } + + /** + * Rename a table on the schema. + * + * @param string $from + * @param string $to + * @return \Illuminate\Database\Schema\Blueprint + */ + public function rename($from, $to) + { + $blueprint = $this->createBlueprint($from); + + $blueprint->rename($to); + + $this->build($blueprint); + } + + /** + * Execute the blueprint to build / modify the table. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @return void + */ + protected function build(Blueprint $blueprint) + { + $blueprint->build($this->connection, $this->grammar); + } + + /** + * Create a new command set with a Closure. + * + * @param string $table + * @param \Closure|null $callback + * @return \Illuminate\Database\Schema\Blueprint + */ + protected function createBlueprint($table, Closure $callback = null) + { + if (isset($this->resolver)) { + return call_user_func($this->resolver, $table, $callback); + } + + return new Blueprint($table, $callback); + } + + /** + * Get the database connection instance. + * + * @return \Illuminate\Database\Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Set the database connection instance. + * + * @param \Illuminate\Database\Connection $connection + * @return $this + */ + public function setConnection(Connection $connection) + { + $this->connection = $connection; + + return $this; + } + + /** + * Set the Schema Blueprint resolver callback. + * + * @param \Closure $resolver + * @return void + */ + public function blueprintResolver(Closure $resolver) + { + $this->resolver = $resolver; + } +} diff --git a/vendor/illuminate/database/Schema/Grammars/Grammar.php b/vendor/illuminate/database/Schema/Grammars/Grammar.php new file mode 100755 index 0000000..6eeff75 --- /dev/null +++ b/vendor/illuminate/database/Schema/Grammars/Grammar.php @@ -0,0 +1,459 @@ +getDoctrineSchemaManager(); + + $table = $this->getTablePrefix().$blueprint->getTable(); + + $column = $connection->getDoctrineColumn($table, $command->from); + + $tableDiff = $this->getRenamedDiff($blueprint, $command, $column, $schema); + + return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff); + } + + /** + * Get a new column instance with the new column name. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Doctrine\DBAL\Schema\Column $column + * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema + * @return \Doctrine\DBAL\Schema\TableDiff + */ + protected function getRenamedDiff(Blueprint $blueprint, Fluent $command, Column $column, SchemaManager $schema) + { + $tableDiff = $this->getDoctrineTableDiff($blueprint, $schema); + + return $this->setRenamedColumns($tableDiff, $command, $column); + } + + /** + * Set the renamed columns on the table diff. + * + * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff + * @param \Illuminate\Support\Fluent $command + * @param \Doctrine\DBAL\Schema\Column $column + * @return \Doctrine\DBAL\Schema\TableDiff + */ + protected function setRenamedColumns(TableDiff $tableDiff, Fluent $command, Column $column) + { + $newColumn = new Column($command->to, $column->getType(), $column->toArray()); + + $tableDiff->renamedColumns = [$command->from => $newColumn]; + + return $tableDiff; + } + + /** + * Compile a foreign key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileForeign(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + $on = $this->wrapTable($command->on); + + // We need to prepare several of the elements of the foreign key definition + // before we can create the SQL, such as wrapping the tables and convert + // an array of columns to comma-delimited strings for the SQL queries. + $columns = $this->columnize($command->columns); + + $onColumns = $this->columnize((array) $command->references); + + $sql = "alter table {$table} add constraint {$command->index} "; + + $sql .= "foreign key ({$columns}) references {$on} ({$onColumns})"; + + // Once we have the basic foreign key creation statement constructed we can + // build out the syntax for what should happen on an update or delete of + // the affected columns, which will get something like "cascade", etc. + if (! is_null($command->onDelete)) { + $sql .= " on delete {$command->onDelete}"; + } + + if (! is_null($command->onUpdate)) { + $sql .= " on update {$command->onUpdate}"; + } + + return $sql; + } + + /** + * Compile the blueprint's column definitions. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @return array + */ + protected function getColumns(Blueprint $blueprint) + { + $columns = []; + + foreach ($blueprint->getAddedColumns() as $column) { + // Each of the column types have their own compiler functions which are tasked + // with turning the column definition into its SQL format for this platform + // used by the connection. The column's modifiers are compiled and added. + $sql = $this->wrap($column).' '.$this->getType($column); + + $columns[] = $this->addModifiers($sql, $blueprint, $column); + } + + return $columns; + } + + /** + * Add the column modifiers to the definition. + * + * @param string $sql + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function addModifiers($sql, Blueprint $blueprint, Fluent $column) + { + foreach ($this->modifiers as $modifier) { + if (method_exists($this, $method = "modify{$modifier}")) { + $sql .= $this->{$method}($blueprint, $column); + } + } + + return $sql; + } + + /** + * Get the primary key command if it exists on the blueprint. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param string $name + * @return \Illuminate\Support\Fluent|null + */ + protected function getCommandByName(Blueprint $blueprint, $name) + { + $commands = $this->getCommandsByName($blueprint, $name); + + if (count($commands) > 0) { + return reset($commands); + } + } + + /** + * Get all of the commands with a given name. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param string $name + * @return array + */ + protected function getCommandsByName(Blueprint $blueprint, $name) + { + return array_filter($blueprint->getCommands(), function ($value) use ($name) { + return $value->name == $name; + }); + } + + /** + * Get the SQL for the column data type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function getType(Fluent $column) + { + return $this->{'type'.ucfirst($column->type)}($column); + } + + /** + * Add a prefix to an array of values. + * + * @param string $prefix + * @param array $values + * @return array + */ + public function prefixArray($prefix, array $values) + { + return array_map(function ($value) use ($prefix) { + return $prefix.' '.$value; + + }, $values); + } + + /** + * Wrap a table in keyword identifiers. + * + * @param mixed $table + * @return string + */ + public function wrapTable($table) + { + if ($table instanceof Blueprint) { + $table = $table->getTable(); + } + + return parent::wrapTable($table); + } + + /** + * {@inheritdoc} + */ + public function wrap($value, $prefixAlias = false) + { + if ($value instanceof Fluent) { + $value = $value->name; + } + + return parent::wrap($value, $prefixAlias); + } + + /** + * Format a value so that it can be used in "default" clauses. + * + * @param mixed $value + * @return string + */ + protected function getDefaultValue($value) + { + if ($value instanceof Expression) { + return $value; + } + + if (is_bool($value)) { + return "'".(int) $value."'"; + } + + return "'".strval($value)."'"; + } + + /** + * Create an empty Doctrine DBAL TableDiff from the Blueprint. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema + * @return \Doctrine\DBAL\Schema\TableDiff + */ + protected function getDoctrineTableDiff(Blueprint $blueprint, SchemaManager $schema) + { + $table = $this->getTablePrefix().$blueprint->getTable(); + + $tableDiff = new TableDiff($table); + + $tableDiff->fromTable = $schema->listTableDetails($table); + + return $tableDiff; + } + + /** + * Compile a change column command into a series of SQL statements. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array + */ + public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection) + { + if (! $connection->isDoctrineAvailable()) { + throw new RuntimeException(sprintf( + 'Changing columns for table "%s" requires Doctrine DBAL; install "doctrine/dbal".', + $blueprint->getTable() + )); + } + + $schema = $connection->getDoctrineSchemaManager(); + + $tableDiff = $this->getChangedDiff($blueprint, $schema); + + if ($tableDiff !== false) { + return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff); + } + + return []; + } + + /** + * Get the Doctrine table difference for the given changes. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema + * @return \Doctrine\DBAL\Schema\TableDiff|bool + */ + protected function getChangedDiff(Blueprint $blueprint, SchemaManager $schema) + { + $table = $schema->listTableDetails($this->getTablePrefix().$blueprint->getTable()); + + return (new Comparator)->diffTable($table, $this->getTableWithColumnChanges($blueprint, $table)); + } + + /** + * Get a copy of the given Doctrine table after making the column changes. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Doctrine\DBAL\Schema\Table $table + * @return \Doctrine\DBAL\Schema\TableDiff + */ + protected function getTableWithColumnChanges(Blueprint $blueprint, Table $table) + { + $table = clone $table; + + foreach ($blueprint->getChangedColumns() as $fluent) { + $column = $this->getDoctrineColumnForChange($table, $fluent); + + // Here we will spin through each fluent column definition and map it to the proper + // Doctrine column definitions - which is necessary because Laravel and Doctrine + // use some different terminology for various column attributes on the tables. + foreach ($fluent->getAttributes() as $key => $value) { + if (! is_null($option = $this->mapFluentOptionToDoctrine($key))) { + if (method_exists($column, $method = 'set'.ucfirst($option))) { + $column->{$method}($this->mapFluentValueToDoctrine($option, $value)); + } + } + } + } + + return $table; + } + + /** + * Get the Doctrine column instance for a column change. + * + * @param \Doctrine\DBAL\Schema\Table $table + * @param \Illuminate\Support\Fluent $fluent + * @return \Doctrine\DBAL\Schema\Column + */ + protected function getDoctrineColumnForChange(Table $table, Fluent $fluent) + { + return $table->changeColumn( + $fluent['name'], $this->getDoctrineColumnChangeOptions($fluent) + )->getColumn($fluent['name']); + } + + /** + * Get the Doctrine column change options. + * + * @param \Illuminate\Support\Fluent $fluent + * @return array + */ + protected function getDoctrineColumnChangeOptions(Fluent $fluent) + { + $options = ['type' => $this->getDoctrineColumnType($fluent['type'])]; + + if (in_array($fluent['type'], ['text', 'mediumText', 'longText'])) { + $options['length'] = $this->calculateDoctrineTextLength($fluent['type']); + } + + return $options; + } + + /** + * Get the doctrine column type. + * + * @param string $type + * @return \Doctrine\DBAL\Types\Type + */ + protected function getDoctrineColumnType($type) + { + $type = strtolower($type); + + switch ($type) { + case 'biginteger': + $type = 'bigint'; + break; + case 'smallinteger': + $type = 'smallint'; + break; + case 'mediumtext': + case 'longtext': + $type = 'text'; + break; + } + + return Type::getType($type); + } + + /** + * Calculate the proper column length to force the Doctrine text type. + * + * @param string $type + * @return int + */ + protected function calculateDoctrineTextLength($type) + { + switch ($type) { + case 'mediumText': + return 65535 + 1; + + case 'longText': + return 16777215 + 1; + + default: + return 255 + 1; + } + } + + /** + * Get the matching Doctrine option for a given Fluent attribute name. + * + * @param string $attribute + * @return string|null + */ + protected function mapFluentOptionToDoctrine($attribute) + { + switch ($attribute) { + case 'type': + case 'name': + return; + + case 'nullable': + return 'notnull'; + + case 'total': + return 'precision'; + + case 'places': + return 'scale'; + + default: + return $attribute; + } + } + + /** + * Get the matching Doctrine value for a given Fluent attribute. + * + * @param string $option + * @param mixed $value + * @return mixed + */ + protected function mapFluentValueToDoctrine($option, $value) + { + return $option == 'notnull' ? ! $value : $value; + } +} diff --git a/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php b/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php new file mode 100755 index 0000000..8157c36 --- /dev/null +++ b/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php @@ -0,0 +1,711 @@ +getColumns($blueprint)); + + $sql = 'create table '.$this->wrapTable($blueprint)." ($columns)"; + + // Once we have the primary SQL, we can add the encoding option to the SQL for + // the table. Then, we can check if a storage engine has been supplied for + // the table. If so, we will add the engine declaration to the SQL query. + $sql = $this->compileCreateEncoding($sql, $connection, $blueprint); + + if (isset($blueprint->engine)) { + $sql .= ' engine = '.$blueprint->engine; + } + + return $sql; + } + + /** + * Append the character set specifications to a command. + * + * @param string $sql + * @param \Illuminate\Database\Connection $connection + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @return string + */ + protected function compileCreateEncoding($sql, Connection $connection, Blueprint $blueprint) + { + if (isset($blueprint->charset)) { + $sql .= ' default character set '.$blueprint->charset; + } elseif (! is_null($charset = $connection->getConfig('charset'))) { + $sql .= ' default character set '.$charset; + } + + if (isset($blueprint->collation)) { + $sql .= ' collate '.$blueprint->collation; + } elseif (! is_null($collation = $connection->getConfig('collation'))) { + $sql .= ' collate '.$collation; + } + + return $sql; + } + + /** + * Compile an add column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileAdd(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + $columns = $this->prefixArray('add', $this->getColumns($blueprint)); + + return 'alter table '.$table.' '.implode(', ', $columns); + } + + /** + * Compile a primary key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compilePrimary(Blueprint $blueprint, Fluent $command) + { + $command->name(null); + + return $this->compileKey($blueprint, $command, 'primary key'); + } + + /** + * Compile a unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileUnique(Blueprint $blueprint, Fluent $command) + { + return $this->compileKey($blueprint, $command, 'unique'); + } + + /** + * Compile a plain index key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileIndex(Blueprint $blueprint, Fluent $command) + { + return $this->compileKey($blueprint, $command, 'index'); + } + + /** + * Compile an index creation command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param string $type + * @return string + */ + protected function compileKey(Blueprint $blueprint, Fluent $command, $type) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "alter table {$table} add {$type} {$command->index}($columns)"; + } + + /** + * Compile a drop table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDrop(Blueprint $blueprint, Fluent $command) + { + return 'drop table '.$this->wrapTable($blueprint); + } + + /** + * Compile a drop table (if exists) command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropIfExists(Blueprint $blueprint, Fluent $command) + { + return 'drop table if exists '.$this->wrapTable($blueprint); + } + + /** + * Compile a drop column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropColumn(Blueprint $blueprint, Fluent $command) + { + $columns = $this->prefixArray('drop', $this->wrapArray($command->columns)); + + $table = $this->wrapTable($blueprint); + + return 'alter table '.$table.' '.implode(', ', $columns); + } + + /** + * Compile a drop primary key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropPrimary(Blueprint $blueprint, Fluent $command) + { + return 'alter table '.$this->wrapTable($blueprint).' drop primary key'; + } + + /** + * Compile a drop unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropUnique(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "alter table {$table} drop index {$command->index}"; + } + + /** + * Compile a drop index command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropIndex(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "alter table {$table} drop index {$command->index}"; + } + + /** + * Compile a drop foreign key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropForeign(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "alter table {$table} drop foreign key {$command->index}"; + } + + /** + * Compile a rename table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileRename(Blueprint $blueprint, Fluent $command) + { + $from = $this->wrapTable($blueprint); + + return "rename table {$from} to ".$this->wrapTable($command->to); + } + + /** + * Create the column definition for a char type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeChar(Fluent $column) + { + return "char({$column->length})"; + } + + /** + * Create the column definition for a string type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeString(Fluent $column) + { + return "varchar({$column->length})"; + } + + /** + * Create the column definition for a text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeText(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a medium text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumText(Fluent $column) + { + return 'mediumtext'; + } + + /** + * Create the column definition for a long text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeLongText(Fluent $column) + { + return 'longtext'; + } + + /** + * Create the column definition for a big integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBigInteger(Fluent $column) + { + return 'bigint'; + } + + /** + * Create the column definition for a integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeInteger(Fluent $column) + { + return 'int'; + } + + /** + * Create the column definition for a medium integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumInteger(Fluent $column) + { + return 'mediumint'; + } + + /** + * Create the column definition for a tiny integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTinyInteger(Fluent $column) + { + return 'tinyint'; + } + + /** + * Create the column definition for a small integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeSmallInteger(Fluent $column) + { + return 'smallint'; + } + + /** + * Create the column definition for a float type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeFloat(Fluent $column) + { + return $this->typeDouble($column); + } + + /** + * Create the column definition for a double type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDouble(Fluent $column) + { + if ($column->total && $column->places) { + return "double({$column->total}, {$column->places})"; + } + + return 'double'; + } + + /** + * Create the column definition for a decimal type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDecimal(Fluent $column) + { + return "decimal({$column->total}, {$column->places})"; + } + + /** + * Create the column definition for a boolean type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBoolean(Fluent $column) + { + return 'tinyint(1)'; + } + + /** + * Create the column definition for an enum type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeEnum(Fluent $column) + { + return "enum('".implode("', '", $column->allowed)."')"; + } + + /** + * Create the column definition for a json type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJson(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a jsonb type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJsonb(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a date type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDate(Fluent $column) + { + return 'date'; + } + + /** + * Create the column definition for a date-time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTime(Fluent $column) + { + return 'datetime'; + } + + /** + * Create the column definition for a date-time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTimeTz(Fluent $column) + { + return 'datetime'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTime(Fluent $column) + { + return 'time'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimeTz(Fluent $column) + { + return 'time'; + } + + /** + * Create the column definition for a timestamp type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestamp(Fluent $column) + { + if (! $column->nullable && $column->default === null) { + return 'timestamp default 0'; + } + + return 'timestamp'; + } + + /** + * Create the column definition for a timestamp type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestampTz(Fluent $column) + { + if (! $column->nullable && $column->default === null) { + return 'timestamp default 0'; + } + + return 'timestamp'; + } + + /** + * Create the column definition for a binary type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBinary(Fluent $column) + { + return 'blob'; + } + + /** + * Create the column definition for a uuid type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeUuid(Fluent $column) + { + return 'char(36)'; + } + + /** + * Get the SQL for an unsigned column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyUnsigned(Blueprint $blueprint, Fluent $column) + { + if ($column->unsigned) { + return ' unsigned'; + } + } + + /** + * Get the SQL for a character set column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyCharset(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->charset)) { + return ' character set '.$column->charset; + } + } + + /** + * Get the SQL for a collation column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyCollate(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->collation)) { + return ' collate '.$column->collation; + } + } + + /** + * Get the SQL for a nullable column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyNullable(Blueprint $blueprint, Fluent $column) + { + return $column->nullable ? ' null' : ' not null'; + } + + /** + * Get the SQL for a default column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyDefault(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->default)) { + return ' default '.$this->getDefaultValue($column->default); + } + } + + /** + * Get the SQL for an auto-increment column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyIncrement(Blueprint $blueprint, Fluent $column) + { + if (in_array($column->type, $this->serials) && $column->autoIncrement) { + return ' auto_increment primary key'; + } + } + + /** + * Get the SQL for a "first" column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyFirst(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->first)) { + return ' first'; + } + } + + /** + * Get the SQL for an "after" column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyAfter(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->after)) { + return ' after '.$this->wrap($column->after); + } + } + + /** + * Get the SQL for a "comment" column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyComment(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->comment)) { + return ' comment "'.$column->comment.'"'; + } + } + + /** + * Wrap a single string in keyword identifiers. + * + * @param string $value + * @return string + */ + protected function wrapValue($value) + { + if ($value === '*') { + return $value; + } + + return '`'.str_replace('`', '``', $value).'`'; + } +} diff --git a/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php b/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php new file mode 100755 index 0000000..33265ba --- /dev/null +++ b/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php @@ -0,0 +1,554 @@ +getColumns($blueprint)); + + return 'create table '.$this->wrapTable($blueprint)." ($columns)"; + } + + /** + * Compile a create table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileAdd(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + $columns = $this->prefixArray('add column', $this->getColumns($blueprint)); + + return 'alter table '.$table.' '.implode(', ', $columns); + } + + /** + * Compile a primary key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compilePrimary(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + return 'alter table '.$this->wrapTable($blueprint)." add primary key ({$columns})"; + } + + /** + * Compile a unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileUnique(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + $columns = $this->columnize($command->columns); + + return "alter table $table add constraint {$command->index} unique ($columns)"; + } + + /** + * Compile a plain index key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileIndex(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + return "create index {$command->index} on ".$this->wrapTable($blueprint)." ({$columns})"; + } + + /** + * Compile a drop table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDrop(Blueprint $blueprint, Fluent $command) + { + return 'drop table '.$this->wrapTable($blueprint); + } + + /** + * Compile a drop table (if exists) command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropIfExists(Blueprint $blueprint, Fluent $command) + { + return 'drop table if exists '.$this->wrapTable($blueprint); + } + + /** + * Compile a drop column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropColumn(Blueprint $blueprint, Fluent $command) + { + $columns = $this->prefixArray('drop column', $this->wrapArray($command->columns)); + + $table = $this->wrapTable($blueprint); + + return 'alter table '.$table.' '.implode(', ', $columns); + } + + /** + * Compile a drop primary key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropPrimary(Blueprint $blueprint, Fluent $command) + { + $table = $blueprint->getTable(); + + return 'alter table '.$this->wrapTable($blueprint)." drop constraint {$table}_pkey"; + } + + /** + * Compile a drop unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropUnique(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "alter table {$table} drop constraint {$command->index}"; + } + + /** + * Compile a drop index command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropIndex(Blueprint $blueprint, Fluent $command) + { + return "drop index {$command->index}"; + } + + /** + * Compile a drop foreign key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropForeign(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "alter table {$table} drop constraint {$command->index}"; + } + + /** + * Compile a rename table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileRename(Blueprint $blueprint, Fluent $command) + { + $from = $this->wrapTable($blueprint); + + return "alter table {$from} rename to ".$this->wrapTable($command->to); + } + + /** + * Create the column definition for a char type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeChar(Fluent $column) + { + return "char({$column->length})"; + } + + /** + * Create the column definition for a string type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeString(Fluent $column) + { + return "varchar({$column->length})"; + } + + /** + * Create the column definition for a text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeText(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a medium text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumText(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a long text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeLongText(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeInteger(Fluent $column) + { + return $column->autoIncrement ? 'serial' : 'integer'; + } + + /** + * Create the column definition for a big integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBigInteger(Fluent $column) + { + return $column->autoIncrement ? 'bigserial' : 'bigint'; + } + + /** + * Create the column definition for a medium integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumInteger(Fluent $column) + { + return $column->autoIncrement ? 'serial' : 'integer'; + } + + /** + * Create the column definition for a tiny integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTinyInteger(Fluent $column) + { + return $column->autoIncrement ? 'smallserial' : 'smallint'; + } + + /** + * Create the column definition for a small integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeSmallInteger(Fluent $column) + { + return $column->autoIncrement ? 'smallserial' : 'smallint'; + } + + /** + * Create the column definition for a float type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeFloat(Fluent $column) + { + return $this->typeDouble($column); + } + + /** + * Create the column definition for a double type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDouble(Fluent $column) + { + return 'double precision'; + } + + /** + * Create the column definition for a decimal type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDecimal(Fluent $column) + { + return "decimal({$column->total}, {$column->places})"; + } + + /** + * Create the column definition for a boolean type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBoolean(Fluent $column) + { + return 'boolean'; + } + + /** + * Create the column definition for an enum type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeEnum(Fluent $column) + { + $allowed = array_map(function ($a) { return "'".$a."'"; }, $column->allowed); + + return "varchar(255) check (\"{$column->name}\" in (".implode(', ', $allowed).'))'; + } + + /** + * Create the column definition for a json type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJson(Fluent $column) + { + return 'json'; + } + + /** + * Create the column definition for a jsonb type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJsonb(Fluent $column) + { + return 'jsonb'; + } + + /** + * Create the column definition for a date type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDate(Fluent $column) + { + return 'date'; + } + + /** + * Create the column definition for a date-time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTime(Fluent $column) + { + return 'timestamp(0) without time zone'; + } + + /** + * Create the column definition for a date-time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTimeTz(Fluent $column) + { + return 'timestamp(0) with time zone'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTime(Fluent $column) + { + return 'time(0) without time zone'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimeTz(Fluent $column) + { + return 'time(0) with time zone'; + } + + /** + * Create the column definition for a timestamp type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestamp(Fluent $column) + { + return 'timestamp(0) without time zone'; + } + + /** + * Create the column definition for a timestamp type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestampTz(Fluent $column) + { + return 'timestamp(0) with time zone'; + } + + /** + * Create the column definition for a binary type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBinary(Fluent $column) + { + return 'bytea'; + } + + /** + * Create the column definition for a uuid type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeUuid(Fluent $column) + { + return 'uuid'; + } + + /** + * Get the SQL for a nullable column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyNullable(Blueprint $blueprint, Fluent $column) + { + return $column->nullable ? ' null' : ' not null'; + } + + /** + * Get the SQL for a default column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyDefault(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->default)) { + return ' default '.$this->getDefaultValue($column->default); + } + } + + /** + * Get the SQL for an auto-increment column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyIncrement(Blueprint $blueprint, Fluent $column) + { + if (in_array($column->type, $this->serials) && $column->autoIncrement) { + return ' primary key'; + } + } +} diff --git a/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php b/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php new file mode 100755 index 0000000..59d61d0 --- /dev/null +++ b/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php @@ -0,0 +1,615 @@ +getColumns($blueprint)); + + $sql = 'create table '.$this->wrapTable($blueprint)." ($columns"; + + // SQLite forces primary keys to be added when the table is initially created + // so we will need to check for a primary key commands and add the columns + // to the table's declaration here so they can be created on the tables. + $sql .= (string) $this->addForeignKeys($blueprint); + + $sql .= (string) $this->addPrimaryKeys($blueprint); + + return $sql.')'; + } + + /** + * Get the foreign key syntax for a table creation statement. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @return string|null + */ + protected function addForeignKeys(Blueprint $blueprint) + { + $sql = ''; + + $foreigns = $this->getCommandsByName($blueprint, 'foreign'); + + // Once we have all the foreign key commands for the table creation statement + // we'll loop through each of them and add them to the create table SQL we + // are building, since SQLite needs foreign keys on the tables creation. + foreach ($foreigns as $foreign) { + $sql .= $this->getForeignKey($foreign); + + if (! is_null($foreign->onDelete)) { + $sql .= " on delete {$foreign->onDelete}"; + } + + if (! is_null($foreign->onUpdate)) { + $sql .= " on update {$foreign->onUpdate}"; + } + } + + return $sql; + } + + /** + * Get the SQL for the foreign key. + * + * @param \Illuminate\Support\Fluent $foreign + * @return string + */ + protected function getForeignKey($foreign) + { + $on = $this->wrapTable($foreign->on); + + // We need to columnize the columns that the foreign key is being defined for + // so that it is a properly formatted list. Once we have done this, we can + // return the foreign key SQL declaration to the calling method for use. + $columns = $this->columnize($foreign->columns); + + $onColumns = $this->columnize((array) $foreign->references); + + return ", foreign key($columns) references $on($onColumns)"; + } + + /** + * Get the primary key syntax for a table creation statement. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @return string|null + */ + protected function addPrimaryKeys(Blueprint $blueprint) + { + $primary = $this->getCommandByName($blueprint, 'primary'); + + if (! is_null($primary)) { + $columns = $this->columnize($primary->columns); + + return ", primary key ({$columns})"; + } + } + + /** + * Compile alter table commands for adding columns. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return array + */ + public function compileAdd(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + $columns = $this->prefixArray('add column', $this->getColumns($blueprint)); + + $statements = []; + + foreach ($columns as $column) { + $statements[] = 'alter table '.$table.' '.$column; + } + + return $statements; + } + + /** + * Compile a unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileUnique(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "create unique index {$command->index} on {$table} ({$columns})"; + } + + /** + * Compile a plain index key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileIndex(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "create index {$command->index} on {$table} ({$columns})"; + } + + /** + * Compile a foreign key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileForeign(Blueprint $blueprint, Fluent $command) + { + // Handled on table creation... + } + + /** + * Compile a drop table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDrop(Blueprint $blueprint, Fluent $command) + { + return 'drop table '.$this->wrapTable($blueprint); + } + + /** + * Compile a drop table (if exists) command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropIfExists(Blueprint $blueprint, Fluent $command) + { + return 'drop table if exists '.$this->wrapTable($blueprint); + } + + /** + * Compile a drop column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array + */ + public function compileDropColumn(Blueprint $blueprint, Fluent $command, Connection $connection) + { + $schema = $connection->getDoctrineSchemaManager(); + + $tableDiff = $this->getDoctrineTableDiff($blueprint, $schema); + + foreach ($command->columns as $name) { + $column = $connection->getDoctrineColumn($blueprint->getTable(), $name); + + $tableDiff->removedColumns[$name] = $column; + } + + return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff); + } + + /** + * Compile a drop unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropUnique(Blueprint $blueprint, Fluent $command) + { + return "drop index {$command->index}"; + } + + /** + * Compile a drop index command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropIndex(Blueprint $blueprint, Fluent $command) + { + return "drop index {$command->index}"; + } + + /** + * Compile a rename table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileRename(Blueprint $blueprint, Fluent $command) + { + $from = $this->wrapTable($blueprint); + + return "alter table {$from} rename to ".$this->wrapTable($command->to); + } + + /** + * Create the column definition for a char type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeChar(Fluent $column) + { + return 'varchar'; + } + + /** + * Create the column definition for a string type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeString(Fluent $column) + { + return 'varchar'; + } + + /** + * Create the column definition for a text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeText(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a medium text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumText(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a long text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeLongText(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeInteger(Fluent $column) + { + return 'integer'; + } + + /** + * Create the column definition for a big integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBigInteger(Fluent $column) + { + return 'integer'; + } + + /** + * Create the column definition for a medium integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumInteger(Fluent $column) + { + return 'integer'; + } + + /** + * Create the column definition for a tiny integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTinyInteger(Fluent $column) + { + return 'integer'; + } + + /** + * Create the column definition for a small integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeSmallInteger(Fluent $column) + { + return 'integer'; + } + + /** + * Create the column definition for a float type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeFloat(Fluent $column) + { + return 'float'; + } + + /** + * Create the column definition for a double type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDouble(Fluent $column) + { + return 'float'; + } + + /** + * Create the column definition for a decimal type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDecimal(Fluent $column) + { + return 'numeric'; + } + + /** + * Create the column definition for a boolean type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBoolean(Fluent $column) + { + return 'tinyint'; + } + + /** + * Create the column definition for an enum type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeEnum(Fluent $column) + { + return 'varchar'; + } + + /** + * Create the column definition for a json type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJson(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a jsonb type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJsonb(Fluent $column) + { + return 'text'; + } + + /** + * Create the column definition for a date type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDate(Fluent $column) + { + return 'date'; + } + + /** + * Create the column definition for a date-time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTime(Fluent $column) + { + return 'datetime'; + } + + /** + * Create the column definition for a date-time type. + * + * Note: "SQLite does not have a storage class set aside for storing dates and/or times." + * @link https://www.sqlite.org/datatype3.html + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTimeTz(Fluent $column) + { + return 'datetime'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTime(Fluent $column) + { + return 'time'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimeTz(Fluent $column) + { + return 'time'; + } + + /** + * Create the column definition for a timestamp type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestamp(Fluent $column) + { + return 'datetime'; + } + + /** + * Create the column definition for a timestamp type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestampTz(Fluent $column) + { + return 'datetime'; + } + + /** + * Create the column definition for a binary type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBinary(Fluent $column) + { + return 'blob'; + } + + /** + * Create the column definition for a uuid type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeUuid(Fluent $column) + { + return 'varchar'; + } + + /** + * Get the SQL for a nullable column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyNullable(Blueprint $blueprint, Fluent $column) + { + return $column->nullable ? ' null' : ' not null'; + } + + /** + * Get the SQL for a default column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyDefault(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->default)) { + return ' default '.$this->getDefaultValue($column->default); + } + } + + /** + * Get the SQL for an auto-increment column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyIncrement(Blueprint $blueprint, Fluent $column) + { + if (in_array($column->type, $this->serials) && $column->autoIncrement) { + return ' primary key autoincrement'; + } + } +} diff --git a/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php b/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php new file mode 100755 index 0000000..9441e6a --- /dev/null +++ b/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php @@ -0,0 +1,562 @@ +getColumns($blueprint)); + + return 'create table '.$this->wrapTable($blueprint)." ($columns)"; + } + + /** + * Compile a create table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileAdd(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + $columns = $this->getColumns($blueprint); + + return 'alter table '.$table.' add '.implode(', ', $columns); + } + + /** + * Compile a primary key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compilePrimary(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "alter table {$table} add constraint {$command->index} primary key ({$columns})"; + } + + /** + * Compile a unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileUnique(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "create unique index {$command->index} on {$table} ({$columns})"; + } + + /** + * Compile a plain index key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileIndex(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "create index {$command->index} on {$table} ({$columns})"; + } + + /** + * Compile a drop table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDrop(Blueprint $blueprint, Fluent $command) + { + return 'drop table '.$this->wrapTable($blueprint); + } + + /** + * Compile a drop table (if exists) command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropIfExists(Blueprint $blueprint, Fluent $command) + { + return 'if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = \''.$blueprint->getTable().'\') drop table '.$blueprint->getTable(); + } + + /** + * Compile a drop column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropColumn(Blueprint $blueprint, Fluent $command) + { + $columns = $this->wrapArray($command->columns); + + $table = $this->wrapTable($blueprint); + + return 'alter table '.$table.' drop column '.implode(', ', $columns); + } + + /** + * Compile a drop primary key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropPrimary(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "alter table {$table} drop constraint {$command->index}"; + } + + /** + * Compile a drop unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropUnique(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "drop index {$command->index} on {$table}"; + } + + /** + * Compile a drop index command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropIndex(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "drop index {$command->index} on {$table}"; + } + + /** + * Compile a drop foreign key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropForeign(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "alter table {$table} drop constraint {$command->index}"; + } + + /** + * Compile a rename table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileRename(Blueprint $blueprint, Fluent $command) + { + $from = $this->wrapTable($blueprint); + + return "sp_rename {$from}, ".$this->wrapTable($command->to); + } + + /** + * Create the column definition for a char type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeChar(Fluent $column) + { + return "nchar({$column->length})"; + } + + /** + * Create the column definition for a string type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeString(Fluent $column) + { + return "nvarchar({$column->length})"; + } + + /** + * Create the column definition for a text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeText(Fluent $column) + { + return 'nvarchar(max)'; + } + + /** + * Create the column definition for a medium text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumText(Fluent $column) + { + return 'nvarchar(max)'; + } + + /** + * Create the column definition for a long text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeLongText(Fluent $column) + { + return 'nvarchar(max)'; + } + + /** + * Create the column definition for a integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeInteger(Fluent $column) + { + return 'int'; + } + + /** + * Create the column definition for a big integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBigInteger(Fluent $column) + { + return 'bigint'; + } + + /** + * Create the column definition for a medium integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumInteger(Fluent $column) + { + return 'int'; + } + + /** + * Create the column definition for a tiny integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTinyInteger(Fluent $column) + { + return 'tinyint'; + } + + /** + * Create the column definition for a small integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeSmallInteger(Fluent $column) + { + return 'smallint'; + } + + /** + * Create the column definition for a float type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeFloat(Fluent $column) + { + return 'float'; + } + + /** + * Create the column definition for a double type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDouble(Fluent $column) + { + return 'float'; + } + + /** + * Create the column definition for a decimal type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDecimal(Fluent $column) + { + return "decimal({$column->total}, {$column->places})"; + } + + /** + * Create the column definition for a boolean type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBoolean(Fluent $column) + { + return 'bit'; + } + + /** + * Create the column definition for an enum type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeEnum(Fluent $column) + { + return 'nvarchar(255)'; + } + + /** + * Create the column definition for a json type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJson(Fluent $column) + { + return 'nvarchar(max)'; + } + + /** + * Create the column definition for a jsonb type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJsonb(Fluent $column) + { + return 'nvarchar(max)'; + } + + /** + * Create the column definition for a date type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDate(Fluent $column) + { + return 'date'; + } + + /** + * Create the column definition for a date-time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTime(Fluent $column) + { + return 'datetime'; + } + + /** + * Create the column definition for a date-time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTimeTz(Fluent $column) + { + return 'datetimeoffset(0)'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTime(Fluent $column) + { + return 'time'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimeTz(Fluent $column) + { + return 'time'; + } + + /** + * Create the column definition for a timestamp type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestamp(Fluent $column) + { + return 'datetime'; + } + + /** + * Create the column definition for a timestamp type. + * + * @link https://msdn.microsoft.com/en-us/library/bb630289(v=sql.120).aspx + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestampTz(Fluent $column) + { + return 'datetimeoffset(0)'; + } + + /** + * Create the column definition for a binary type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBinary(Fluent $column) + { + return 'varbinary(max)'; + } + + /** + * Create the column definition for a uuid type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeUuid(Fluent $column) + { + return 'uniqueidentifier'; + } + + /** + * Get the SQL for a nullable column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyNullable(Blueprint $blueprint, Fluent $column) + { + return $column->nullable ? ' null' : ' not null'; + } + + /** + * Get the SQL for a default column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyDefault(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->default)) { + return ' default '.$this->getDefaultValue($column->default); + } + } + + /** + * Get the SQL for an auto-increment column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyIncrement(Blueprint $blueprint, Fluent $column) + { + if (in_array($column->type, $this->serials) && $column->autoIncrement) { + return ' identity primary key'; + } + } +} diff --git a/vendor/illuminate/database/Schema/MySqlBuilder.php b/vendor/illuminate/database/Schema/MySqlBuilder.php new file mode 100755 index 0000000..e0b0ade --- /dev/null +++ b/vendor/illuminate/database/Schema/MySqlBuilder.php @@ -0,0 +1,42 @@ +grammar->compileTableExists(); + + $database = $this->connection->getDatabaseName(); + + $table = $this->connection->getTablePrefix().$table; + + return count($this->connection->select($sql, [$database, $table])) > 0; + } + + /** + * Get the column listing for a given table. + * + * @param string $table + * @return array + */ + public function getColumnListing($table) + { + $sql = $this->grammar->compileColumnExists(); + + $database = $this->connection->getDatabaseName(); + + $table = $this->connection->getTablePrefix().$table; + + $results = $this->connection->select($sql, [$database, $table]); + + return $this->connection->getPostProcessor()->processColumnListing($results); + } +} diff --git a/vendor/illuminate/database/SeedServiceProvider.php b/vendor/illuminate/database/SeedServiceProvider.php new file mode 100755 index 0000000..3a97cde --- /dev/null +++ b/vendor/illuminate/database/SeedServiceProvider.php @@ -0,0 +1,69 @@ +registerSeedCommand(); + + $this->registerMakeCommand(); + + $this->app->singleton('seeder', function () { + return new Seeder; + }); + + $this->commands('command.seed', 'command.seeder.make'); + } + + /** + * Register the seed console command. + * + * @return void + */ + protected function registerSeedCommand() + { + $this->app->singleton('command.seed', function ($app) { + return new SeedCommand($app['db']); + }); + } + + /** + * Register the seeder generator command. + * + * @return void + */ + protected function registerMakeCommand() + { + $this->app->singleton('command.seeder.make', function ($app) { + return new SeederMakeCommand($app['files'], $app['composer']); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return ['seeder', 'command.seed', 'command.seeder.make']; + } +} diff --git a/vendor/illuminate/database/Seeder.php b/vendor/illuminate/database/Seeder.php new file mode 100755 index 0000000..4e29c16 --- /dev/null +++ b/vendor/illuminate/database/Seeder.php @@ -0,0 +1,97 @@ +resolve($class)->run(); + + if (isset($this->command)) { + $this->command->getOutput()->writeln("Seeded: $class"); + } + } + + /** + * Resolve an instance of the given seeder class. + * + * @param string $class + * @return \Illuminate\Database\Seeder + */ + protected function resolve($class) + { + if (isset($this->container)) { + $instance = $this->container->make($class); + + $instance->setContainer($this->container); + } else { + $instance = new $class; + } + + if (isset($this->command)) { + $instance->setCommand($this->command); + } + + return $instance; + } + + /** + * Set the IoC container instance. + * + * @param \Illuminate\Container\Container $container + * @return $this + */ + public function setContainer(Container $container) + { + $this->container = $container; + + return $this; + } + + /** + * Set the console command instance. + * + * @param \Illuminate\Console\Command $command + * @return $this + */ + public function setCommand(Command $command) + { + $this->command = $command; + + return $this; + } +} diff --git a/vendor/illuminate/database/SqlServerConnection.php b/vendor/illuminate/database/SqlServerConnection.php new file mode 100755 index 0000000..fa097e2 --- /dev/null +++ b/vendor/illuminate/database/SqlServerConnection.php @@ -0,0 +1,95 @@ +getDriverName() == 'sqlsrv') { + return parent::transaction($callback); + } + + $this->pdo->exec('BEGIN TRAN'); + + // We'll simply execute the given callback within a try / catch block + // and if we catch any exception we can rollback the transaction + // so that none of the changes are persisted to the database. + try { + $result = $callback($this); + + $this->pdo->exec('COMMIT TRAN'); + } + + // If we catch an exception, we will roll back so nothing gets messed + // up in the database. Then we'll re-throw the exception so it can + // be handled how the developer sees fit for their applications. + catch (Exception $e) { + $this->pdo->exec('ROLLBACK TRAN'); + + throw $e; + } catch (Throwable $e) { + $this->pdo->exec('ROLLBACK TRAN'); + + throw $e; + } + + return $result; + } + + /** + * Get the default query grammar instance. + * + * @return \Illuminate\Database\Query\Grammars\SqlServerGrammar + */ + protected function getDefaultQueryGrammar() + { + return $this->withTablePrefix(new QueryGrammar); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\SqlServerGrammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\SqlServerProcessor + */ + protected function getDefaultPostProcessor() + { + return new SqlServerProcessor; + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Doctrine\DBAL\Driver\PDOSqlsrv\Driver + */ + protected function getDoctrineDriver() + { + return new DoctrineDriver; + } +} diff --git a/vendor/illuminate/database/composer.json b/vendor/illuminate/database/composer.json new file mode 100755 index 0000000..8b7f1e2 --- /dev/null +++ b/vendor/illuminate/database/composer.json @@ -0,0 +1,42 @@ +{ + "name": "illuminate/database", + "description": "The Illuminate Database package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "keywords": ["laravel", "database", "sql", "orm"], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19" + }, + "autoload": { + "psr-4": { + "Illuminate\\Database\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", + "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", + "illuminate/console": "Required to use the database commands (5.1.*).", + "illuminate/events": "Required to use the observers with Eloquent (5.1.*).", + "illuminate/filesystem": "Required to use the migrations (5.1.*)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/encryption/BaseEncrypter.php b/vendor/illuminate/encryption/BaseEncrypter.php new file mode 100644 index 0000000..1d427af --- /dev/null +++ b/vendor/illuminate/encryption/BaseEncrypter.php @@ -0,0 +1,82 @@ +key); + } + + /** + * Get the JSON array from the given payload. + * + * @param string $payload + * @return array + * + * @throws \Illuminate\Contracts\Encryption\DecryptException + */ + protected function getJsonPayload($payload) + { + $payload = json_decode(base64_decode($payload), true); + + // If the payload is not valid JSON or does not have the proper keys set we will + // assume it is invalid and bail out of the routine since we will not be able + // to decrypt the given value. We'll also check the MAC for this encryption. + if (! $payload || $this->invalidPayload($payload)) { + throw new DecryptException('The payload is invalid.'); + } + + if (! $this->validMac($payload)) { + throw new DecryptException('The MAC is invalid.'); + } + + return $payload; + } + + /** + * Verify that the encryption payload is valid. + * + * @param array|mixed $data + * @return bool + */ + protected function invalidPayload($data) + { + return ! is_array($data) || ! isset($data['iv']) || ! isset($data['value']) || ! isset($data['mac']); + } + + /** + * Determine if the MAC for the given payload is valid. + * + * @param array $payload + * @return bool + * + * @throws \RuntimeException + */ + protected function validMac(array $payload) + { + $bytes = Str::randomBytes(16); + + $calcMac = hash_hmac('sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true); + + return Str::equals(hash_hmac('sha256', $payload['mac'], $bytes, true), $calcMac); + } +} diff --git a/vendor/illuminate/encryption/Encrypter.php b/vendor/illuminate/encryption/Encrypter.php new file mode 100755 index 0000000..63c4a07 --- /dev/null +++ b/vendor/illuminate/encryption/Encrypter.php @@ -0,0 +1,107 @@ +key = $key; + $this->cipher = $cipher; + } else { + throw new RuntimeException('The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths.'); + } + } + + /** + * Determine if the given key and cipher combination is valid. + * + * @param string $key + * @param string $cipher + * @return bool + */ + public static function supported($key, $cipher) + { + $length = mb_strlen($key, '8bit'); + + return ($cipher === 'AES-128-CBC' && $length === 16) || ($cipher === 'AES-256-CBC' && $length === 32); + } + + /** + * Encrypt the given value. + * + * @param string $value + * @return string + */ + public function encrypt($value) + { + $iv = Str::randomBytes($this->getIvSize()); + + $value = openssl_encrypt(serialize($value), $this->cipher, $this->key, 0, $iv); + + if ($value === false) { + throw new EncryptException('Could not encrypt the data.'); + } + + // Once we have the encrypted value we will go ahead base64_encode the input + // vector and create the MAC for the encrypted value so we can verify its + // authenticity. Then, we'll JSON encode the data in a "payload" array. + $mac = $this->hash($iv = base64_encode($iv), $value); + + return base64_encode(json_encode(compact('iv', 'value', 'mac'))); + } + + /** + * Decrypt the given value. + * + * @param string $payload + * @return string + */ + public function decrypt($payload) + { + $payload = $this->getJsonPayload($payload); + + $iv = base64_decode($payload['iv']); + + $decrypted = openssl_decrypt($payload['value'], $this->cipher, $this->key, 0, $iv); + + if ($decrypted === false) { + throw new DecryptException('Could not decrypt the data.'); + } + + return unserialize($decrypted); + } + + /** + * Get the IV size for the cipher. + * + * @return int + */ + protected function getIvSize() + { + return 16; + } +} diff --git a/vendor/illuminate/encryption/EncryptionServiceProvider.php b/vendor/illuminate/encryption/EncryptionServiceProvider.php new file mode 100755 index 0000000..a0b9491 --- /dev/null +++ b/vendor/illuminate/encryption/EncryptionServiceProvider.php @@ -0,0 +1,33 @@ +app->singleton('encrypter', function ($app) { + $config = $app->make('config')->get('app'); + + $key = $config['key']; + + $cipher = $config['cipher']; + + if (Encrypter::supported($key, $cipher)) { + return new Encrypter($key, $cipher); + } elseif (McryptEncrypter::supported($key, $cipher)) { + return new McryptEncrypter($key, $cipher); + } else { + throw new RuntimeException('No supported encrypter found. The cipher and / or key length are invalid.'); + } + }); + } +} diff --git a/vendor/illuminate/encryption/McryptEncrypter.php b/vendor/illuminate/encryption/McryptEncrypter.php new file mode 100644 index 0000000..49df0eb --- /dev/null +++ b/vendor/illuminate/encryption/McryptEncrypter.php @@ -0,0 +1,203 @@ +key = $key; + $this->cipher = $cipher; + $this->block = mcrypt_get_iv_size($this->cipher, MCRYPT_MODE_CBC); + } else { + throw new RuntimeException('The only supported ciphers are MCRYPT_RIJNDAEL_128 and MCRYPT_RIJNDAEL_256.'); + } + } + + /** + * Determine if the given key and cipher combination is valid. + * + * @param string $key + * @param string $cipher + * @return bool + */ + public static function supported($key, $cipher) + { + return defined('MCRYPT_RIJNDAEL_128') && + ($cipher === MCRYPT_RIJNDAEL_128 || $cipher === MCRYPT_RIJNDAEL_256); + } + + /** + * Encrypt the given value. + * + * @param string $value + * @return string + */ + public function encrypt($value) + { + $iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer()); + + $value = base64_encode($this->padAndMcrypt($value, $iv)); + + // Once we have the encrypted value we will go ahead base64_encode the input + // vector and create the MAC for the encrypted value so we can verify its + // authenticity. Then, we'll JSON encode the data in a "payload" array. + $mac = $this->hash($iv = base64_encode($iv), $value); + + return base64_encode(json_encode(compact('iv', 'value', 'mac'))); + } + + /** + * Pad and use mcrypt on the given value and input vector. + * + * @param string $value + * @param string $iv + * @return string + */ + protected function padAndMcrypt($value, $iv) + { + $value = $this->addPadding(serialize($value)); + + return mcrypt_encrypt($this->cipher, $this->key, $value, MCRYPT_MODE_CBC, $iv); + } + + /** + * Decrypt the given value. + * + * @param string $payload + * @return string + */ + public function decrypt($payload) + { + $payload = $this->getJsonPayload($payload); + + // We'll go ahead and remove the PKCS7 padding from the encrypted value before + // we decrypt it. Once we have the de-padded value, we will grab the vector + // and decrypt the data, passing back the unserialized from of the value. + $value = base64_decode($payload['value']); + + $iv = base64_decode($payload['iv']); + + return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv))); + } + + /** + * Run the mcrypt decryption routine for the value. + * + * @param string $value + * @param string $iv + * @return string + * + * @throws \Illuminate\Contracts\Encryption\DecryptException + */ + protected function mcryptDecrypt($value, $iv) + { + try { + return mcrypt_decrypt($this->cipher, $this->key, $value, MCRYPT_MODE_CBC, $iv); + } catch (Exception $e) { + throw new DecryptException($e->getMessage()); + } + } + + /** + * Add PKCS7 padding to a given value. + * + * @param string $value + * @return string + */ + protected function addPadding($value) + { + $pad = $this->block - (strlen($value) % $this->block); + + return $value.str_repeat(chr($pad), $pad); + } + + /** + * Remove the padding from the given value. + * + * @param string $value + * @return string + */ + protected function stripPadding($value) + { + $pad = ord($value[($len = strlen($value)) - 1]); + + return $this->paddingIsValid($pad, $value) ? substr($value, 0, $len - $pad) : $value; + } + + /** + * Determine if the given padding for a value is valid. + * + * @param string $pad + * @param string $value + * @return bool + */ + protected function paddingIsValid($pad, $value) + { + $beforePad = strlen($value) - $pad; + + return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad); + } + + /** + * Get the IV size for the cipher. + * + * @return int + */ + protected function getIvSize() + { + return mcrypt_get_iv_size($this->cipher, MCRYPT_MODE_CBC); + } + + /** + * Get the random data source available for the OS. + * + * @return int + */ + protected function getRandomizer() + { + if (defined('MCRYPT_DEV_URANDOM')) { + return MCRYPT_DEV_URANDOM; + } + + if (defined('MCRYPT_DEV_RANDOM')) { + return MCRYPT_DEV_RANDOM; + } + + mt_srand(); + + return MCRYPT_RAND; + } +} diff --git a/vendor/illuminate/encryption/composer.json b/vendor/illuminate/encryption/composer.json new file mode 100755 index 0000000..a50c1de --- /dev/null +++ b/vendor/illuminate/encryption/composer.json @@ -0,0 +1,37 @@ +{ + "name": "illuminate/encryption", + "description": "The Illuminate Encryption package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "ext-mbstring": "*", + "ext-openssl": "*", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Encryption\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "paragonie/random_compat": "Provides a compatible interface like PHP7's random_bytes() in PHP 5 projects (^1.0.6)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/events/CallQueuedHandler.php b/vendor/illuminate/events/CallQueuedHandler.php new file mode 100644 index 0000000..b182cd8 --- /dev/null +++ b/vendor/illuminate/events/CallQueuedHandler.php @@ -0,0 +1,80 @@ +container = $container; + } + + /** + * Handle the queued job. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @param array $data + * @return void + */ + public function call(Job $job, array $data) + { + $handler = $this->setJobInstanceIfNecessary( + $job, $this->container->make($data['class']) + ); + + call_user_func_array( + [$handler, $data['method']], unserialize($data['data']) + ); + + if (! $job->isDeletedOrReleased()) { + $job->delete(); + } + } + + /** + * Set the job instance of the given class if necessary. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @param mixed $instance + * @return mixed + */ + protected function setJobInstanceIfNecessary(Job $job, $instance) + { + if (in_array('Illuminate\Queue\InteractsWithQueue', class_uses_recursive(get_class($instance)))) { + $instance->setJob($job); + } + + return $instance; + } + + /** + * Call the failed method on the job instance. + * + * @param array $data + * @return void + */ + public function failed(array $data) + { + $handler = $this->container->make($data['class']); + + if (method_exists($handler, 'failed')) { + call_user_func_array([$handler, 'failed'], unserialize($data['data'])); + } + } +} diff --git a/vendor/illuminate/events/Dispatcher.php b/vendor/illuminate/events/Dispatcher.php new file mode 100755 index 0000000..9e99ea8 --- /dev/null +++ b/vendor/illuminate/events/Dispatcher.php @@ -0,0 +1,497 @@ +container = $container ?: new Container; + } + + /** + * Register an event listener with the dispatcher. + * + * @param string|array $events + * @param mixed $listener + * @param int $priority + * @return void + */ + public function listen($events, $listener, $priority = 0) + { + foreach ((array) $events as $event) { + if (Str::contains($event, '*')) { + $this->setupWildcardListen($event, $listener); + } else { + $this->listeners[$event][$priority][] = $this->makeListener($listener); + + unset($this->sorted[$event]); + } + } + } + + /** + * Setup a wildcard listener callback. + * + * @param string $event + * @param mixed $listener + * @return void + */ + protected function setupWildcardListen($event, $listener) + { + $this->wildcards[$event][] = $this->makeListener($listener); + } + + /** + * Determine if a given event has listeners. + * + * @param string $eventName + * @return bool + */ + public function hasListeners($eventName) + { + return isset($this->listeners[$eventName]); + } + + /** + * Register an event and payload to be fired later. + * + * @param string $event + * @param array $payload + * @return void + */ + public function push($event, $payload = []) + { + $this->listen($event.'_pushed', function () use ($event, $payload) { + $this->fire($event, $payload); + }); + } + + /** + * Register an event subscriber with the dispatcher. + * + * @param object|string $subscriber + * @return void + */ + public function subscribe($subscriber) + { + $subscriber = $this->resolveSubscriber($subscriber); + + $subscriber->subscribe($this); + } + + /** + * Resolve the subscriber instance. + * + * @param object|string $subscriber + * @return mixed + */ + protected function resolveSubscriber($subscriber) + { + if (is_string($subscriber)) { + return $this->container->make($subscriber); + } + + return $subscriber; + } + + /** + * Fire an event until the first non-null response is returned. + * + * @param string|object $event + * @param array $payload + * @return mixed + */ + public function until($event, $payload = []) + { + return $this->fire($event, $payload, true); + } + + /** + * Flush a set of pushed events. + * + * @param string $event + * @return void + */ + public function flush($event) + { + $this->fire($event.'_pushed'); + } + + /** + * Get the event that is currently firing. + * + * @return string + */ + public function firing() + { + return last($this->firing); + } + + /** + * Fire an event and call the listeners. + * + * @param string|object $event + * @param mixed $payload + * @param bool $halt + * @return array|null + */ + public function fire($event, $payload = [], $halt = false) + { + // When the given "event" is actually an object we will assume it is an event + // object and use the class as the event name and this event itself as the + // payload to the handler, which makes object based events quite simple. + if (is_object($event)) { + list($payload, $event) = [[$event], get_class($event)]; + } + + $responses = []; + + // If an array is not given to us as the payload, we will turn it into one so + // we can easily use call_user_func_array on the listeners, passing in the + // payload to each of them so that they receive each of these arguments. + if (! is_array($payload)) { + $payload = [$payload]; + } + + $this->firing[] = $event; + + if (isset($payload[0]) && $payload[0] instanceof ShouldBroadcast) { + $this->broadcastEvent($payload[0]); + } + + foreach ($this->getListeners($event) as $listener) { + $response = call_user_func_array($listener, $payload); + + // If a response is returned from the listener and event halting is enabled + // we will just return this response, and not call the rest of the event + // listeners. Otherwise we will add the response on the response list. + if (! is_null($response) && $halt) { + array_pop($this->firing); + + return $response; + } + + // If a boolean false is returned from a listener, we will stop propagating + // the event to any further listeners down in the chain, else we keep on + // looping through the listeners and firing every one in our sequence. + if ($response === false) { + break; + } + + $responses[] = $response; + } + + array_pop($this->firing); + + return $halt ? null : $responses; + } + + /** + * Broadcast the given event class. + * + * @param \Illuminate\Contracts\Broadcasting\ShouldBroadcast $event + * @return void + */ + protected function broadcastEvent($event) + { + if ($this->queueResolver) { + $connection = $event instanceof ShouldBroadcastNow ? 'sync' : null; + + $queue = method_exists($event, 'onQueue') ? $event->onQueue() : null; + + $this->resolveQueue()->connection($connection)->pushOn($queue, 'Illuminate\Broadcasting\BroadcastEvent', [ + 'event' => serialize(clone $event), + ]); + } + } + + /** + * Get all of the listeners for a given event name. + * + * @param string $eventName + * @return array + */ + public function getListeners($eventName) + { + $wildcards = $this->getWildcardListeners($eventName); + + if (! isset($this->sorted[$eventName])) { + $this->sortListeners($eventName); + } + + return array_merge($this->sorted[$eventName], $wildcards); + } + + /** + * Get the wildcard listeners for the event. + * + * @param string $eventName + * @return array + */ + protected function getWildcardListeners($eventName) + { + $wildcards = []; + + foreach ($this->wildcards as $key => $listeners) { + if (Str::is($key, $eventName)) { + $wildcards = array_merge($wildcards, $listeners); + } + } + + return $wildcards; + } + + /** + * Sort the listeners for a given event by priority. + * + * @param string $eventName + * @return array + */ + protected function sortListeners($eventName) + { + $this->sorted[$eventName] = []; + + // If listeners exist for the given event, we will sort them by the priority + // so that we can call them in the correct order. We will cache off these + // sorted event listeners so we do not have to re-sort on every events. + if (isset($this->listeners[$eventName])) { + krsort($this->listeners[$eventName]); + + $this->sorted[$eventName] = call_user_func_array( + 'array_merge', $this->listeners[$eventName] + ); + } + } + + /** + * Register an event listener with the dispatcher. + * + * @param mixed $listener + * @return mixed + */ + public function makeListener($listener) + { + return is_string($listener) ? $this->createClassListener($listener) : $listener; + } + + /** + * Create a class based listener using the IoC container. + * + * @param mixed $listener + * @return \Closure + */ + public function createClassListener($listener) + { + $container = $this->container; + + return function () use ($listener, $container) { + return call_user_func_array( + $this->createClassCallable($listener, $container), func_get_args() + ); + }; + } + + /** + * Create the class based event callable. + * + * @param string $listener + * @param \Illuminate\Container\Container $container + * @return callable + */ + protected function createClassCallable($listener, $container) + { + list($class, $method) = $this->parseClassCallable($listener); + + if ($this->handlerShouldBeQueued($class)) { + return $this->createQueuedHandlerCallable($class, $method); + } else { + return [$container->make($class), $method]; + } + } + + /** + * Parse the class listener into class and method. + * + * @param string $listener + * @return array + */ + protected function parseClassCallable($listener) + { + $segments = explode('@', $listener); + + return [$segments[0], count($segments) == 2 ? $segments[1] : 'handle']; + } + + /** + * Determine if the event handler class should be queued. + * + * @param string $class + * @return bool + */ + protected function handlerShouldBeQueued($class) + { + try { + return (new ReflectionClass($class))->implementsInterface( + 'Illuminate\Contracts\Queue\ShouldQueue' + ); + } catch (Exception $e) { + return false; + } + } + + /** + * Create a callable for putting an event handler on the queue. + * + * @param string $class + * @param string $method + * @return \Closure + */ + protected function createQueuedHandlerCallable($class, $method) + { + return function () use ($class, $method) { + $arguments = $this->cloneArgumentsForQueueing(func_get_args()); + + if (method_exists($class, 'queue')) { + $this->callQueueMethodOnHandler($class, $method, $arguments); + } else { + $this->resolveQueue()->push('Illuminate\Events\CallQueuedHandler@call', [ + 'class' => $class, 'method' => $method, 'data' => serialize($arguments), + ]); + } + }; + } + + /** + * Clone the given arguments for queueing. + * + * @param array $arguments + * @return array + */ + protected function cloneArgumentsForQueueing(array $arguments) + { + return array_map(function ($a) { return is_object($a) ? clone $a : $a; }, $arguments); + } + + /** + * Call the queue method on the handler class. + * + * @param string $class + * @param string $method + * @param array $arguments + * @return void + */ + protected function callQueueMethodOnHandler($class, $method, $arguments) + { + $handler = (new ReflectionClass($class))->newInstanceWithoutConstructor(); + + $handler->queue($this->resolveQueue(), 'Illuminate\Events\CallQueuedHandler@call', [ + 'class' => $class, 'method' => $method, 'data' => serialize($arguments), + ]); + } + + /** + * Remove a set of listeners from the dispatcher. + * + * @param string $event + * @return void + */ + public function forget($event) + { + unset($this->listeners[$event], $this->sorted[$event]); + } + + /** + * Forget all of the pushed listeners. + * + * @return void + */ + public function forgetPushed() + { + foreach ($this->listeners as $key => $value) { + if (Str::endsWith($key, '_pushed')) { + $this->forget($key); + } + } + } + + /** + * Get the queue implementation from the resolver. + * + * @return \Illuminate\Contracts\Queue\Queue + */ + protected function resolveQueue() + { + return call_user_func($this->queueResolver); + } + + /** + * Set the queue resolver implementation. + * + * @param callable $resolver + * @return $this + */ + public function setQueueResolver(callable $resolver) + { + $this->queueResolver = $resolver; + + return $this; + } +} diff --git a/vendor/illuminate/events/EventServiceProvider.php b/vendor/illuminate/events/EventServiceProvider.php new file mode 100755 index 0000000..54c24cd --- /dev/null +++ b/vendor/illuminate/events/EventServiceProvider.php @@ -0,0 +1,22 @@ +app->singleton('events', function ($app) { + return (new Dispatcher($app))->setQueueResolver(function () use ($app) { + return $app->make('Illuminate\Contracts\Queue\Factory'); + }); + }); + } +} diff --git a/vendor/illuminate/events/composer.json b/vendor/illuminate/events/composer.json new file mode 100755 index 0000000..4cbe705 --- /dev/null +++ b/vendor/illuminate/events/composer.json @@ -0,0 +1,33 @@ +{ + "name": "illuminate/events", + "description": "The Illuminate Events package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Events\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/filesystem/ClassFinder.php b/vendor/illuminate/filesystem/ClassFinder.php new file mode 100644 index 0000000..84f2c24 --- /dev/null +++ b/vendor/illuminate/filesystem/ClassFinder.php @@ -0,0 +1,145 @@ +in($directory)->name('*.php') as $file) { + $classes[] = $this->findClass($file->getRealPath()); + } + + return array_filter($classes); + } + + /** + * Extract the class name from the file at the given path. + * + * @param string $path + * @return string|null + */ + public function findClass($path) + { + $namespace = null; + + $tokens = token_get_all(file_get_contents($path)); + + foreach ($tokens as $key => $token) { + if ($this->tokenIsNamespace($token)) { + $namespace = $this->getNamespace($key + 2, $tokens); + } elseif ($this->tokenIsClassOrInterface($token)) { + return ltrim($namespace.'\\'.$this->getClass($key + 2, $tokens), '\\'); + } + } + } + + /** + * Find the namespace in the tokens starting at a given key. + * + * @param int $key + * @param array $tokens + * @return string|null + */ + protected function getNamespace($key, array $tokens) + { + $namespace = null; + + $tokenCount = count($tokens); + + for ($i = $key; $i < $tokenCount; $i++) { + if ($this->isPartOfNamespace($tokens[$i])) { + $namespace .= $tokens[$i][1]; + } elseif ($tokens[$i] == ';') { + return $namespace; + } + } + } + + /** + * Find the class in the tokens starting at a given key. + * + * @param int $key + * @param array $tokens + * @return string|null + */ + protected function getClass($key, array $tokens) + { + $class = null; + + $tokenCount = count($tokens); + + for ($i = $key; $i < $tokenCount; $i++) { + if ($this->isPartOfClass($tokens[$i])) { + $class .= $tokens[$i][1]; + } elseif ($this->isWhitespace($tokens[$i])) { + return $class; + } + } + } + + /** + * Determine if the given token is a namespace keyword. + * + * @param array|string $token + * @return bool + */ + protected function tokenIsNamespace($token) + { + return is_array($token) && $token[0] == T_NAMESPACE; + } + + /** + * Determine if the given token is a class or interface keyword. + * + * @param array|string $token + * @return bool + */ + protected function tokenIsClassOrInterface($token) + { + return is_array($token) && ($token[0] == T_CLASS || $token[0] == T_INTERFACE); + } + + /** + * Determine if the given token is part of the namespace. + * + * @param array|string $token + * @return bool + */ + protected function isPartOfNamespace($token) + { + return is_array($token) && ($token[0] == T_STRING || $token[0] == T_NS_SEPARATOR); + } + + /** + * Determine if the given token is part of the class. + * + * @param array|string $token + * @return bool + */ + protected function isPartOfClass($token) + { + return is_array($token) && $token[0] == T_STRING; + } + + /** + * Determine if the given token is whitespace. + * + * @param array|string $token + * @return bool + */ + protected function isWhitespace($token) + { + return is_array($token) && $token[0] == T_WHITESPACE; + } +} diff --git a/vendor/illuminate/filesystem/Filesystem.php b/vendor/illuminate/filesystem/Filesystem.php new file mode 100755 index 0000000..a989025 --- /dev/null +++ b/vendor/illuminate/filesystem/Filesystem.php @@ -0,0 +1,442 @@ +isFile($path)) { + return file_get_contents($path); + } + + throw new FileNotFoundException("File does not exist at path {$path}"); + } + + /** + * Get the returned value of a file. + * + * @param string $path + * @return mixed + * + * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + */ + public function getRequire($path) + { + if ($this->isFile($path)) { + return require $path; + } + + throw new FileNotFoundException("File does not exist at path {$path}"); + } + + /** + * Require the given file once. + * + * @param string $file + * @return mixed + */ + public function requireOnce($file) + { + require_once $file; + } + + /** + * Write the contents of a file. + * + * @param string $path + * @param string $contents + * @param bool $lock + * @return int + */ + public function put($path, $contents, $lock = false) + { + return file_put_contents($path, $contents, $lock ? LOCK_EX : 0); + } + + /** + * Prepend to a file. + * + * @param string $path + * @param string $data + * @return int + */ + public function prepend($path, $data) + { + if ($this->exists($path)) { + return $this->put($path, $data.$this->get($path)); + } + + return $this->put($path, $data); + } + + /** + * Append to a file. + * + * @param string $path + * @param string $data + * @return int + */ + public function append($path, $data) + { + return file_put_contents($path, $data, FILE_APPEND); + } + + /** + * Delete the file at a given path. + * + * @param string|array $paths + * @return bool + */ + public function delete($paths) + { + $paths = is_array($paths) ? $paths : func_get_args(); + + $success = true; + + foreach ($paths as $path) { + try { + if (! @unlink($path)) { + $success = false; + } + } catch (ErrorException $e) { + $success = false; + } + } + + return $success; + } + + /** + * Move a file to a new location. + * + * @param string $path + * @param string $target + * @return bool + */ + public function move($path, $target) + { + return rename($path, $target); + } + + /** + * Copy a file to a new location. + * + * @param string $path + * @param string $target + * @return bool + */ + public function copy($path, $target) + { + return copy($path, $target); + } + + /** + * Extract the file name from a file path. + * + * @param string $path + * @return string + */ + public function name($path) + { + return pathinfo($path, PATHINFO_FILENAME); + } + + /** + * Extract the file extension from a file path. + * + * @param string $path + * @return string + */ + public function extension($path) + { + return pathinfo($path, PATHINFO_EXTENSION); + } + + /** + * Get the file type of a given file. + * + * @param string $path + * @return string + */ + public function type($path) + { + return filetype($path); + } + + /** + * Get the mime-type of a given file. + * + * @param string $path + * @return string|false + */ + public function mimeType($path) + { + return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path); + } + + /** + * Get the file size of a given file. + * + * @param string $path + * @return int + */ + public function size($path) + { + return filesize($path); + } + + /** + * Get the file's last modification time. + * + * @param string $path + * @return int + */ + public function lastModified($path) + { + return filemtime($path); + } + + /** + * Determine if the given path is a directory. + * + * @param string $directory + * @return bool + */ + public function isDirectory($directory) + { + return is_dir($directory); + } + + /** + * Determine if the given path is writable. + * + * @param string $path + * @return bool + */ + public function isWritable($path) + { + return is_writable($path); + } + + /** + * Determine if the given path is a file. + * + * @param string $file + * @return bool + */ + public function isFile($file) + { + return is_file($file); + } + + /** + * Find path names matching a given pattern. + * + * @param string $pattern + * @param int $flags + * @return array + */ + public function glob($pattern, $flags = 0) + { + return glob($pattern, $flags); + } + + /** + * Get an array of all files in a directory. + * + * @param string $directory + * @return array + */ + public function files($directory) + { + $glob = glob($directory.'/*'); + + if ($glob === false) { + return []; + } + + // To get the appropriate files, we'll simply glob the directory and filter + // out any "files" that are not truly files so we do not end up with any + // directories in our list, but only true files within the directory. + return array_filter($glob, function ($file) { + return filetype($file) == 'file'; + }); + } + + /** + * Get all of the files from the given directory (recursive). + * + * @param string $directory + * @return array + */ + public function allFiles($directory) + { + return iterator_to_array(Finder::create()->files()->in($directory), false); + } + + /** + * Get all of the directories within a given directory. + * + * @param string $directory + * @return array + */ + public function directories($directory) + { + $directories = []; + + foreach (Finder::create()->in($directory)->directories()->depth(0) as $dir) { + $directories[] = $dir->getPathname(); + } + + return $directories; + } + + /** + * Create a directory. + * + * @param string $path + * @param int $mode + * @param bool $recursive + * @param bool $force + * @return bool + */ + public function makeDirectory($path, $mode = 0755, $recursive = false, $force = false) + { + if ($force) { + return @mkdir($path, $mode, $recursive); + } + + return mkdir($path, $mode, $recursive); + } + + /** + * Copy a directory from one location to another. + * + * @param string $directory + * @param string $destination + * @param int $options + * @return bool + */ + public function copyDirectory($directory, $destination, $options = null) + { + if (! $this->isDirectory($directory)) { + return false; + } + + $options = $options ?: FilesystemIterator::SKIP_DOTS; + + // If the destination directory does not actually exist, we will go ahead and + // create it recursively, which just gets the destination prepared to copy + // the files over. Once we make the directory we'll proceed the copying. + if (! $this->isDirectory($destination)) { + $this->makeDirectory($destination, 0777, true); + } + + $items = new FilesystemIterator($directory, $options); + + foreach ($items as $item) { + // As we spin through items, we will check to see if the current file is actually + // a directory or a file. When it is actually a directory we will need to call + // back into this function recursively to keep copying these nested folders. + $target = $destination.'/'.$item->getBasename(); + + if ($item->isDir()) { + $path = $item->getPathname(); + + if (! $this->copyDirectory($path, $target, $options)) { + return false; + } + } + + // If the current items is just a regular file, we will just copy this to the new + // location and keep looping. If for some reason the copy fails we'll bail out + // and return false, so the developer is aware that the copy process failed. + else { + if (! $this->copy($item->getPathname(), $target)) { + return false; + } + } + } + + return true; + } + + /** + * Recursively delete a directory. + * + * The directory itself may be optionally preserved. + * + * @param string $directory + * @param bool $preserve + * @return bool + */ + public function deleteDirectory($directory, $preserve = false) + { + if (! $this->isDirectory($directory)) { + return false; + } + + $items = new FilesystemIterator($directory); + + foreach ($items as $item) { + // If the item is a directory, we can just recurse into the function and + // delete that sub-directory otherwise we'll just delete the file and + // keep iterating through each file until the directory is cleaned. + if ($item->isDir() && ! $item->isLink()) { + $this->deleteDirectory($item->getPathname()); + } + + // If the item is just a file, we can go ahead and delete it since we're + // just looping through and waxing all of the files in this directory + // and calling directories recursively, so we delete the real path. + else { + $this->delete($item->getPathname()); + } + } + + if (! $preserve) { + @rmdir($directory); + } + + return true; + } + + /** + * Empty the specified directory of all files and folders. + * + * @param string $directory + * @return bool + */ + public function cleanDirectory($directory) + { + return $this->deleteDirectory($directory, true); + } +} diff --git a/vendor/illuminate/filesystem/FilesystemAdapter.php b/vendor/illuminate/filesystem/FilesystemAdapter.php new file mode 100644 index 0000000..3643493 --- /dev/null +++ b/vendor/illuminate/filesystem/FilesystemAdapter.php @@ -0,0 +1,349 @@ +driver = $driver; + } + + /** + * Determine if a file exists. + * + * @param string $path + * @return bool + */ + public function exists($path) + { + return $this->driver->has($path); + } + + /** + * Get the contents of a file. + * + * @param string $path + * @return string + * + * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + */ + public function get($path) + { + try { + return $this->driver->read($path); + } catch (FileNotFoundException $e) { + throw new ContractFileNotFoundException($path, $e->getCode(), $e); + } + } + + /** + * Write the contents of a file. + * + * @param string $path + * @param string|resource $contents + * @param string $visibility + * @return bool + */ + public function put($path, $contents, $visibility = null) + { + $config = ['visibility' => $this->parseVisibility($visibility)]; + + if (is_resource($contents)) { + return $this->driver->putStream($path, $contents, $config); + } else { + return $this->driver->put($path, $contents, $config); + } + } + + /** + * Get the visibility for the given path. + * + * @param string $path + * @return string + */ + public function getVisibility($path) + { + if ($this->driver->getVisibility($path) == AdapterInterface::VISIBILITY_PUBLIC) { + return FilesystemContract::VISIBILITY_PUBLIC; + } + + return FilesystemContract::VISIBILITY_PRIVATE; + } + + /** + * Set the visibility for the given path. + * + * @param string $path + * @param string $visibility + * @return void + */ + public function setVisibility($path, $visibility) + { + return $this->driver->setVisibility($path, $this->parseVisibility($visibility)); + } + + /** + * Prepend to a file. + * + * @param string $path + * @param string $data + * @return int + */ + public function prepend($path, $data) + { + if ($this->exists($path)) { + return $this->put($path, $data.PHP_EOL.$this->get($path)); + } + + return $this->put($path, $data); + } + + /** + * Append to a file. + * + * @param string $path + * @param string $data + * @return int + */ + public function append($path, $data) + { + if ($this->exists($path)) { + return $this->put($path, $this->get($path).PHP_EOL.$data); + } + + return $this->put($path, $data); + } + + /** + * Delete the file at a given path. + * + * @param string|array $paths + * @return bool + */ + public function delete($paths) + { + $paths = is_array($paths) ? $paths : func_get_args(); + + foreach ($paths as $path) { + $this->driver->delete($path); + } + + return true; + } + + /** + * Copy a file to a new location. + * + * @param string $from + * @param string $to + * @return bool + */ + public function copy($from, $to) + { + return $this->driver->copy($from, $to); + } + + /** + * Move a file to a new location. + * + * @param string $from + * @param string $to + * @return bool + */ + public function move($from, $to) + { + return $this->driver->rename($from, $to); + } + + /** + * Get the file size of a given file. + * + * @param string $path + * @return int + */ + public function size($path) + { + return $this->driver->getSize($path); + } + + /** + * Get the mime-type of a given file. + * + * @param string $path + * @return string|false + */ + public function mimeType($path) + { + return $this->driver->getMimetype($path); + } + + /** + * Get the file's last modification time. + * + * @param string $path + * @return int + */ + public function lastModified($path) + { + return $this->driver->getTimestamp($path); + } + + /** + * Get an array of all files in a directory. + * + * @param string|null $directory + * @param bool $recursive + * @return array + */ + public function files($directory = null, $recursive = false) + { + $contents = $this->driver->listContents($directory, $recursive); + + return $this->filterContentsByType($contents, 'file'); + } + + /** + * Get all of the files from the given directory (recursive). + * + * @param string|null $directory + * @return array + */ + public function allFiles($directory = null) + { + return $this->files($directory, true); + } + + /** + * Get all of the directories within a given directory. + * + * @param string|null $directory + * @param bool $recursive + * @return array + */ + public function directories($directory = null, $recursive = false) + { + $contents = $this->driver->listContents($directory, $recursive); + + return $this->filterContentsByType($contents, 'dir'); + } + + /** + * Get all (recursive) of the directories within a given directory. + * + * @param string|null $directory + * @return array + */ + public function allDirectories($directory = null) + { + return $this->directories($directory, true); + } + + /** + * Create a directory. + * + * @param string $path + * @return bool + */ + public function makeDirectory($path) + { + return $this->driver->createDir($path); + } + + /** + * Recursively delete a directory. + * + * @param string $directory + * @return bool + */ + public function deleteDirectory($directory) + { + return $this->driver->deleteDir($directory); + } + + /** + * Get the Flysystem driver. + * + * @return \League\Flysystem\FilesystemInterface + */ + public function getDriver() + { + return $this->driver; + } + + /** + * Filter directory contents by type. + * + * @param array $contents + * @param string $type + * @return array + */ + protected function filterContentsByType($contents, $type) + { + return Collection::make($contents) + ->where('type', $type) + ->pluck('path') + ->values() + ->all(); + } + + /** + * Parse the given visibility value. + * + * @param string|null $visibility + * @return string|null + * @throws \InvalidArgumentException + */ + protected function parseVisibility($visibility) + { + if (is_null($visibility)) { + return; + } + + switch ($visibility) { + case FilesystemContract::VISIBILITY_PUBLIC: + return AdapterInterface::VISIBILITY_PUBLIC; + + case FilesystemContract::VISIBILITY_PRIVATE: + return AdapterInterface::VISIBILITY_PRIVATE; + } + + throw new InvalidArgumentException('Unknown visibility: '.$visibility); + } + + /** + * Pass dynamic methods call onto Flysystem. + * + * @param string $method + * @param array $parameters + * @return mixed + * + * @throws \BadMethodCallException + */ + public function __call($method, array $parameters) + { + return call_user_func_array([$this->driver, $method], $parameters); + } +} diff --git a/vendor/illuminate/filesystem/FilesystemManager.php b/vendor/illuminate/filesystem/FilesystemManager.php new file mode 100644 index 0000000..8d1b82b --- /dev/null +++ b/vendor/illuminate/filesystem/FilesystemManager.php @@ -0,0 +1,274 @@ +app = $app; + } + + /** + * Get a filesystem instance. + * + * @param string $name + * @return \Illuminate\Contracts\Filesystem\Filesystem + */ + public function drive($name = null) + { + return $this->disk($name); + } + + /** + * Get a filesystem instance. + * + * @param string $name + * @return \Illuminate\Contracts\Filesystem\Filesystem + */ + public function disk($name = null) + { + $name = $name ?: $this->getDefaultDriver(); + + return $this->disks[$name] = $this->get($name); + } + + /** + * Attempt to get the disk from the local cache. + * + * @param string $name + * @return \Illuminate\Contracts\Filesystem\Filesystem + */ + protected function get($name) + { + return isset($this->disks[$name]) ? $this->disks[$name] : $this->resolve($name); + } + + /** + * Resolve the given disk. + * + * @param string $name + * @return \Illuminate\Contracts\Filesystem\Filesystem + */ + protected function resolve($name) + { + $config = $this->getConfig($name); + + if (isset($this->customCreators[$config['driver']])) { + return $this->callCustomCreator($config); + } + + return $this->{'create'.ucfirst($config['driver']).'Driver'}($config); + } + + /** + * Call a custom driver creator. + * + * @param array $config + * @return \Illuminate\Contracts\Filesystem\Filesystem + */ + protected function callCustomCreator(array $config) + { + $driver = $this->customCreators[$config['driver']]($this->app, $config); + + if ($driver instanceof FilesystemInterface) { + return $this->adapt($driver); + } + + return $driver; + } + + /** + * Create an instance of the local driver. + * + * @param array $config + * @return \Illuminate\Contracts\Filesystem\Filesystem + */ + public function createLocalDriver(array $config) + { + $permissions = isset($config['permissions']) ? $config['permissions'] : []; + + return $this->adapt(new Flysystem(new LocalAdapter( + $config['root'], LOCK_EX, LocalAdapter::DISALLOW_LINKS, $permissions + ))); + } + + /** + * Create an instance of the ftp driver. + * + * @param array $config + * @return \Illuminate\Contracts\Filesystem\Filesystem + */ + public function createFtpDriver(array $config) + { + $ftpConfig = Arr::only($config, [ + 'host', 'username', 'password', 'port', 'root', 'passive', 'ssl', 'timeout', + ]); + + return $this->adapt(new Flysystem(new FtpAdapter($ftpConfig))); + } + + /** + * Create an instance of the Amazon S3 driver. + * + * @param array $config + * @return \Illuminate\Contracts\Filesystem\Cloud + */ + public function createS3Driver(array $config) + { + $config = $this->formatS3Config($config); + + $root = isset($config['root']) ? $config['root'] : null; + + return $this->adapt( + new Flysystem(new S3Adapter(new S3Client($config), $config['bucket'], $root)) + ); + } + + /** + * Format the given S3 configuration with the default options. + * + * @param array $config + * @return array + */ + protected function formatS3Config(array $config) + { + $config += ['version' => 'latest']; + + if ($config['key'] && $config['secret']) { + $config['credentials'] = Arr::only($config, ['key', 'secret']); + } + + return $config; + } + + /** + * Create an instance of the Rackspace driver. + * + * @param array $config + * @return \Illuminate\Contracts\Filesystem\Cloud + */ + public function createRackspaceDriver(array $config) + { + $client = new Rackspace($config['endpoint'], [ + 'username' => $config['username'], 'apiKey' => $config['key'], + ]); + + return $this->adapt(new Flysystem( + new RackspaceAdapter($this->getRackspaceContainer($client, $config)) + )); + } + + /** + * Get the Rackspace Cloud Files container. + * + * @param \OpenCloud\Rackspace $client + * @param array $config + * @return \OpenCloud\ObjectStore\Resource\Container + */ + protected function getRackspaceContainer(Rackspace $client, array $config) + { + $urlType = Arr::get($config, 'url_type'); + + $store = $client->objectStoreService('cloudFiles', $config['region'], $urlType); + + return $store->getContainer($config['container']); + } + + /** + * Adapt the filesystem implementation. + * + * @param \League\Flysystem\FilesystemInterface $filesystem + * @return \Illuminate\Contracts\Filesystem\Filesystem + */ + protected function adapt(FilesystemInterface $filesystem) + { + return new FilesystemAdapter($filesystem); + } + + /** + * Get the filesystem connection configuration. + * + * @param string $name + * @return array + */ + protected function getConfig($name) + { + return $this->app['config']["filesystems.disks.{$name}"]; + } + + /** + * Get the default driver name. + * + * @return string + */ + public function getDefaultDriver() + { + return $this->app['config']['filesystems.default']; + } + + /** + * Register a custom driver creator Closure. + * + * @param string $driver + * @param \Closure $callback + * @return $this + */ + public function extend($driver, Closure $callback) + { + $this->customCreators[$driver] = $callback; + + return $this; + } + + /** + * Dynamically call the default driver instance. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->disk(), $method], $parameters); + } +} diff --git a/vendor/illuminate/filesystem/FilesystemServiceProvider.php b/vendor/illuminate/filesystem/FilesystemServiceProvider.php new file mode 100755 index 0000000..5e16866 --- /dev/null +++ b/vendor/illuminate/filesystem/FilesystemServiceProvider.php @@ -0,0 +1,80 @@ +registerNativeFilesystem(); + + $this->registerFlysystem(); + } + + /** + * Register the native filesystem implementation. + * + * @return void + */ + protected function registerNativeFilesystem() + { + $this->app->singleton('files', function () { return new Filesystem; }); + } + + /** + * Register the driver based filesystem. + * + * @return void + */ + protected function registerFlysystem() + { + $this->registerManager(); + + $this->app->singleton('filesystem.disk', function () { + return $this->app['filesystem']->disk($this->getDefaultDriver()); + }); + + $this->app->singleton('filesystem.cloud', function () { + return $this->app['filesystem']->disk($this->getCloudDriver()); + }); + } + + /** + * Register the filesystem manager. + * + * @return void + */ + protected function registerManager() + { + $this->app->singleton('filesystem', function () { + return new FilesystemManager($this->app); + }); + } + + /** + * Get the default file driver. + * + * @return string + */ + protected function getDefaultDriver() + { + return $this->app['config']['filesystems.default']; + } + + /** + * Get the default cloud based file driver. + * + * @return string + */ + protected function getCloudDriver() + { + return $this->app['config']['filesystems.cloud']; + } +} diff --git a/vendor/illuminate/filesystem/composer.json b/vendor/illuminate/filesystem/composer.json new file mode 100755 index 0000000..a00fa40 --- /dev/null +++ b/vendor/illuminate/filesystem/composer.json @@ -0,0 +1,38 @@ +{ + "name": "illuminate/filesystem", + "description": "The Illuminate Filesystem package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "symfony/finder": "2.7.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Filesystem\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "league/flysystem": "Required to use the Flysystem local and FTP drivers (~1.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", + "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/hashing/BcryptHasher.php b/vendor/illuminate/hashing/BcryptHasher.php new file mode 100755 index 0000000..39acc88 --- /dev/null +++ b/vendor/illuminate/hashing/BcryptHasher.php @@ -0,0 +1,82 @@ +rounds; + + $hash = password_hash($value, PASSWORD_BCRYPT, ['cost' => $cost]); + + if ($hash === false) { + throw new RuntimeException('Bcrypt hashing not supported.'); + } + + return $hash; + } + + /** + * Check the given plain value against a hash. + * + * @param string $value + * @param string $hashedValue + * @param array $options + * @return bool + */ + public function check($value, $hashedValue, array $options = []) + { + if (strlen($hashedValue) === 0) { + return false; + } + + return password_verify($value, $hashedValue); + } + + /** + * Check if the given hash has been hashed using the given options. + * + * @param string $hashedValue + * @param array $options + * @return bool + */ + public function needsRehash($hashedValue, array $options = []) + { + $cost = isset($options['rounds']) ? $options['rounds'] : $this->rounds; + + return password_needs_rehash($hashedValue, PASSWORD_BCRYPT, ['cost' => $cost]); + } + + /** + * Set the default password work factor. + * + * @param int $rounds + * @return $this + */ + public function setRounds($rounds) + { + $this->rounds = (int) $rounds; + + return $this; + } +} diff --git a/vendor/illuminate/hashing/HashServiceProvider.php b/vendor/illuminate/hashing/HashServiceProvider.php new file mode 100755 index 0000000..819e9ed --- /dev/null +++ b/vendor/illuminate/hashing/HashServiceProvider.php @@ -0,0 +1,35 @@ +app->singleton('hash', function () { return new BcryptHasher; }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return ['hash']; + } +} diff --git a/vendor/illuminate/hashing/composer.json b/vendor/illuminate/hashing/composer.json new file mode 100755 index 0000000..d2ccf86 --- /dev/null +++ b/vendor/illuminate/hashing/composer.json @@ -0,0 +1,32 @@ +{ + "name": "illuminate/hashing", + "description": "The Illuminate Hashing package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Hashing\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/http/Exception/HttpResponseException.php b/vendor/illuminate/http/Exception/HttpResponseException.php new file mode 100644 index 0000000..0dcf48a --- /dev/null +++ b/vendor/illuminate/http/Exception/HttpResponseException.php @@ -0,0 +1,37 @@ +response = $response; + } + + /** + * Get the underlying response instance. + * + * @return \Symfony\Component\HttpFoundation\Response + */ + public function getResponse() + { + return $this->response; + } +} diff --git a/vendor/illuminate/http/Exception/PostTooLargeException.php b/vendor/illuminate/http/Exception/PostTooLargeException.php new file mode 100644 index 0000000..f0b7a67 --- /dev/null +++ b/vendor/illuminate/http/Exception/PostTooLargeException.php @@ -0,0 +1,10 @@ +jsonOptions = $options; + + parent::__construct($data, $status, $headers); + } + + /** + * Get the json_decoded data from the response. + * + * @param bool $assoc + * @param int $depth + * @return mixed + */ + public function getData($assoc = false, $depth = 512) + { + return json_decode($this->data, $assoc, $depth); + } + + /** + * {@inheritdoc} + */ + public function setData($data = []) + { + $this->data = $data instanceof Jsonable + ? $data->toJson($this->jsonOptions) + : json_encode($data, $this->jsonOptions); + + return $this->update(); + } + + /** + * Get the JSON encoding options. + * + * @return int + */ + public function getJsonOptions() + { + return $this->jsonOptions; + } + + /** + * Set the JSON encoding options. + * + * @param int $options + * @return mixed + */ + public function setJsonOptions($options) + { + $this->jsonOptions = $options; + + return $this->setData($this->getData()); + } +} diff --git a/vendor/illuminate/http/Middleware/FrameGuard.php b/vendor/illuminate/http/Middleware/FrameGuard.php new file mode 100644 index 0000000..b5d3f3c --- /dev/null +++ b/vendor/illuminate/http/Middleware/FrameGuard.php @@ -0,0 +1,24 @@ +headers->set('X-Frame-Options', 'SAMEORIGIN', false); + + return $response; + } +} diff --git a/vendor/illuminate/http/RedirectResponse.php b/vendor/illuminate/http/RedirectResponse.php new file mode 100755 index 0000000..629cac1 --- /dev/null +++ b/vendor/illuminate/http/RedirectResponse.php @@ -0,0 +1,200 @@ + $value]; + + foreach ($key as $k => $v) { + $this->session->flash($k, $v); + } + + return $this; + } + + /** + * Add multiple cookies to the response. + * + * @param array $cookies + * @return $this + */ + public function withCookies(array $cookies) + { + foreach ($cookies as $cookie) { + $this->headers->setCookie($cookie); + } + + return $this; + } + + /** + * Flash an array of input to the session. + * + * @param array $input + * @return $this + */ + public function withInput(array $input = null) + { + $input = $input ?: $this->request->input(); + + $this->session->flashInput($data = array_filter($input, $callback = function (&$value) use (&$callback) { + if (is_array($value)) { + $value = array_filter($value, $callback); + } + + return ! $value instanceof UploadedFile; + })); + + return $this; + } + + /** + * Flash an array of input to the session. + * + * @param mixed string + * @return $this + */ + public function onlyInput() + { + return $this->withInput($this->request->only(func_get_args())); + } + + /** + * Flash an array of input to the session. + * + * @param mixed string + * @return \Illuminate\Http\RedirectResponse + */ + public function exceptInput() + { + return $this->withInput($this->request->except(func_get_args())); + } + + /** + * Flash a container of errors to the session. + * + * @param \Illuminate\Contracts\Support\MessageProvider|array|string $provider + * @param string $key + * @return $this + */ + public function withErrors($provider, $key = 'default') + { + $value = $this->parseErrors($provider); + + $this->session->flash( + 'errors', $this->session->get('errors', new ViewErrorBag)->put($key, $value) + ); + + return $this; + } + + /** + * Parse the given errors into an appropriate value. + * + * @param \Illuminate\Contracts\Support\MessageProvider|array|string $provider + * @return \Illuminate\Support\MessageBag + */ + protected function parseErrors($provider) + { + if ($provider instanceof MessageProvider) { + return $provider->getMessageBag(); + } + + return new MessageBag((array) $provider); + } + + /** + * Get the request instance. + * + * @return \Illuminate\Http\Request|null + */ + public function getRequest() + { + return $this->request; + } + + /** + * Set the request instance. + * + * @param \Illuminate\Http\Request $request + * @return void + */ + public function setRequest(Request $request) + { + $this->request = $request; + } + + /** + * Get the session store implementation. + * + * @return \Illuminate\Session\Store|null + */ + public function getSession() + { + return $this->session; + } + + /** + * Set the session store implementation. + * + * @param \Illuminate\Session\Store $session + * @return void + */ + public function setSession(SessionStore $session) + { + $this->session = $session; + } + + /** + * Dynamically bind flash data in the session. + * + * @param string $method + * @param array $parameters + * @return $this + * + * @throws \BadMethodCallException + */ + public function __call($method, $parameters) + { + if (Str::startsWith($method, 'with')) { + return $this->with(Str::snake(substr($method, 4)), $parameters[0]); + } + + throw new BadMethodCallException("Method [$method] does not exist on Redirect."); + } +} diff --git a/vendor/illuminate/http/Request.php b/vendor/illuminate/http/Request.php new file mode 100755 index 0000000..f59d3c9 --- /dev/null +++ b/vendor/illuminate/http/Request.php @@ -0,0 +1,910 @@ +getMethod(); + } + + /** + * Get the root URL for the application. + * + * @return string + */ + public function root() + { + return rtrim($this->getSchemeAndHttpHost().$this->getBaseUrl(), '/'); + } + + /** + * Get the URL (no query string) for the request. + * + * @return string + */ + public function url() + { + return rtrim(preg_replace('/\?.*/', '', $this->getUri()), '/'); + } + + /** + * Get the full URL for the request. + * + * @return string + */ + public function fullUrl() + { + $query = $this->getQueryString(); + + return $query ? $this->url().'?'.$query : $this->url(); + } + + /** + * Get the current path info for the request. + * + * @return string + */ + public function path() + { + $pattern = trim($this->getPathInfo(), '/'); + + return $pattern == '' ? '/' : $pattern; + } + + /** + * Get the current encoded path info for the request. + * + * @return string + */ + public function decodedPath() + { + return rawurldecode($this->path()); + } + + /** + * Get a segment from the URI (1 based index). + * + * @param int $index + * @param string|null $default + * @return string|null + */ + public function segment($index, $default = null) + { + return Arr::get($this->segments(), $index - 1, $default); + } + + /** + * Get all of the segments for the request path. + * + * @return array + */ + public function segments() + { + $segments = explode('/', $this->path()); + + return array_values(array_filter($segments, function ($v) { return $v != ''; })); + } + + /** + * Determine if the current request URI matches a pattern. + * + * @param mixed string + * @return bool + */ + public function is() + { + foreach (func_get_args() as $pattern) { + if (Str::is($pattern, urldecode($this->path()))) { + return true; + } + } + + return false; + } + + /** + * Determine if the request is the result of an AJAX call. + * + * @return bool + */ + public function ajax() + { + return $this->isXmlHttpRequest(); + } + + /** + * Determine if the request is the result of an PJAX call. + * + * @return bool + */ + public function pjax() + { + return $this->headers->get('X-PJAX') == true; + } + + /** + * Determine if the request is over HTTPS. + * + * @return bool + */ + public function secure() + { + return $this->isSecure(); + } + + /** + * Returns the client IP address. + * + * @return string + */ + public function ip() + { + return $this->getClientIp(); + } + + /** + * Returns the client IP addresses. + * + * @return array + */ + public function ips() + { + return $this->getClientIps(); + } + + /** + * Determine if the request contains a given input item key. + * + * @param string|array $key + * @return bool + */ + public function exists($key) + { + $keys = is_array($key) ? $key : func_get_args(); + + $input = $this->all(); + + foreach ($keys as $value) { + if (! array_key_exists($value, $input)) { + return false; + } + } + + return true; + } + + /** + * Determine if the request contains a non-empty value for an input item. + * + * @param string|array $key + * @return bool + */ + public function has($key) + { + $keys = is_array($key) ? $key : func_get_args(); + + foreach ($keys as $value) { + if ($this->isEmptyString($value)) { + return false; + } + } + + return true; + } + + /** + * Determine if the given input key is an empty string for "has". + * + * @param string $key + * @return bool + */ + protected function isEmptyString($key) + { + $value = $this->input($key); + + $boolOrArray = is_bool($value) || is_array($value); + + return ! $boolOrArray && trim((string) $value) === ''; + } + + /** + * Get all of the input and files for the request. + * + * @return array + */ + public function all() + { + return array_replace_recursive($this->input(), $this->files->all()); + } + + /** + * Retrieve an input item from the request. + * + * @param string $key + * @param string|array|null $default + * @return string|array + */ + public function input($key = null, $default = null) + { + $input = $this->getInputSource()->all() + $this->query->all(); + + return Arr::get($input, $key, $default); + } + + /** + * Get a subset of the items from the input data. + * + * @param array $keys + * @return array + */ + public function only($keys) + { + $keys = is_array($keys) ? $keys : func_get_args(); + + $results = []; + + $input = $this->all(); + + foreach ($keys as $key) { + Arr::set($results, $key, Arr::get($input, $key)); + } + + return $results; + } + + /** + * Get all of the input except for a specified array of items. + * + * @param array|mixed $keys + * @return array + */ + public function except($keys) + { + $keys = is_array($keys) ? $keys : func_get_args(); + + $results = $this->all(); + + Arr::forget($results, $keys); + + return $results; + } + + /** + * Retrieve a query string item from the request. + * + * @param string $key + * @param string|array|null $default + * @return string|array + */ + public function query($key = null, $default = null) + { + return $this->retrieveItem('query', $key, $default); + } + + /** + * Determine if a cookie is set on the request. + * + * @param string $key + * @return bool + */ + public function hasCookie($key) + { + return ! is_null($this->cookie($key)); + } + + /** + * Retrieve a cookie from the request. + * + * @param string $key + * @param string|array|null $default + * @return string|array + */ + public function cookie($key = null, $default = null) + { + return $this->retrieveItem('cookies', $key, $default); + } + + /** + * Retrieve a file from the request. + * + * @param string $key + * @param mixed $default + * @return \Symfony\Component\HttpFoundation\File\UploadedFile|array|null + */ + public function file($key = null, $default = null) + { + return Arr::get($this->files->all(), $key, $default); + } + + /** + * Determine if the uploaded data contains a file. + * + * @param string $key + * @return bool + */ + public function hasFile($key) + { + if (! is_array($files = $this->file($key))) { + $files = [$files]; + } + + foreach ($files as $file) { + if ($this->isValidFile($file)) { + return true; + } + } + + return false; + } + + /** + * Check that the given file is a valid file instance. + * + * @param mixed $file + * @return bool + */ + protected function isValidFile($file) + { + return $file instanceof SplFileInfo && $file->getPath() != ''; + } + + /** + * Retrieve a header from the request. + * + * @param string $key + * @param string|array|null $default + * @return string|array + */ + public function header($key = null, $default = null) + { + return $this->retrieveItem('headers', $key, $default); + } + + /** + * Retrieve a server variable from the request. + * + * @param string $key + * @param string|array|null $default + * @return string|array + */ + public function server($key = null, $default = null) + { + return $this->retrieveItem('server', $key, $default); + } + + /** + * Retrieve an old input item. + * + * @param string $key + * @param string|array|null $default + * @return string|array + */ + public function old($key = null, $default = null) + { + return $this->session()->getOldInput($key, $default); + } + + /** + * Flash the input for the current request to the session. + * + * @param string $filter + * @param array $keys + * @return void + */ + public function flash($filter = null, $keys = []) + { + $flash = (! is_null($filter)) ? $this->$filter($keys) : $this->input(); + + $this->session()->flashInput($flash); + } + + /** + * Flash only some of the input to the session. + * + * @param array|mixed $keys + * @return void + */ + public function flashOnly($keys) + { + $keys = is_array($keys) ? $keys : func_get_args(); + + return $this->flash('only', $keys); + } + + /** + * Flash only some of the input to the session. + * + * @param array|mixed $keys + * @return void + */ + public function flashExcept($keys) + { + $keys = is_array($keys) ? $keys : func_get_args(); + + return $this->flash('except', $keys); + } + + /** + * Flush all of the old input from the session. + * + * @return void + */ + public function flush() + { + $this->session()->flashInput([]); + } + + /** + * Retrieve a parameter item from a given source. + * + * @param string $source + * @param string $key + * @param string|array|null $default + * @return string|array + */ + protected function retrieveItem($source, $key, $default) + { + if (is_null($key)) { + return $this->$source->all(); + } + + return $this->$source->get($key, $default, true); + } + + /** + * Merge new input into the current request's input array. + * + * @param array $input + * @return void + */ + public function merge(array $input) + { + $this->getInputSource()->add($input); + } + + /** + * Replace the input for the current request. + * + * @param array $input + * @return void + */ + public function replace(array $input) + { + $this->getInputSource()->replace($input); + } + + /** + * Get the JSON payload for the request. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function json($key = null, $default = null) + { + if (! isset($this->json)) { + $this->json = new ParameterBag((array) json_decode($this->getContent(), true)); + } + + if (is_null($key)) { + return $this->json; + } + + return Arr::get($this->json->all(), $key, $default); + } + + /** + * Get the input source for the request. + * + * @return \Symfony\Component\HttpFoundation\ParameterBag + */ + protected function getInputSource() + { + if ($this->isJson()) { + return $this->json(); + } + + return $this->getMethod() == 'GET' ? $this->query : $this->request; + } + + /** + * Determine if the given content types match. + * + * @param string $actual + * @param string $type + * @return bool + */ + public static function matchesType($actual, $type) + { + if ($actual === $type) { + return true; + } + + $split = explode('/', $actual); + + if (isset($split[1]) && preg_match('/'.$split[0].'\/.+\+'.$split[1].'/', $type)) { + return true; + } + + return false; + } + + /** + * Determine if the request is sending JSON. + * + * @return bool + */ + public function isJson() + { + return Str::contains($this->header('CONTENT_TYPE'), '/json'); + } + + /** + * Determine if the current request is asking for JSON in return. + * + * @return bool + */ + public function wantsJson() + { + $acceptable = $this->getAcceptableContentTypes(); + + return isset($acceptable[0]) && $acceptable[0] === 'application/json'; + } + + /** + * Determines whether the current requests accepts a given content type. + * + * @param string|array $contentTypes + * @return bool + */ + public function accepts($contentTypes) + { + $accepts = $this->getAcceptableContentTypes(); + + if (count($accepts) === 0) { + return true; + } + + $types = (array) $contentTypes; + + foreach ($accepts as $accept) { + if ($accept === '*/*' || $accept === '*') { + return true; + } + + foreach ($types as $type) { + if ($this->matchesType($accept, $type) || $accept === strtok($type, '/').'/*') { + return true; + } + } + } + + return false; + } + + /** + * Return the most suitable content type from the given array based on content negotiation. + * + * @param string|array $contentTypes + * @return string|null + */ + public function prefers($contentTypes) + { + $accepts = $this->getAcceptableContentTypes(); + + $contentTypes = (array) $contentTypes; + + foreach ($accepts as $accept) { + if (in_array($accept, ['*/*', '*'])) { + return $contentTypes[0]; + } + + foreach ($contentTypes as $contentType) { + $type = $contentType; + + if (! is_null($mimeType = $this->getMimeType($contentType))) { + $type = $mimeType; + } + + if ($this->matchesType($type, $accept) || $accept === strtok($type, '/').'/*') { + return $contentType; + } + } + } + } + + /** + * Determines whether a request accepts JSON. + * + * @return bool + */ + public function acceptsJson() + { + return $this->accepts('application/json'); + } + + /** + * Determines whether a request accepts HTML. + * + * @return bool + */ + public function acceptsHtml() + { + return $this->accepts('text/html'); + } + + /** + * Get the data format expected in the response. + * + * @param string $default + * @return string + */ + public function format($default = 'html') + { + foreach ($this->getAcceptableContentTypes() as $type) { + if ($format = $this->getFormat($type)) { + return $format; + } + } + + return $default; + } + + /** + * Create an Illuminate request from a Symfony instance. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * @return \Illuminate\Http\Request + */ + public static function createFromBase(SymfonyRequest $request) + { + if ($request instanceof static) { + return $request; + } + + $content = $request->content; + + $request = (new static)->duplicate( + + $request->query->all(), $request->request->all(), $request->attributes->all(), + + $request->cookies->all(), $request->files->all(), $request->server->all() + ); + + $request->content = $content; + + $request->request = $request->getInputSource(); + + return $request; + } + + /** + * {@inheritdoc} + */ + public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null) + { + return parent::duplicate($query, $request, $attributes, $cookies, array_filter((array) $files), $server); + } + + /** + * Get the session associated with the request. + * + * @return \Illuminate\Session\Store + * + * @throws \RuntimeException + */ + public function session() + { + if (! $this->hasSession()) { + throw new RuntimeException('Session store not set on request.'); + } + + return $this->getSession(); + } + + /** + * Get the user making the request. + * + * @return mixed + */ + public function user() + { + return call_user_func($this->getUserResolver()); + } + + /** + * Get the route handling the request. + * + * @param string|null $param + * + * @return \Illuminate\Routing\Route|object|string + */ + public function route($param = null) + { + $route = call_user_func($this->getRouteResolver()); + + if (is_null($route) || is_null($param)) { + return $route; + } else { + return $route->parameter($param); + } + } + + /** + * Get the user resolver callback. + * + * @return \Closure + */ + public function getUserResolver() + { + return $this->userResolver ?: function () {}; + } + + /** + * Set the user resolver callback. + * + * @param \Closure $callback + * @return $this + */ + public function setUserResolver(Closure $callback) + { + $this->userResolver = $callback; + + return $this; + } + + /** + * Get the route resolver callback. + * + * @return \Closure + */ + public function getRouteResolver() + { + return $this->routeResolver ?: function () {}; + } + + /** + * Set the route resolver callback. + * + * @param \Closure $callback + * @return $this + */ + public function setRouteResolver(Closure $callback) + { + $this->routeResolver = $callback; + + return $this; + } + + /** + * Determine if the given offset exists. + * + * @param string $offset + * @return bool + */ + public function offsetExists($offset) + { + return array_key_exists($offset, $this->all()); + } + + /** + * Get the value at the given offset. + * + * @param string $offset + * @return mixed + */ + public function offsetGet($offset) + { + return Arr::get($this->all(), $offset); + } + + /** + * Set the value at the given offset. + * + * @param string $offset + * @param mixed $value + * @return void + */ + public function offsetSet($offset, $value) + { + return $this->getInputSource()->set($offset, $value); + } + + /** + * Remove the value at the given offset. + * + * @param string $offset + * @return void + */ + public function offsetUnset($offset) + { + return $this->getInputSource()->remove($offset); + } + + /** + * Check if an input element is set on the request. + * + * @param string $key + * @return bool + */ + public function __isset($key) + { + return ! is_null($this->__get($key)); + } + + /** + * Get an input element from the request. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + $all = $this->all(); + + if (array_key_exists($key, $all)) { + return $all[$key]; + } else { + return $this->route($key); + } + } +} diff --git a/vendor/illuminate/http/Response.php b/vendor/illuminate/http/Response.php new file mode 100755 index 0000000..3c9299d --- /dev/null +++ b/vendor/illuminate/http/Response.php @@ -0,0 +1,94 @@ +original = $content; + + // If the content is "JSONable" we will set the appropriate header and convert + // the content to JSON. This is useful when returning something like models + // from routes that will be automatically transformed to their JSON form. + if ($this->shouldBeJson($content)) { + $this->header('Content-Type', 'application/json'); + + $content = $this->morphToJson($content); + } + + // If this content implements the "Renderable" interface then we will call the + // render method on the object so we will avoid any "__toString" exceptions + // that might be thrown and have their errors obscured by PHP's handling. + elseif ($content instanceof Renderable) { + $content = $content->render(); + } + + return parent::setContent($content); + } + + /** + * Morph the given content into JSON. + * + * @param mixed $content + * @return string + */ + protected function morphToJson($content) + { + if ($content instanceof Jsonable) { + return $content->toJson(); + } + + return json_encode($content); + } + + /** + * Determine if the given content should be turned into JSON. + * + * @param mixed $content + * @return bool + */ + protected function shouldBeJson($content) + { + return $content instanceof Jsonable || + $content instanceof ArrayObject || + is_array($content); + } + + /** + * Get the original response content. + * + * @return mixed + */ + public function getOriginalContent() + { + return $this->original; + } +} diff --git a/vendor/illuminate/http/ResponseTrait.php b/vendor/illuminate/http/ResponseTrait.php new file mode 100644 index 0000000..56ddc6a --- /dev/null +++ b/vendor/illuminate/http/ResponseTrait.php @@ -0,0 +1,58 @@ +getStatusCode(); + } + + /** + * Get the content of the response. + * + * @return string + */ + public function content() + { + return $this->getContent(); + } + + /** + * Set a header on the Response. + * + * @param string $key + * @param string $value + * @param bool $replace + * @return $this + */ + public function header($key, $value, $replace = true) + { + $this->headers->set($key, $value, $replace); + + return $this; + } + + /** + * Add a cookie to the response. + * + * @param \Symfony\Component\HttpFoundation\Cookie|mixed $cookie + * @return $this + */ + public function withCookie($cookie) + { + if (is_string($cookie) && function_exists('cookie')) { + $cookie = call_user_func_array('cookie', func_get_args()); + } + + $this->headers->setCookie($cookie); + + return $this; + } +} diff --git a/vendor/illuminate/http/composer.json b/vendor/illuminate/http/composer.json new file mode 100755 index 0000000..a7bb6d3 --- /dev/null +++ b/vendor/illuminate/http/composer.json @@ -0,0 +1,34 @@ +{ + "name": "illuminate/http", + "description": "The Illuminate Http package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/session": "5.1.*", + "illuminate/support": "5.1.*", + "symfony/http-foundation": "2.7.*", + "symfony/http-kernel": "2.7.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Http\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/pagination/AbstractPaginator.php b/vendor/illuminate/pagination/AbstractPaginator.php new file mode 100644 index 0000000..cea0408 --- /dev/null +++ b/vendor/illuminate/pagination/AbstractPaginator.php @@ -0,0 +1,487 @@ += 1 && filter_var($page, FILTER_VALIDATE_INT) !== false; + } + + /** + * Create a range of pagination URLs. + * + * @param int $start + * @param int $end + * @return string + */ + public function getUrlRange($start, $end) + { + $urls = []; + + for ($page = $start; $page <= $end; $page++) { + $urls[$page] = $this->url($page); + } + + return $urls; + } + + /** + * Get a URL for a given page number. + * + * @param int $page + * @return string + */ + public function url($page) + { + if ($page <= 0) { + $page = 1; + } + + // If we have any extra query string key / value pairs that need to be added + // onto the URL, we will put them in query string form and then attach it + // to the URL. This allows for extra information like sortings storage. + $parameters = [$this->pageName => $page]; + + if (count($this->query) > 0) { + $parameters = array_merge($this->query, $parameters); + } + + return $this->path.'?' + .urldecode(http_build_query($parameters, null, '&')) + .$this->buildFragment(); + } + + /** + * Get the URL for the previous page. + * + * @return string|null + */ + public function previousPageUrl() + { + if ($this->currentPage() > 1) { + return $this->url($this->currentPage() - 1); + } + } + + /** + * Get / set the URL fragment to be appended to URLs. + * + * @param string|null $fragment + * @return $this|string|null + */ + public function fragment($fragment = null) + { + if (is_null($fragment)) { + return $this->fragment; + } + + $this->fragment = $fragment; + + return $this; + } + + /** + * Add a set of query string values to the paginator. + * + * @param array|string $key + * @param string|null $value + * @return $this + */ + public function appends($key, $value = null) + { + if (is_array($key)) { + return $this->appendArray($key); + } + + return $this->addQuery($key, $value); + } + + /** + * Add an array of query string values. + * + * @param array $keys + * @return $this + */ + protected function appendArray(array $keys) + { + foreach ($keys as $key => $value) { + $this->addQuery($key, $value); + } + + return $this; + } + + /** + * Add a query string value to the paginator. + * + * @param string $key + * @param string $value + * @return $this + */ + public function addQuery($key, $value) + { + if ($key !== $this->pageName) { + $this->query[$key] = $value; + } + + return $this; + } + + /** + * Build the full fragment portion of a URL. + * + * @return string + */ + protected function buildFragment() + { + return $this->fragment ? '#'.$this->fragment : ''; + } + + /** + * Get the slice of items being paginated. + * + * @return array + */ + public function items() + { + return $this->items->all(); + } + + /** + * Get the number of the first item in the slice. + * + * @return int + */ + public function firstItem() + { + return ($this->currentPage - 1) * $this->perPage + 1; + } + + /** + * Get the number of the last item in the slice. + * + * @return int + */ + public function lastItem() + { + return $this->firstItem() + $this->count() - 1; + } + + /** + * Get the number of items shown per page. + * + * @return int + */ + public function perPage() + { + return $this->perPage; + } + + /** + * Get the current page. + * + * @return int + */ + public function currentPage() + { + return $this->currentPage; + } + + /** + * Determine if there are enough items to split into multiple pages. + * + * @return bool + */ + public function hasPages() + { + return ! ($this->currentPage() == 1 && ! $this->hasMorePages()); + } + + /** + * Resolve the current request path or return the default value. + * + * @param string $default + * @return string + */ + public static function resolveCurrentPath($default = '/') + { + if (isset(static::$currentPathResolver)) { + return call_user_func(static::$currentPathResolver); + } + + return $default; + } + + /** + * Set the current request path resolver callback. + * + * @param \Closure $resolver + * @return void + */ + public static function currentPathResolver(Closure $resolver) + { + static::$currentPathResolver = $resolver; + } + + /** + * Resolve the current page or return the default value. + * + * @param string $pageName + * @param int $default + * @return int + */ + public static function resolveCurrentPage($pageName = 'page', $default = 1) + { + if (isset(static::$currentPageResolver)) { + return call_user_func(static::$currentPageResolver, $pageName); + } + + return $default; + } + + /** + * Set the current page resolver callback. + * + * @param \Closure $resolver + * @return void + */ + public static function currentPageResolver(Closure $resolver) + { + static::$currentPageResolver = $resolver; + } + + /** + * Set the default Presenter resolver. + * + * @param \Closure $resolver + * @return void + */ + public static function presenter(Closure $resolver) + { + static::$presenterResolver = $resolver; + } + + /** + * Get the query string variable used to store the page. + * + * @return string + */ + public function getPageName() + { + return $this->pageName; + } + + /** + * Set the query string variable used to store the page. + * + * @param string $name + * @return $this + */ + public function setPageName($name) + { + $this->pageName = $name; + + return $this; + } + + /** + * Set the base path to assign to all URLs. + * + * @param string $path + * @return $this + */ + public function setPath($path) + { + $this->path = $path; + + return $this; + } + + /** + * Get an iterator for the items. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->items->all()); + } + + /** + * Determine if the list of items is empty or not. + * + * @return bool + */ + public function isEmpty() + { + return $this->items->isEmpty(); + } + + /** + * Get the number of items for the current page. + * + * @return int + */ + public function count() + { + return $this->items->count(); + } + + /** + * Get the paginator's underlying collection. + * + * @return \Illuminate\Support\Collection + */ + public function getCollection() + { + return $this->items; + } + + /** + * Determine if the given item exists. + * + * @param mixed $key + * @return bool + */ + public function offsetExists($key) + { + return $this->items->has($key); + } + + /** + * Get the item at the given offset. + * + * @param mixed $key + * @return mixed + */ + public function offsetGet($key) + { + return $this->items->get($key); + } + + /** + * Set the item at the given offset. + * + * @param mixed $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + $this->items->put($key, $value); + } + + /** + * Unset the item at the given key. + * + * @param mixed $key + * @return void + */ + public function offsetUnset($key) + { + $this->items->forget($key); + } + + /** + * Make dynamic calls into the collection. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->getCollection(), $method], $parameters); + } + + /** + * Render the contents of the paginator when casting to string. + * + * @return string + */ + public function __toString() + { + return $this->render(); + } +} diff --git a/vendor/illuminate/pagination/BootstrapThreeNextPreviousButtonRendererTrait.php b/vendor/illuminate/pagination/BootstrapThreeNextPreviousButtonRendererTrait.php new file mode 100644 index 0000000..a8fda50 --- /dev/null +++ b/vendor/illuminate/pagination/BootstrapThreeNextPreviousButtonRendererTrait.php @@ -0,0 +1,48 @@ +paginator->currentPage() <= 1) { + return $this->getDisabledTextWrapper($text); + } + + $url = $this->paginator->url( + $this->paginator->currentPage() - 1 + ); + + return $this->getPageLinkWrapper($url, $text, 'prev'); + } + + /** + * Get the next page pagination element. + * + * @param string $text + * @return string + */ + public function getNextButton($text = '»') + { + // If the current page is greater than or equal to the last page, it means we + // can't go any further into the pages, as we're already on this last page + // that is available, so we will make it the "next" link style disabled. + if (! $this->paginator->hasMorePages()) { + return $this->getDisabledTextWrapper($text); + } + + $url = $this->paginator->url($this->paginator->currentPage() + 1); + + return $this->getPageLinkWrapper($url, $text, 'next'); + } +} diff --git a/vendor/illuminate/pagination/BootstrapThreePresenter.php b/vendor/illuminate/pagination/BootstrapThreePresenter.php new file mode 100644 index 0000000..21e647d --- /dev/null +++ b/vendor/illuminate/pagination/BootstrapThreePresenter.php @@ -0,0 +1,134 @@ +paginator = $paginator; + $this->window = is_null($window) ? UrlWindow::make($paginator) : $window->get(); + } + + /** + * Determine if the underlying paginator being presented has pages to show. + * + * @return bool + */ + public function hasPages() + { + return $this->paginator->hasPages(); + } + + /** + * Convert the URL window into Bootstrap HTML. + * + * @return string + */ + public function render() + { + if ($this->hasPages()) { + return sprintf( + '
    %s %s %s
', + $this->getPreviousButton(), + $this->getLinks(), + $this->getNextButton() + ); + } + + return ''; + } + + /** + * Get HTML wrapper for an available page link. + * + * @param string $url + * @param int $page + * @param string|null $rel + * @return string + */ + protected function getAvailablePageWrapper($url, $page, $rel = null) + { + $rel = is_null($rel) ? '' : ' rel="'.$rel.'"'; + + return '
  • '.$page.'
  • '; + } + + /** + * Get HTML wrapper for disabled text. + * + * @param string $text + * @return string + */ + protected function getDisabledTextWrapper($text) + { + return '
  • '.$text.'
  • '; + } + + /** + * Get HTML wrapper for active text. + * + * @param string $text + * @return string + */ + protected function getActivePageWrapper($text) + { + return '
  • '.$text.'
  • '; + } + + /** + * Get a pagination "dot" element. + * + * @return string + */ + protected function getDots() + { + return $this->getDisabledTextWrapper('...'); + } + + /** + * Get the current page from the paginator. + * + * @return int + */ + protected function currentPage() + { + return $this->paginator->currentPage(); + } + + /** + * Get the last page from the paginator. + * + * @return int + */ + protected function lastPage() + { + return $this->paginator->lastPage(); + } +} diff --git a/vendor/illuminate/pagination/LengthAwarePaginator.php b/vendor/illuminate/pagination/LengthAwarePaginator.php new file mode 100644 index 0000000..dbecee9 --- /dev/null +++ b/vendor/illuminate/pagination/LengthAwarePaginator.php @@ -0,0 +1,164 @@ + $value) { + $this->{$key} = $value; + } + + $this->total = $total; + $this->perPage = $perPage; + $this->lastPage = (int) ceil($total / $perPage); + $this->currentPage = $this->setCurrentPage($currentPage, $this->lastPage); + $this->path = $this->path != '/' ? rtrim($this->path, '/').'/' : $this->path; + $this->items = $items instanceof Collection ? $items : Collection::make($items); + } + + /** + * Get the current page for the request. + * + * @param int $currentPage + * @param int $lastPage + * @return int + */ + protected function setCurrentPage($currentPage, $lastPage) + { + $currentPage = $currentPage ?: static::resolveCurrentPage(); + + // The page number will get validated and adjusted if it either less than one + // or greater than the last page available based on the count of the given + // items array. If it's greater than the last, we'll give back the last. + if (is_numeric($currentPage) && $currentPage > $lastPage) { + return $lastPage > 0 ? $lastPage : 1; + } + + return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1; + } + + /** + * Get the URL for the next page. + * + * @return string|null + */ + public function nextPageUrl() + { + if ($this->lastPage() > $this->currentPage()) { + return $this->url($this->currentPage() + 1); + } + } + + /** + * Determine if there are more items in the data source. + * + * @return bool + */ + public function hasMorePages() + { + return $this->currentPage() < $this->lastPage(); + } + + /** + * Get the total number of items being paginated. + * + * @return int + */ + public function total() + { + return $this->total; + } + + /** + * Get the last page. + * + * @return int + */ + public function lastPage() + { + return $this->lastPage; + } + + /** + * Render the paginator using the given presenter. + * + * @param \Illuminate\Contracts\Pagination\Presenter|null $presenter + * @return string + */ + public function render(Presenter $presenter = null) + { + if (is_null($presenter) && static::$presenterResolver) { + $presenter = call_user_func(static::$presenterResolver, $this); + } + + $presenter = $presenter ?: new BootstrapThreePresenter($this); + + return $presenter->render(); + } + + /** + * Get the instance as an array. + * + * @return array + */ + public function toArray() + { + return [ + 'total' => $this->total(), + 'per_page' => $this->perPage(), + 'current_page' => $this->currentPage(), + 'last_page' => $this->lastPage(), + 'next_page_url' => $this->nextPageUrl(), + 'prev_page_url' => $this->previousPageUrl(), + 'from' => $this->firstItem(), + 'to' => $this->lastItem(), + 'data' => $this->items->toArray(), + ]; + } + + /** + * Convert the object to its JSON representation. + * + * @param int $options + * @return string + */ + public function toJson($options = 0) + { + return json_encode($this->toArray(), $options); + } +} diff --git a/vendor/illuminate/pagination/PaginationServiceProvider.php b/vendor/illuminate/pagination/PaginationServiceProvider.php new file mode 100755 index 0000000..28a17fb --- /dev/null +++ b/vendor/illuminate/pagination/PaginationServiceProvider.php @@ -0,0 +1,24 @@ +app['request']->url(); + }); + + Paginator::currentPageResolver(function ($pageName = 'page') { + return $this->app['request']->input($pageName); + }); + } +} diff --git a/vendor/illuminate/pagination/Paginator.php b/vendor/illuminate/pagination/Paginator.php new file mode 100644 index 0000000..0c969fc --- /dev/null +++ b/vendor/illuminate/pagination/Paginator.php @@ -0,0 +1,135 @@ + $value) { + $this->{$key} = $value; + } + + $this->perPage = $perPage; + $this->currentPage = $this->setCurrentPage($currentPage); + $this->path = $this->path != '/' ? rtrim($this->path, '/').'/' : $this->path; + $this->items = $items instanceof Collection ? $items : Collection::make($items); + + $this->checkForMorePages(); + } + + /** + * Get the current page for the request. + * + * @param int $currentPage + * @return int + */ + protected function setCurrentPage($currentPage) + { + $currentPage = $currentPage ?: static::resolveCurrentPage(); + + return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1; + } + + /** + * Check for more pages. The last item will be sliced off. + * + * @return void + */ + protected function checkForMorePages() + { + $this->hasMore = count($this->items) > ($this->perPage); + + $this->items = $this->items->slice(0, $this->perPage); + } + + /** + * Get the URL for the next page. + * + * @return string|null + */ + public function nextPageUrl() + { + if ($this->hasMore) { + return $this->url($this->currentPage() + 1); + } + } + + /** + * Determine if there are more items in the data source. + * + * @return bool + */ + public function hasMorePages() + { + return $this->hasMore; + } + + /** + * Render the paginator using the given presenter. + * + * @param \Illuminate\Contracts\Pagination\Presenter|null $presenter + * @return string + */ + public function render(Presenter $presenter = null) + { + if (is_null($presenter) && static::$presenterResolver) { + $presenter = call_user_func(static::$presenterResolver, $this); + } + + $presenter = $presenter ?: new SimpleBootstrapThreePresenter($this); + + return $presenter->render(); + } + + /** + * Get the instance as an array. + * + * @return array + */ + public function toArray() + { + return [ + 'per_page' => $this->perPage(), 'current_page' => $this->currentPage(), + 'next_page_url' => $this->nextPageUrl(), 'prev_page_url' => $this->previousPageUrl(), + 'from' => $this->firstItem(), 'to' => $this->lastItem(), + 'data' => $this->items->toArray(), + ]; + } + + /** + * Convert the object to its JSON representation. + * + * @param int $options + * @return string + */ + public function toJson($options = 0) + { + return json_encode($this->toArray(), $options); + } +} diff --git a/vendor/illuminate/pagination/SimpleBootstrapThreePresenter.php b/vendor/illuminate/pagination/SimpleBootstrapThreePresenter.php new file mode 100644 index 0000000..bbb2790 --- /dev/null +++ b/vendor/illuminate/pagination/SimpleBootstrapThreePresenter.php @@ -0,0 +1,47 @@ +paginator = $paginator; + } + + /** + * Determine if the underlying paginator being presented has pages to show. + * + * @return bool + */ + public function hasPages() + { + return $this->paginator->hasPages() && count($this->paginator->items()) > 0; + } + + /** + * Convert the URL window into Bootstrap HTML. + * + * @return string + */ + public function render() + { + if ($this->hasPages()) { + return sprintf( + '
      %s %s
    ', + $this->getPreviousButton(), + $this->getNextButton() + ); + } + + return ''; + } +} diff --git a/vendor/illuminate/pagination/UrlWindow.php b/vendor/illuminate/pagination/UrlWindow.php new file mode 100644 index 0000000..655f646 --- /dev/null +++ b/vendor/illuminate/pagination/UrlWindow.php @@ -0,0 +1,222 @@ +paginator = $paginator; + } + + /** + * Create a new URL window instance. + * + * @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator + * @param int $onEachSide + * @return array + */ + public static function make(PaginatorContract $paginator, $onEachSide = 3) + { + return (new static($paginator))->get($onEachSide); + } + + /** + * Get the window of URLs to be shown. + * + * @param int $onEachSide + * @return array + */ + public function get($onEachSide = 3) + { + if ($this->paginator->lastPage() < ($onEachSide * 2) + 6) { + return $this->getSmallSlider(); + } + + return $this->getUrlSlider($onEachSide); + } + + /** + * Get the slider of URLs there are not enough pages to slide. + * + * @return array + */ + protected function getSmallSlider() + { + return [ + 'first' => $this->paginator->getUrlRange(1, $this->lastPage()), + 'slider' => null, + 'last' => null, + ]; + } + + /** + * Create a URL slider links. + * + * @param int $onEachSide + * @return array + */ + protected function getUrlSlider($onEachSide) + { + $window = $onEachSide * 2; + + if (! $this->hasPages()) { + return [ + 'first' => null, + 'slider' => null, + 'last' => null, + ]; + } + + // If the current page is very close to the beginning of the page range, we will + // just render the beginning of the page range, followed by the last 2 of the + // links in this list, since we will not have room to create a full slider. + if ($this->currentPage() <= $window) { + return $this->getSliderTooCloseToBeginning($window); + } + + // If the current page is close to the ending of the page range we will just get + // this first couple pages, followed by a larger window of these ending pages + // since we're too close to the end of the list to create a full on slider. + elseif ($this->currentPage() > ($this->lastPage() - $window)) { + return $this->getSliderTooCloseToEnding($window); + } + + // If we have enough room on both sides of the current page to build a slider we + // will surround it with both the beginning and ending caps, with this window + // of pages in the middle providing a Google style sliding paginator setup. + return $this->getFullSlider($onEachSide); + } + + /** + * Get the slider of URLs when too close to beginning of window. + * + * @param int $window + * @return array + */ + protected function getSliderTooCloseToBeginning($window) + { + return [ + 'first' => $this->paginator->getUrlRange(1, $window + 2), + 'slider' => null, + 'last' => $this->getFinish(), + ]; + } + + /** + * Get the slider of URLs when too close to ending of window. + * + * @param int $window + * @return array + */ + protected function getSliderTooCloseToEnding($window) + { + $last = $this->paginator->getUrlRange( + $this->lastPage() - ($window + 2), + $this->lastPage() + ); + + return [ + 'first' => $this->getStart(), + 'slider' => null, + 'last' => $last, + ]; + } + + /** + * Get the slider of URLs when a full slider can be made. + * + * @param int $onEachSide + * @return array + */ + protected function getFullSlider($onEachSide) + { + return [ + 'first' => $this->getStart(), + 'slider' => $this->getAdjacentUrlRange($onEachSide), + 'last' => $this->getFinish(), + ]; + } + + /** + * Get the page range for the current page window. + * + * @param int $onEachSide + * @return array + */ + public function getAdjacentUrlRange($onEachSide) + { + return $this->paginator->getUrlRange( + $this->currentPage() - $onEachSide, + $this->currentPage() + $onEachSide + ); + } + + /** + * Get the starting URLs of a pagination slider. + * + * @return array + */ + public function getStart() + { + return $this->paginator->getUrlRange(1, 2); + } + + /** + * Get the ending URLs of a pagination slider. + * + * @return array + */ + public function getFinish() + { + return $this->paginator->getUrlRange( + $this->lastPage() - 1, + $this->lastPage() + ); + } + + /** + * Determine if the underlying paginator being presented has pages to show. + * + * @return bool + */ + public function hasPages() + { + return $this->paginator->lastPage() > 1; + } + + /** + * Get the current page from the paginator. + * + * @return int + */ + protected function currentPage() + { + return $this->paginator->currentPage(); + } + + /** + * Get the last page from the paginator. + * + * @return int + */ + protected function lastPage() + { + return $this->paginator->lastPage(); + } +} diff --git a/vendor/illuminate/pagination/UrlWindowPresenterTrait.php b/vendor/illuminate/pagination/UrlWindowPresenterTrait.php new file mode 100644 index 0000000..64a3397 --- /dev/null +++ b/vendor/illuminate/pagination/UrlWindowPresenterTrait.php @@ -0,0 +1,66 @@ +window['first'])) { + $html .= $this->getUrlLinks($this->window['first']); + } + + if (is_array($this->window['slider'])) { + $html .= $this->getDots(); + $html .= $this->getUrlLinks($this->window['slider']); + } + + if (is_array($this->window['last'])) { + $html .= $this->getDots(); + $html .= $this->getUrlLinks($this->window['last']); + } + + return $html; + } + + /** + * Get the links for the URLs in the given array. + * + * @param array $urls + * @return string + */ + protected function getUrlLinks(array $urls) + { + $html = ''; + + foreach ($urls as $page => $url) { + $html .= $this->getPageLinkWrapper($url, $page); + } + + return $html; + } + + /** + * Get HTML wrapper for a page link. + * + * @param string $url + * @param int $page + * @param string|null $rel + * @return string + */ + protected function getPageLinkWrapper($url, $page, $rel = null) + { + if ($page == $this->paginator->currentPage()) { + return $this->getActivePageWrapper($page); + } + + return $this->getAvailablePageWrapper($url, $page, $rel); + } +} diff --git a/vendor/illuminate/pagination/composer.json b/vendor/illuminate/pagination/composer.json new file mode 100755 index 0000000..871c66e --- /dev/null +++ b/vendor/illuminate/pagination/composer.json @@ -0,0 +1,32 @@ +{ + "name": "illuminate/pagination", + "description": "The Illuminate Pagination package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Pagination\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/pipeline/Hub.php b/vendor/illuminate/pipeline/Hub.php new file mode 100644 index 0000000..ed48df4 --- /dev/null +++ b/vendor/illuminate/pipeline/Hub.php @@ -0,0 +1,74 @@ +container = $container; + } + + /** + * Define the default named pipeline. + * + * @param \Closure $callback + * @return void + */ + public function defaults(Closure $callback) + { + return $this->pipeline('default', $callback); + } + + /** + * Define a new named pipeline. + * + * @param string $name + * @param \Closure $callback + * @return void + */ + public function pipeline($name, Closure $callback) + { + $this->pipelines[$name] = $callback; + } + + /** + * Send an object through one of the available pipelines. + * + * @param mixed $object + * @param string|null $pipeline + * @return mixed + */ + public function pipe($object, $pipeline = null) + { + $pipeline = $pipeline ?: 'default'; + + return call_user_func( + $this->pipelines[$pipeline], new Pipeline($this->container), $object + ); + } +} diff --git a/vendor/illuminate/pipeline/Pipeline.php b/vendor/illuminate/pipeline/Pipeline.php new file mode 100644 index 0000000..12aa6d7 --- /dev/null +++ b/vendor/illuminate/pipeline/Pipeline.php @@ -0,0 +1,159 @@ +container = $container; + } + + /** + * Set the object being sent through the pipeline. + * + * @param mixed $passable + * @return $this + */ + public function send($passable) + { + $this->passable = $passable; + + return $this; + } + + /** + * Set the array of pipes. + * + * @param array|mixed $pipes + * @return $this + */ + public function through($pipes) + { + $this->pipes = is_array($pipes) ? $pipes : func_get_args(); + + return $this; + } + + /** + * Set the method to call on the pipes. + * + * @param string $method + * @return $this + */ + public function via($method) + { + $this->method = $method; + + return $this; + } + + /** + * Run the pipeline with a final destination callback. + * + * @param \Closure $destination + * @return mixed + */ + public function then(Closure $destination) + { + $firstSlice = $this->getInitialSlice($destination); + + $pipes = array_reverse($this->pipes); + + return call_user_func( + array_reduce($pipes, $this->getSlice(), $firstSlice), $this->passable + ); + } + + /** + * Get a Closure that represents a slice of the application onion. + * + * @return \Closure + */ + protected function getSlice() + { + return function ($stack, $pipe) { + return function ($passable) use ($stack, $pipe) { + // If the pipe is an instance of a Closure, we will just call it directly but + // otherwise we'll resolve the pipes out of the container and call it with + // the appropriate method and arguments, returning the results back out. + if ($pipe instanceof Closure) { + return call_user_func($pipe, $passable, $stack); + } else { + list($name, $parameters) = $this->parsePipeString($pipe); + + return call_user_func_array([$this->container->make($name), $this->method], + array_merge([$passable, $stack], $parameters)); + } + }; + }; + } + + /** + * Get the initial slice to begin the stack call. + * + * @param \Closure $destination + * @return \Closure + */ + protected function getInitialSlice(Closure $destination) + { + return function ($passable) use ($destination) { + return call_user_func($destination, $passable); + }; + } + + /** + * Parse full pipe string to get name and parameters. + * + * @param string $pipe + * @return array + */ + protected function parsePipeString($pipe) + { + list($name, $parameters) = array_pad(explode(':', $pipe, 2), 2, []); + + if (is_string($parameters)) { + $parameters = explode(',', $parameters); + } + + return [$name, $parameters]; + } +} diff --git a/vendor/illuminate/pipeline/PipelineServiceProvider.php b/vendor/illuminate/pipeline/PipelineServiceProvider.php new file mode 100644 index 0000000..aceaddf --- /dev/null +++ b/vendor/illuminate/pipeline/PipelineServiceProvider.php @@ -0,0 +1,39 @@ +app->singleton( + 'Illuminate\Contracts\Pipeline\Hub', 'Illuminate\Pipeline\Hub' + ); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'Illuminate\Contracts\Pipeline\Hub', + ]; + } +} diff --git a/vendor/illuminate/pipeline/composer.json b/vendor/illuminate/pipeline/composer.json new file mode 100644 index 0000000..85b0734 --- /dev/null +++ b/vendor/illuminate/pipeline/composer.json @@ -0,0 +1,32 @@ +{ + "name": "illuminate/pipeline", + "description": "The Illuminate Pipeline package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Pipeline\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/queue/BeanstalkdQueue.php b/vendor/illuminate/queue/BeanstalkdQueue.php new file mode 100755 index 0000000..ad090ac --- /dev/null +++ b/vendor/illuminate/queue/BeanstalkdQueue.php @@ -0,0 +1,143 @@ +default = $default; + $this->timeToRun = $timeToRun; + $this->pheanstalk = $pheanstalk; + } + + /** + * Push a new job onto the queue. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function push($job, $data = '', $queue = null) + { + return $this->pushRaw($this->createPayload($job, $data), $queue); + } + + /** + * Push a raw payload onto the queue. + * + * @param string $payload + * @param string $queue + * @param array $options + * @return mixed + */ + public function pushRaw($payload, $queue = null, array $options = []) + { + return $this->pheanstalk->useTube($this->getQueue($queue))->put( + $payload, Pheanstalk::DEFAULT_PRIORITY, Pheanstalk::DEFAULT_DELAY, $this->timeToRun + ); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTime|int $delay + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function later($delay, $job, $data = '', $queue = null) + { + $payload = $this->createPayload($job, $data); + + $pheanstalk = $this->pheanstalk->useTube($this->getQueue($queue)); + + return $pheanstalk->put($payload, Pheanstalk::DEFAULT_PRIORITY, $this->getSeconds($delay), $this->timeToRun); + } + + /** + * Pop the next job off of the queue. + * + * @param string $queue + * @return \Illuminate\Contracts\Queue\Job|null + */ + public function pop($queue = null) + { + $queue = $this->getQueue($queue); + + $job = $this->pheanstalk->watchOnly($queue)->reserve(0); + + if ($job instanceof PheanstalkJob) { + return new BeanstalkdJob($this->container, $this->pheanstalk, $job, $queue); + } + } + + /** + * Delete a message from the Beanstalk queue. + * + * @param string $queue + * @param string $id + * @return void + */ + public function deleteMessage($queue, $id) + { + $this->pheanstalk->useTube($this->getQueue($queue))->delete($id); + } + + /** + * Get the queue or return the default. + * + * @param string|null $queue + * @return string + */ + public function getQueue($queue) + { + return $queue ?: $this->default; + } + + /** + * Get the underlying Pheanstalk instance. + * + * @return \Pheanstalk\Pheanstalk + */ + public function getPheanstalk() + { + return $this->pheanstalk; + } +} diff --git a/vendor/illuminate/queue/CallQueuedHandler.php b/vendor/illuminate/queue/CallQueuedHandler.php new file mode 100644 index 0000000..dc16c88 --- /dev/null +++ b/vendor/illuminate/queue/CallQueuedHandler.php @@ -0,0 +1,80 @@ +dispatcher = $dispatcher; + } + + /** + * Handle the queued job. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @param array $data + * @return void + */ + public function call(Job $job, array $data) + { + $command = $this->setJobInstanceIfNecessary( + $job, unserialize($data['command']) + ); + + $this->dispatcher->dispatchNow($command, function ($handler) use ($job) { + $this->setJobInstanceIfNecessary($job, $handler); + }); + + if (! $job->isDeletedOrReleased()) { + $job->delete(); + } + } + + /** + * Set the job instance of the given class if necessary. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @param mixed $instance + * @return mixed + */ + protected function setJobInstanceIfNecessary(Job $job, $instance) + { + if (in_array('Illuminate\Queue\InteractsWithQueue', class_uses_recursive(get_class($instance)))) { + $instance->setJob($job); + } + + return $instance; + } + + /** + * Call the failed method on the job instance. + * + * @param array $data + * @return void + */ + public function failed(array $data) + { + $handler = $this->dispatcher->resolveHandler($command = unserialize($data['command'])); + + if (method_exists($handler, 'failed')) { + call_user_func([$handler, 'failed'], $command); + } + } +} diff --git a/vendor/illuminate/queue/Capsule/Manager.php b/vendor/illuminate/queue/Capsule/Manager.php new file mode 100644 index 0000000..179be60 --- /dev/null +++ b/vendor/illuminate/queue/Capsule/Manager.php @@ -0,0 +1,183 @@ +setupContainer($container ?: new Container); + + // Once we have the container setup, we will setup the default configuration + // options in the container "config" bindings. This just makes this queue + // manager behave correctly since all the correct binding are in place. + $this->setupDefaultConfiguration(); + + $this->setupManager(); + + $this->registerConnectors(); + } + + /** + * Setup the default queue configuration options. + * + * @return void + */ + protected function setupDefaultConfiguration() + { + $this->container['config']['queue.default'] = 'default'; + } + + /** + * Build the queue manager instance. + * + * @return void + */ + protected function setupManager() + { + $this->manager = new QueueManager($this->container); + } + + /** + * Register the default connectors that the component ships with. + * + * @return void + */ + protected function registerConnectors() + { + $provider = new QueueServiceProvider($this->container); + + $provider->registerConnectors($this->manager); + } + + /** + * Get a connection instance from the global manager. + * + * @param string $connection + * @return \Illuminate\Contracts\Queue\Queue + */ + public static function connection($connection = null) + { + return static::$instance->getConnection($connection); + } + + /** + * Push a new job onto the queue. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @param string $connection + * @return mixed + */ + public static function push($job, $data = '', $queue = null, $connection = null) + { + return static::$instance->connection($connection)->push($job, $data, $queue); + } + + /** + * Push a new an array of jobs onto the queue. + * + * @param array $jobs + * @param mixed $data + * @param string $queue + * @param string $connection + * @return mixed + */ + public static function bulk($jobs, $data = '', $queue = null, $connection = null) + { + return static::$instance->connection($connection)->bulk($jobs, $data, $queue); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTime|int $delay + * @param string $job + * @param mixed $data + * @param string $queue + * @param string $connection + * @return mixed + */ + public static function later($delay, $job, $data = '', $queue = null, $connection = null) + { + return static::$instance->connection($connection)->later($delay, $job, $data, $queue); + } + + /** + * Get a registered connection instance. + * + * @param string $name + * @return \Illuminate\Contracts\Queue\Queue + */ + public function getConnection($name = null) + { + return $this->manager->connection($name); + } + + /** + * Register a connection with the manager. + * + * @param array $config + * @param string $name + * @return void + */ + public function addConnection(array $config, $name = 'default') + { + $this->container['config']["queue.connections.{$name}"] = $config; + } + + /** + * Get the queue manager instance. + * + * @return \Illuminate\Queue\QueueManager + */ + public function getQueueManager() + { + return $this->manager; + } + + /** + * Pass dynamic instance methods to the manager. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->manager, $method], $parameters); + } + + /** + * Dynamically pass methods to the default connection. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public static function __callStatic($method, $parameters) + { + return call_user_func_array([static::connection(), $method], $parameters); + } +} diff --git a/vendor/illuminate/queue/Connectors/BeanstalkdConnector.php b/vendor/illuminate/queue/Connectors/BeanstalkdConnector.php new file mode 100755 index 0000000..1087415 --- /dev/null +++ b/vendor/illuminate/queue/Connectors/BeanstalkdConnector.php @@ -0,0 +1,26 @@ +connections = $connections; + } + + /** + * Establish a queue connection. + * + * @param array $config + * @return \Illuminate\Contracts\Queue\Queue + */ + public function connect(array $config) + { + return new DatabaseQueue( + $this->connections->connection(Arr::get($config, 'connection')), + $config['table'], + $config['queue'], + Arr::get($config, 'expire', 60) + ); + } +} diff --git a/vendor/illuminate/queue/Connectors/IronConnector.php b/vendor/illuminate/queue/Connectors/IronConnector.php new file mode 100755 index 0000000..d103c19 --- /dev/null +++ b/vendor/illuminate/queue/Connectors/IronConnector.php @@ -0,0 +1,61 @@ +crypt = $crypt; + $this->request = $request; + } + + /** + * Establish a queue connection. + * + * @param array $config + * @return \Illuminate\Contracts\Queue\Queue + */ + public function connect(array $config) + { + $ironConfig = ['token' => $config['token'], 'project_id' => $config['project']]; + + if (isset($config['host'])) { + $ironConfig['host'] = $config['host']; + } + + $iron = new IronMQ($ironConfig); + + if (isset($config['ssl_verifypeer'])) { + $iron->ssl_verifypeer = $config['ssl_verifypeer']; + } + + return new IronQueue($iron, $this->request, $config['queue'], $config['encrypt']); + } +} diff --git a/vendor/illuminate/queue/Connectors/NullConnector.php b/vendor/illuminate/queue/Connectors/NullConnector.php new file mode 100644 index 0000000..39de480 --- /dev/null +++ b/vendor/illuminate/queue/Connectors/NullConnector.php @@ -0,0 +1,19 @@ +redis = $redis; + $this->connection = $connection; + } + + /** + * Establish a queue connection. + * + * @param array $config + * @return \Illuminate\Contracts\Queue\Queue + */ + public function connect(array $config) + { + $queue = new RedisQueue( + $this->redis, $config['queue'], Arr::get($config, 'connection', $this->connection) + ); + + $queue->setExpire(Arr::get($config, 'expire', 60)); + + return $queue; + } +} diff --git a/vendor/illuminate/queue/Connectors/SqsConnector.php b/vendor/illuminate/queue/Connectors/SqsConnector.php new file mode 100755 index 0000000..595b9e8 --- /dev/null +++ b/vendor/illuminate/queue/Connectors/SqsConnector.php @@ -0,0 +1,29 @@ + 'latest', 'http' => ['connect_timeout' => 60], + ], $config); + + if ($config['key'] && $config['secret']) { + $config['credentials'] = Arr::only($config, ['key', 'secret']); + } + + return new SqsQueue(new SqsClient($config), $config['queue']); + } +} diff --git a/vendor/illuminate/queue/Connectors/SyncConnector.php b/vendor/illuminate/queue/Connectors/SyncConnector.php new file mode 100755 index 0000000..4269b80 --- /dev/null +++ b/vendor/illuminate/queue/Connectors/SyncConnector.php @@ -0,0 +1,19 @@ +files = $files; + $this->composer = $composer; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $table = $this->laravel['config']['queue.failed.table']; + + $tableClassName = Str::studly($table); + + $fullPath = $this->createBaseMigration($table); + + $stub = str_replace( + ['{{table}}', '{{tableClassName}}'], [$table, $tableClassName], $this->files->get(__DIR__.'/stubs/failed_jobs.stub') + ); + + $this->files->put($fullPath, $stub); + + $this->info('Migration created successfully!'); + + $this->composer->dumpAutoloads(); + } + + /** + * Create a base migration file for the table. + * + * @param string $table + * @return string + */ + protected function createBaseMigration($table = 'failed_jobs') + { + $name = 'create_'.$table.'_table'; + + $path = $this->laravel->databasePath().'/migrations'; + + return $this->laravel['migration.creator']->create($name, $path); + } +} diff --git a/vendor/illuminate/queue/Console/FlushFailedCommand.php b/vendor/illuminate/queue/Console/FlushFailedCommand.php new file mode 100644 index 0000000..fc21093 --- /dev/null +++ b/vendor/illuminate/queue/Console/FlushFailedCommand.php @@ -0,0 +1,34 @@ +laravel['queue.failer']->flush(); + + $this->info('All failed jobs deleted successfully!'); + } +} diff --git a/vendor/illuminate/queue/Console/ForgetFailedCommand.php b/vendor/illuminate/queue/Console/ForgetFailedCommand.php new file mode 100644 index 0000000..2a016cf --- /dev/null +++ b/vendor/illuminate/queue/Console/ForgetFailedCommand.php @@ -0,0 +1,49 @@ +laravel['queue.failer']->forget($this->argument('id'))) { + $this->info('Failed job deleted successfully!'); + } else { + $this->error('No failed job matches the given ID.'); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['id', InputArgument::REQUIRED, 'The ID of the failed job'], + ]; + } +} diff --git a/vendor/illuminate/queue/Console/ListFailedCommand.php b/vendor/illuminate/queue/Console/ListFailedCommand.php new file mode 100644 index 0000000..33113b5 --- /dev/null +++ b/vendor/illuminate/queue/Console/ListFailedCommand.php @@ -0,0 +1,113 @@ +getFailedJobs(); + + if (count($jobs) == 0) { + return $this->info('No failed jobs!'); + } + + $this->displayFailedJobs($jobs); + } + + /** + * Compile the failed jobs into a displayable format. + * + * @return array + */ + protected function getFailedJobs() + { + $results = []; + + foreach ($this->laravel['queue.failer']->all() as $failed) { + $results[] = $this->parseFailedJob((array) $failed); + } + + return array_filter($results); + } + + /** + * Parse the failed job row. + * + * @param array $failed + * @return array + */ + protected function parseFailedJob(array $failed) + { + $row = array_values(array_except($failed, ['payload'])); + + array_splice($row, 3, 0, $this->extractJobName($failed['payload'])); + + return $row; + } + + /** + * Extract the failed job name from payload. + * + * @param string $payload + * @return string|null + */ + private function extractJobName($payload) + { + $payload = json_decode($payload, true); + + if ($payload && (! isset($payload['data']['command']))) { + return Arr::get($payload, 'job'); + } + + if ($payload && isset($payload['data']['command'])) { + preg_match('/"([^"]+)"/', $payload['data']['command'], $matches); + + if (isset($matches[1])) { + return $matches[1]; + } else { + return Arr::get($payload, 'job'); + } + } + } + + /** + * Display the failed jobs in the console. + * + * @param array $jobs + * @return void + */ + protected function displayFailedJobs(array $jobs) + { + $this->table($this->headers, $jobs); + } +} diff --git a/vendor/illuminate/queue/Console/ListenCommand.php b/vendor/illuminate/queue/Console/ListenCommand.php new file mode 100755 index 0000000..67de1d1 --- /dev/null +++ b/vendor/illuminate/queue/Console/ListenCommand.php @@ -0,0 +1,144 @@ +listener = $listener; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $this->setListenerOptions(); + + $delay = $this->input->getOption('delay'); + + // The memory limit is the amount of memory we will allow the script to occupy + // before killing it and letting a process manager restart it for us, which + // is to protect us against any memory leaks that will be in the scripts. + $memory = $this->input->getOption('memory'); + + $connection = $this->input->getArgument('connection'); + + $timeout = $this->input->getOption('timeout'); + + // We need to get the right queue for the connection which is set in the queue + // configuration file for the application. We will pull it based on the set + // connection being run for the queue operation currently being executed. + $queue = $this->getQueue($connection); + + $this->listener->listen( + $connection, $queue, $delay, $memory, $timeout + ); + } + + /** + * Get the name of the queue connection to listen on. + * + * @param string $connection + * @return string + */ + protected function getQueue($connection) + { + if (is_null($connection)) { + $connection = $this->laravel['config']['queue.default']; + } + + $queue = $this->laravel['config']->get("queue.connections.{$connection}.queue", 'default'); + + return $this->input->getOption('queue') ?: $queue; + } + + /** + * Set the options on the queue listener. + * + * @return void + */ + protected function setListenerOptions() + { + $this->listener->setEnvironment($this->laravel->environment()); + + $this->listener->setSleep($this->option('sleep')); + + $this->listener->setMaxTries($this->option('tries')); + + $this->listener->setOutputHandler(function ($type, $line) { + $this->output->write($line); + }); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['connection', InputArgument::OPTIONAL, 'The name of connection'], + ]; + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['queue', null, InputOption::VALUE_OPTIONAL, 'The queue to listen on', null], + + ['delay', null, InputOption::VALUE_OPTIONAL, 'Amount of time to delay failed jobs', 0], + + ['memory', null, InputOption::VALUE_OPTIONAL, 'The memory limit in megabytes', 128], + + ['timeout', null, InputOption::VALUE_OPTIONAL, 'Seconds a job may run before timing out', 60], + + ['sleep', null, InputOption::VALUE_OPTIONAL, 'Seconds to wait before checking queue for jobs', 3], + + ['tries', null, InputOption::VALUE_OPTIONAL, 'Number of times to attempt a job before logging it failed', 0], + ]; + } +} diff --git a/vendor/illuminate/queue/Console/RestartCommand.php b/vendor/illuminate/queue/Console/RestartCommand.php new file mode 100644 index 0000000..72ad27e --- /dev/null +++ b/vendor/illuminate/queue/Console/RestartCommand.php @@ -0,0 +1,34 @@ +laravel['cache']->forever('illuminate:queue:restart', time()); + + $this->info('Broadcasting queue restart signal.'); + } +} diff --git a/vendor/illuminate/queue/Console/RetryCommand.php b/vendor/illuminate/queue/Console/RetryCommand.php new file mode 100644 index 0000000..f8a373c --- /dev/null +++ b/vendor/illuminate/queue/Console/RetryCommand.php @@ -0,0 +1,76 @@ +laravel['queue.failer']->find($this->argument('id')); + + if (! is_null($failed)) { + $failed = (object) $failed; + + $failed->payload = $this->resetAttempts($failed->payload); + + $this->laravel['queue']->connection($failed->connection)->pushRaw($failed->payload, $failed->queue); + + $this->laravel['queue.failer']->forget($failed->id); + + $this->info('The failed job has been pushed back onto the queue!'); + } else { + $this->error('No failed job matches the given ID.'); + } + } + + /** + * Reset the payload attempts. + * + * @param string $payload + * @return string + */ + protected function resetAttempts($payload) + { + $payload = json_decode($payload, true); + + if (isset($payload['attempts'])) { + $payload['attempts'] = 0; + } + + return json_encode($payload); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['id', InputArgument::REQUIRED, 'The ID of the failed job'], + ]; + } +} diff --git a/vendor/illuminate/queue/Console/SubscribeCommand.php b/vendor/illuminate/queue/Console/SubscribeCommand.php new file mode 100755 index 0000000..48d4501 --- /dev/null +++ b/vendor/illuminate/queue/Console/SubscribeCommand.php @@ -0,0 +1,162 @@ +laravel['queue']->connection(); + + if (! $iron instanceof IronQueue) { + throw new RuntimeException('Iron.io based queue must be default.'); + } + + $iron->getIron()->updateQueue($this->argument('queue'), $this->getQueueOptions()); + + $this->line('Queue subscriber added: '.$this->argument('url').''); + } + + /** + * Get the queue options. + * + * @return array + */ + protected function getQueueOptions() + { + return [ + 'push_type' => $this->getPushType(), 'subscribers' => $this->getSubscriberList(), + ]; + } + + /** + * Get the push type for the queue. + * + * @return string + */ + protected function getPushType() + { + if ($this->option('type')) { + return $this->option('type'); + } + + try { + return $this->getQueue()->push_type; + } catch (Exception $e) { + return 'multicast'; + } + } + + /** + * Get the current subscribers for the queue. + * + * @return array + */ + protected function getSubscriberList() + { + $subscribers = $this->getCurrentSubscribers(); + + $url = $this->argument('url'); + + if (! Str::startsWith($url, ['http://', 'https://'])) { + $url = $this->laravel['url']->to($url); + } + + $subscribers[] = ['url' => $url]; + + return $subscribers; + } + + /** + * Get the current subscriber list. + * + * @return array + */ + protected function getCurrentSubscribers() + { + try { + return $this->getQueue()->subscribers; + } catch (Exception $e) { + return []; + } + } + + /** + * Get the queue information from Iron.io. + * + * @return object + */ + protected function getQueue() + { + if (isset($this->meta)) { + return $this->meta; + } + + return $this->meta = $this->laravel['queue']->getIron()->getQueue($this->argument('queue')); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['queue', InputArgument::REQUIRED, 'The name of Iron.io queue.'], + + ['url', InputArgument::REQUIRED, 'The URL to be subscribed.'], + ]; + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['type', null, InputOption::VALUE_OPTIONAL, 'The push type for the queue.'], + ]; + } +} diff --git a/vendor/illuminate/queue/Console/TableCommand.php b/vendor/illuminate/queue/Console/TableCommand.php new file mode 100644 index 0000000..f41d15c --- /dev/null +++ b/vendor/illuminate/queue/Console/TableCommand.php @@ -0,0 +1,91 @@ +files = $files; + $this->composer = $composer; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $table = $this->laravel['config']['queue.connections.database.table']; + + $tableClassName = Str::studly($table); + + $fullPath = $this->createBaseMigration($table); + + $stub = str_replace( + ['{{table}}', '{{tableClassName}}'], [$table, $tableClassName], $this->files->get(__DIR__.'/stubs/jobs.stub') + ); + + $this->files->put($fullPath, $stub); + + $this->info('Migration created successfully!'); + + $this->composer->dumpAutoloads(); + } + + /** + * Create a base migration file for the table. + * + * @param string $table + * @return string + */ + protected function createBaseMigration($table = 'jobs') + { + $name = 'create_'.$table.'_table'; + + $path = $this->laravel->databasePath().'/migrations'; + + return $this->laravel['migration.creator']->create($name, $path); + } +} diff --git a/vendor/illuminate/queue/Console/WorkCommand.php b/vendor/illuminate/queue/Console/WorkCommand.php new file mode 100755 index 0000000..1ae918f --- /dev/null +++ b/vendor/illuminate/queue/Console/WorkCommand.php @@ -0,0 +1,177 @@ +worker = $worker; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + if ($this->downForMaintenance() && ! $this->option('daemon')) { + return $this->worker->sleep($this->option('sleep')); + } + + $queue = $this->option('queue'); + + $delay = $this->option('delay'); + + // The memory limit is the amount of memory we will allow the script to occupy + // before killing it and letting a process manager restart it for us, which + // is to protect us against any memory leaks that will be in the scripts. + $memory = $this->option('memory'); + + $connection = $this->argument('connection'); + + $response = $this->runWorker( + $connection, $queue, $delay, $memory, $this->option('daemon') + ); + + // If a job was fired by the worker, we'll write the output out to the console + // so that the developer can watch live while the queue runs in the console + // window, which will also of get logged if stdout is logged out to disk. + if (! is_null($response['job'])) { + $this->writeOutput($response['job'], $response['failed']); + } + } + + /** + * Run the worker instance. + * + * @param string $connection + * @param string $queue + * @param int $delay + * @param int $memory + * @param bool $daemon + * @return array + */ + protected function runWorker($connection, $queue, $delay, $memory, $daemon = false) + { + if ($daemon) { + $this->worker->setCache($this->laravel['cache']->driver()); + + $this->worker->setDaemonExceptionHandler( + $this->laravel['Illuminate\Contracts\Debug\ExceptionHandler'] + ); + + return $this->worker->daemon( + $connection, $queue, $delay, $memory, + $this->option('sleep'), $this->option('tries') + ); + } + + return $this->worker->pop( + $connection, $queue, $delay, + $this->option('sleep'), $this->option('tries') + ); + } + + /** + * Write the status output for the queue worker. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @param bool $failed + * @return void + */ + protected function writeOutput(Job $job, $failed) + { + if ($failed) { + $this->output->writeln('Failed: '.$job->getName()); + } else { + $this->output->writeln('Processed: '.$job->getName()); + } + } + + /** + * Determine if the worker should run in maintenance mode. + * + * @return bool + */ + protected function downForMaintenance() + { + if ($this->option('force')) { + return false; + } + + return $this->laravel->isDownForMaintenance(); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['connection', InputArgument::OPTIONAL, 'The name of connection', null], + ]; + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['queue', null, InputOption::VALUE_OPTIONAL, 'The queue to listen on'], + + ['daemon', null, InputOption::VALUE_NONE, 'Run the worker in daemon mode'], + + ['delay', null, InputOption::VALUE_OPTIONAL, 'Amount of time to delay failed jobs', 0], + + ['force', null, InputOption::VALUE_NONE, 'Force the worker to run even in maintenance mode'], + + ['memory', null, InputOption::VALUE_OPTIONAL, 'The memory limit in megabytes', 128], + + ['sleep', null, InputOption::VALUE_OPTIONAL, 'Number of seconds to sleep when no job is available', 3], + + ['tries', null, InputOption::VALUE_OPTIONAL, 'Number of times to attempt a job before logging it failed', 0], + ]; + } +} diff --git a/vendor/illuminate/queue/Console/stubs/failed_jobs.stub b/vendor/illuminate/queue/Console/stubs/failed_jobs.stub new file mode 100644 index 0000000..68370da --- /dev/null +++ b/vendor/illuminate/queue/Console/stubs/failed_jobs.stub @@ -0,0 +1,33 @@ +increments('id'); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->timestamp('failed_at'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('{{table}}'); + } +} diff --git a/vendor/illuminate/queue/Console/stubs/jobs.stub b/vendor/illuminate/queue/Console/stubs/jobs.stub new file mode 100644 index 0000000..1866669 --- /dev/null +++ b/vendor/illuminate/queue/Console/stubs/jobs.stub @@ -0,0 +1,37 @@ +bigIncrements('id'); + $table->string('queue'); + $table->longText('payload'); + $table->tinyInteger('attempts')->unsigned(); + $table->tinyInteger('reserved')->unsigned(); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + $table->index(['queue', 'reserved', 'reserved_at']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('{{table}}'); + } +} diff --git a/vendor/illuminate/queue/ConsoleServiceProvider.php b/vendor/illuminate/queue/ConsoleServiceProvider.php new file mode 100644 index 0000000..0a81e1e --- /dev/null +++ b/vendor/illuminate/queue/ConsoleServiceProvider.php @@ -0,0 +1,71 @@ +app->singleton('command.queue.table', function ($app) { + return new TableCommand($app['files'], $app['composer']); + }); + + $this->app->singleton('command.queue.failed', function () { + return new ListFailedCommand; + }); + + $this->app->singleton('command.queue.retry', function () { + return new RetryCommand; + }); + + $this->app->singleton('command.queue.forget', function () { + return new ForgetFailedCommand; + }); + + $this->app->singleton('command.queue.flush', function () { + return new FlushFailedCommand; + }); + + $this->app->singleton('command.queue.failed-table', function ($app) { + return new FailedTableCommand($app['files'], $app['composer']); + }); + + $this->commands( + 'command.queue.table', 'command.queue.failed', 'command.queue.retry', + 'command.queue.forget', 'command.queue.flush', 'command.queue.failed-table' + ); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'command.queue.table', 'command.queue.failed', 'command.queue.retry', + 'command.queue.forget', 'command.queue.flush', 'command.queue.failed-table', + ]; + } +} diff --git a/vendor/illuminate/queue/DatabaseQueue.php b/vendor/illuminate/queue/DatabaseQueue.php new file mode 100644 index 0000000..7aa6db8 --- /dev/null +++ b/vendor/illuminate/queue/DatabaseQueue.php @@ -0,0 +1,323 @@ +table = $table; + $this->expire = $expire; + $this->default = $default; + $this->database = $database; + } + + /** + * Push a new job onto the queue. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function push($job, $data = '', $queue = null) + { + return $this->pushToDatabase(0, $queue, $this->createPayload($job, $data)); + } + + /** + * Push a raw payload onto the queue. + * + * @param string $payload + * @param string $queue + * @param array $options + * @return mixed + */ + public function pushRaw($payload, $queue = null, array $options = []) + { + return $this->pushToDatabase(0, $queue, $payload); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTime|int $delay + * @param string $job + * @param mixed $data + * @param string $queue + * @return void + */ + public function later($delay, $job, $data = '', $queue = null) + { + return $this->pushToDatabase($delay, $queue, $this->createPayload($job, $data)); + } + + /** + * Push an array of jobs onto the queue. + * + * @param array $jobs + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function bulk($jobs, $data = '', $queue = null) + { + $queue = $this->getQueue($queue); + + $availableAt = $this->getAvailableAt(0); + + $records = array_map(function ($job) use ($queue, $data, $availableAt) { + return $this->buildDatabaseRecord( + $queue, $this->createPayload($job, $data), $availableAt + ); + }, (array) $jobs); + + return $this->database->table($this->table)->insert($records); + } + + /** + * Release a reserved job back onto the queue. + * + * @param string $queue + * @param \StdClass $job + * @param int $delay + * @return mixed + */ + public function release($queue, $job, $delay) + { + return $this->pushToDatabase($delay, $queue, $job->payload, $job->attempts); + } + + /** + * Push a raw payload to the database with a given delay. + * + * @param \DateTime|int $delay + * @param string|null $queue + * @param string $payload + * @param int $attempts + * @return mixed + */ + protected function pushToDatabase($delay, $queue, $payload, $attempts = 0) + { + $attributes = $this->buildDatabaseRecord( + $this->getQueue($queue), $payload, $this->getAvailableAt($delay), $attempts + ); + + return $this->database->table($this->table)->insertGetId($attributes); + } + + /** + * Pop the next job off of the queue. + * + * @param string $queue + * @return \Illuminate\Contracts\Queue\Job|null + */ + public function pop($queue = null) + { + $queue = $this->getQueue($queue); + + if (! is_null($this->expire)) { + $this->releaseJobsThatHaveBeenReservedTooLong($queue); + } + + if ($job = $this->getNextAvailableJob($queue)) { + $this->markJobAsReserved($job->id); + + $this->database->commit(); + + return new DatabaseJob( + $this->container, $this, $job, $queue + ); + } + + $this->database->commit(); + } + + /** + * Release the jobs that have been reserved for too long. + * + * @param string $queue + * @return void + */ + protected function releaseJobsThatHaveBeenReservedTooLong($queue) + { + $expired = Carbon::now()->subSeconds($this->expire)->getTimestamp(); + + $this->database->table($this->table) + ->where('queue', $this->getQueue($queue)) + ->where('reserved', 1) + ->where('reserved_at', '<=', $expired) + ->update([ + 'reserved' => 0, + 'reserved_at' => null, + 'attempts' => new Expression('attempts + 1'), + ]); + } + + /** + * Get the next available job for the queue. + * + * @param string|null $queue + * @return \StdClass|null + */ + protected function getNextAvailableJob($queue) + { + $this->database->beginTransaction(); + + $job = $this->database->table($this->table) + ->lockForUpdate() + ->where('queue', $this->getQueue($queue)) + ->where('reserved', 0) + ->where('available_at', '<=', $this->getTime()) + ->orderBy('id', 'asc') + ->first(); + + return $job ? (object) $job : null; + } + + /** + * Mark the given job ID as reserved. + * + * @param string $id + * @return void + */ + protected function markJobAsReserved($id) + { + $this->database->table($this->table)->where('id', $id)->update([ + 'reserved' => 1, 'reserved_at' => $this->getTime(), + ]); + } + + /** + * Delete a reserved job from the queue. + * + * @param string $queue + * @param string $id + * @return void + */ + public function deleteReserved($queue, $id) + { + $this->database->table($this->table)->where('id', $id)->delete(); + } + + /** + * Get the "available at" UNIX timestamp. + * + * @param \DateTime|int $delay + * @return int + */ + protected function getAvailableAt($delay) + { + $availableAt = $delay instanceof DateTime ? $delay : Carbon::now()->addSeconds($delay); + + return $availableAt->getTimestamp(); + } + + /** + * Create an array to insert for the given job. + * + * @param string|null $queue + * @param string $payload + * @param int $availableAt + * @param int $attempts + * @return array + */ + protected function buildDatabaseRecord($queue, $payload, $availableAt, $attempts = 0) + { + return [ + 'queue' => $queue, + 'payload' => $payload, + 'attempts' => $attempts, + 'reserved' => 0, + 'reserved_at' => null, + 'available_at' => $availableAt, + 'created_at' => $this->getTime(), + ]; + } + + /** + * Get the queue or return the default. + * + * @param string|null $queue + * @return string + */ + protected function getQueue($queue) + { + return $queue ?: $this->default; + } + + /** + * Get the underlying database instance. + * + * @return \Illuminate\Database\Connection + */ + public function getDatabase() + { + return $this->database; + } + + /** + * Get the expiration time in seconds. + * + * @return int|null + */ + public function getExpire() + { + return $this->expire; + } + + /** + * Set the expiration time in seconds. + * + * @param int|null $seconds + * @return void + */ + public function setExpire($seconds) + { + $this->expire = $seconds; + } +} diff --git a/vendor/illuminate/queue/Failed/DatabaseFailedJobProvider.php b/vendor/illuminate/queue/Failed/DatabaseFailedJobProvider.php new file mode 100644 index 0000000..5758627 --- /dev/null +++ b/vendor/illuminate/queue/Failed/DatabaseFailedJobProvider.php @@ -0,0 +1,112 @@ +table = $table; + $this->resolver = $resolver; + $this->database = $database; + } + + /** + * Log a failed job into storage. + * + * @param string $connection + * @param string $queue + * @param string $payload + * @return void + */ + public function log($connection, $queue, $payload) + { + $failed_at = Carbon::now(); + + $this->getTable()->insert(compact('connection', 'queue', 'payload', 'failed_at')); + } + + /** + * Get a list of all of the failed jobs. + * + * @return array + */ + public function all() + { + return $this->getTable()->orderBy('id', 'desc')->get(); + } + + /** + * Get a single failed job. + * + * @param mixed $id + * @return array + */ + public function find($id) + { + return $this->getTable()->find($id); + } + + /** + * Delete a single failed job from storage. + * + * @param mixed $id + * @return bool + */ + public function forget($id) + { + return $this->getTable()->where('id', $id)->delete() > 0; + } + + /** + * Flush all of the failed jobs from storage. + * + * @return void + */ + public function flush() + { + $this->getTable()->delete(); + } + + /** + * Get a new query builder instance for the table. + * + * @return \Illuminate\Database\Query\Builder + */ + protected function getTable() + { + return $this->resolver->connection($this->database)->table($this->table); + } +} diff --git a/vendor/illuminate/queue/Failed/FailedJobProviderInterface.php b/vendor/illuminate/queue/Failed/FailedJobProviderInterface.php new file mode 100644 index 0000000..1b207c0 --- /dev/null +++ b/vendor/illuminate/queue/Failed/FailedJobProviderInterface.php @@ -0,0 +1,46 @@ +crypt = $crypt; + } + + /** + * Fire the Closure based queue job. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @param array $data + * @return void + */ + public function fire($job, $data) + { + $closure = unserialize($this->crypt->decrypt($data['closure'])); + + $closure($job); + } +} diff --git a/vendor/illuminate/queue/InteractsWithQueue.php b/vendor/illuminate/queue/InteractsWithQueue.php new file mode 100644 index 0000000..bf1e021 --- /dev/null +++ b/vendor/illuminate/queue/InteractsWithQueue.php @@ -0,0 +1,63 @@ +job) { + return $this->job->delete(); + } + } + + /** + * Release the job back into the queue. + * + * @param int $delay + * @return void + */ + public function release($delay = 0) + { + if ($this->job) { + return $this->job->release($delay); + } + } + + /** + * Get the number of times the job has been attempted. + * + * @return int + */ + public function attempts() + { + return $this->job ? $this->job->attempts() : 1; + } + + /** + * Set the base queue job instance. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @return $this + */ + public function setJob(JobContract $job) + { + $this->job = $job; + + return $this; + } +} diff --git a/vendor/illuminate/queue/IronQueue.php b/vendor/illuminate/queue/IronQueue.php new file mode 100755 index 0000000..2baaaf6 --- /dev/null +++ b/vendor/illuminate/queue/IronQueue.php @@ -0,0 +1,263 @@ +iron = $iron; + $this->request = $request; + $this->default = $default; + $this->shouldEncrypt = $shouldEncrypt; + } + + /** + * Push a new job onto the queue. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function push($job, $data = '', $queue = null) + { + return $this->pushRaw($this->createPayload($job, $data, $queue), $queue); + } + + /** + * Push a raw payload onto the queue. + * + * @param string $payload + * @param string $queue + * @param array $options + * @return mixed + */ + public function pushRaw($payload, $queue = null, array $options = []) + { + if ($this->shouldEncrypt) { + $payload = $this->crypt->encrypt($payload); + } + + return $this->iron->postMessage($this->getQueue($queue), $payload, $options)->id; + } + + /** + * Push a raw payload onto the queue after encrypting the payload. + * + * @param string $payload + * @param string $queue + * @param int $delay + * @return mixed + */ + public function recreate($payload, $queue = null, $delay) + { + $options = ['delay' => $this->getSeconds($delay)]; + + return $this->pushRaw($payload, $queue, $options); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTime|int $delay + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function later($delay, $job, $data = '', $queue = null) + { + $delay = $this->getSeconds($delay); + + $payload = $this->createPayload($job, $data, $queue); + + return $this->pushRaw($payload, $queue, compact('delay')); + } + + /** + * Pop the next job off of the queue. + * + * @param string $queue + * @return \Illuminate\Contracts\Queue\Job|null + */ + public function pop($queue = null) + { + $queue = $this->getQueue($queue); + + $job = $this->iron->getMessage($queue); + + // If we were able to pop a message off of the queue, we will need to decrypt + // the message body, as all Iron.io messages are encrypted, since the push + // queues will be a security hazard to unsuspecting developers using it. + if (! is_null($job)) { + $job->body = $this->parseJobBody($job->body); + + return new IronJob($this->container, $this, $job); + } + } + + /** + * Delete a message from the Iron queue. + * + * @param string $queue + * @param string $id + * @return void + */ + public function deleteMessage($queue, $id) + { + $this->iron->deleteMessage($queue, $id); + } + + /** + * Marshal a push queue request and fire the job. + * + * @return \Illuminate\Http\Response + * + * @deprecated since version 5.1. + */ + public function marshal() + { + $this->createPushedIronJob($this->marshalPushedJob())->fire(); + + return new Response('OK'); + } + + /** + * Marshal out the pushed job and payload. + * + * @return object + */ + protected function marshalPushedJob() + { + $r = $this->request; + + $body = $this->parseJobBody($r->getContent()); + + return (object) [ + 'id' => $r->header('iron-message-id'), 'body' => $body, 'pushed' => true, + ]; + } + + /** + * Create a new IronJob for a pushed job. + * + * @param object $job + * @return \Illuminate\Queue\Jobs\IronJob + */ + protected function createPushedIronJob($job) + { + return new IronJob($this->container, $this, $job, true); + } + + /** + * Create a payload string from the given job and data. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @return string + */ + protected function createPayload($job, $data = '', $queue = null) + { + $payload = $this->setMeta(parent::createPayload($job, $data), 'attempts', 1); + + return $this->setMeta($payload, 'queue', $this->getQueue($queue)); + } + + /** + * Parse the job body for firing. + * + * @param string $body + * @return string + */ + protected function parseJobBody($body) + { + return $this->shouldEncrypt ? $this->crypt->decrypt($body) : $body; + } + + /** + * Get the queue or return the default. + * + * @param string|null $queue + * @return string + */ + public function getQueue($queue) + { + return $queue ?: $this->default; + } + + /** + * Get the underlying IronMQ instance. + * + * @return \IronMQ\IronMQ + */ + public function getIron() + { + return $this->iron; + } + + /** + * Get the request instance. + * + * @return \Illuminate\Http\Request + */ + public function getRequest() + { + return $this->request; + } + + /** + * Set the request instance. + * + * @param \Illuminate\Http\Request $request + * @return void + */ + public function setRequest(Request $request) + { + $this->request = $request; + } +} diff --git a/vendor/illuminate/queue/Jobs/BeanstalkdJob.php b/vendor/illuminate/queue/Jobs/BeanstalkdJob.php new file mode 100755 index 0000000..8c041e1 --- /dev/null +++ b/vendor/illuminate/queue/Jobs/BeanstalkdJob.php @@ -0,0 +1,154 @@ +job = $job; + $this->queue = $queue; + $this->container = $container; + $this->pheanstalk = $pheanstalk; + } + + /** + * Fire the job. + * + * @return void + */ + public function fire() + { + $this->resolveAndFire(json_decode($this->getRawBody(), true)); + } + + /** + * Get the raw body string for the job. + * + * @return string + */ + public function getRawBody() + { + return $this->job->getData(); + } + + /** + * Delete the job from the queue. + * + * @return void + */ + public function delete() + { + parent::delete(); + + $this->pheanstalk->delete($this->job); + } + + /** + * Release the job back into the queue. + * + * @param int $delay + * @return void + */ + public function release($delay = 0) + { + parent::release($delay); + + $priority = Pheanstalk::DEFAULT_PRIORITY; + + $this->pheanstalk->release($this->job, $priority, $delay); + } + + /** + * Bury the job in the queue. + * + * @return void + */ + public function bury() + { + $this->pheanstalk->bury($this->job); + } + + /** + * Get the number of times the job has been attempted. + * + * @return int + */ + public function attempts() + { + $stats = $this->pheanstalk->statsJob($this->job); + + return (int) $stats->reserves; + } + + /** + * Get the job identifier. + * + * @return string + */ + public function getJobId() + { + return $this->job->getId(); + } + + /** + * Get the IoC container instance. + * + * @return \Illuminate\Container\Container + */ + public function getContainer() + { + return $this->container; + } + + /** + * Get the underlying Pheanstalk instance. + * + * @return \Pheanstalk\Pheanstalk + */ + public function getPheanstalk() + { + return $this->pheanstalk; + } + + /** + * Get the underlying Pheanstalk job. + * + * @return \Pheanstalk\Job + */ + public function getPheanstalkJob() + { + return $this->job; + } +} diff --git a/vendor/illuminate/queue/Jobs/DatabaseJob.php b/vendor/illuminate/queue/Jobs/DatabaseJob.php new file mode 100644 index 0000000..c60eed4 --- /dev/null +++ b/vendor/illuminate/queue/Jobs/DatabaseJob.php @@ -0,0 +1,139 @@ +job = $job; + $this->queue = $queue; + $this->database = $database; + $this->container = $container; + $this->job->attempts = $this->job->attempts + 1; + } + + /** + * Fire the job. + * + * @return void + */ + public function fire() + { + $this->resolveAndFire(json_decode($this->job->payload, true)); + } + + /** + * Delete the job from the queue. + * + * @return void + */ + public function delete() + { + parent::delete(); + + $this->database->deleteReserved($this->queue, $this->job->id); + } + + /** + * Release the job back into the queue. + * + * @param int $delay + * @return void + */ + public function release($delay = 0) + { + parent::release($delay); + + $this->delete(); + + $this->database->release($this->queue, $this->job, $delay); + } + + /** + * Get the number of times the job has been attempted. + * + * @return int + */ + public function attempts() + { + return (int) $this->job->attempts; + } + + /** + * Get the job identifier. + * + * @return string + */ + public function getJobId() + { + return $this->job->id; + } + + /** + * Get the raw body string for the job. + * + * @return string + */ + public function getRawBody() + { + return $this->job->payload; + } + + /** + * Get the IoC container instance. + * + * @return \Illuminate\Container\Container + */ + public function getContainer() + { + return $this->container; + } + + /** + * Get the underlying queue driver instance. + * + * @return \Illuminate\Queue\DatabaseQueue + */ + public function getDatabaseQueue() + { + return $this->database; + } + + /** + * Get the underlying database job. + * + * @return \StdClass + */ + public function getDatabaseJob() + { + return $this->job; + } +} diff --git a/vendor/illuminate/queue/Jobs/IronJob.php b/vendor/illuminate/queue/Jobs/IronJob.php new file mode 100755 index 0000000..6793bcd --- /dev/null +++ b/vendor/illuminate/queue/Jobs/IronJob.php @@ -0,0 +1,180 @@ +job = $job; + $this->iron = $iron; + $this->pushed = $pushed; + $this->container = $container; + } + + /** + * Fire the job. + * + * @return void + */ + public function fire() + { + $this->resolveAndFire(json_decode($this->getRawBody(), true)); + } + + /** + * Get the raw body string for the job. + * + * @return string + */ + public function getRawBody() + { + return $this->job->body; + } + + /** + * Delete the job from the queue. + * + * @return void + */ + public function delete() + { + parent::delete(); + + if (isset($this->job->pushed)) { + return; + } + + $this->iron->deleteMessage($this->getQueue(), $this->job->id); + } + + /** + * Release the job back into the queue. + * + * @param int $delay + * @return void + */ + public function release($delay = 0) + { + parent::release($delay); + + if (! $this->pushed) { + $this->delete(); + } + + $this->recreateJob($delay); + } + + /** + * Release a pushed job back onto the queue. + * + * @param int $delay + * @return void + */ + protected function recreateJob($delay) + { + $payload = json_decode($this->job->body, true); + + Arr::set($payload, 'attempts', Arr::get($payload, 'attempts', 1) + 1); + + $this->iron->recreate(json_encode($payload), $this->getQueue(), $delay); + } + + /** + * Get the number of times the job has been attempted. + * + * @return int + */ + public function attempts() + { + return Arr::get(json_decode($this->job->body, true), 'attempts', 1); + } + + /** + * Get the job identifier. + * + * @return string + */ + public function getJobId() + { + return $this->job->id; + } + + /** + * Get the IoC container instance. + * + * @return \Illuminate\Container\Container + */ + public function getContainer() + { + return $this->container; + } + + /** + * Get the underlying Iron queue instance. + * + * @return \Illuminate\Queue\IronQueue + */ + public function getIron() + { + return $this->iron; + } + + /** + * Get the underlying IronMQ job. + * + * @return array + */ + public function getIronJob() + { + return $this->job; + } + + /** + * Get the name of the queue the job belongs to. + * + * @return string + */ + public function getQueue() + { + return Arr::get(json_decode($this->job->body, true), 'queue'); + } +} diff --git a/vendor/illuminate/queue/Jobs/Job.php b/vendor/illuminate/queue/Jobs/Job.php new file mode 100755 index 0000000..304bc9d --- /dev/null +++ b/vendor/illuminate/queue/Jobs/Job.php @@ -0,0 +1,270 @@ +deleted = true; + } + + /** + * Determine if the job has been deleted. + * + * @return bool + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Release the job back into the queue. + * + * @param int $delay + * @return void + */ + public function release($delay = 0) + { + $this->released = true; + } + + /** + * Determine if the job was released back into the queue. + * + * @return bool + */ + public function isReleased() + { + return $this->released; + } + + /** + * Determine if the job has been deleted or released. + * + * @return bool + */ + public function isDeletedOrReleased() + { + return $this->isDeleted() || $this->isReleased(); + } + + /** + * Get the number of times the job has been attempted. + * + * @return int + */ + abstract public function attempts(); + + /** + * Get the raw body string for the job. + * + * @return string + */ + abstract public function getRawBody(); + + /** + * Resolve and fire the job handler method. + * + * @param array $payload + * @return void + */ + protected function resolveAndFire(array $payload) + { + list($class, $method) = $this->parseJob($payload['job']); + + $this->instance = $this->resolve($class); + + $this->instance->{$method}($this, $this->resolveQueueableEntities($payload['data'])); + } + + /** + * Parse the job declaration into class and method. + * + * @param string $job + * @return array + */ + protected function parseJob($job) + { + $segments = explode('@', $job); + + return count($segments) > 1 ? $segments : [$segments[0], 'fire']; + } + + /** + * Resolve the given job handler. + * + * @param string $class + * @return mixed + */ + protected function resolve($class) + { + return $this->container->make($class); + } + + /** + * Resolve all of the queueable entities in the given payload. + * + * @param mixed $data + * @return mixed + */ + protected function resolveQueueableEntities($data) + { + if (is_string($data)) { + return $this->resolveQueueableEntity($data); + } + + if (is_array($data)) { + $data = array_map(function ($d) { + if (is_array($d)) { + return $this->resolveQueueableEntities($d); + } + + return $this->resolveQueueableEntity($d); + }, $data); + } + + return $data; + } + + /** + * Resolve a single queueable entity from the resolver. + * + * @param mixed $value + * @return \Illuminate\Contracts\Queue\QueueableEntity + */ + protected function resolveQueueableEntity($value) + { + if (is_string($value) && Str::startsWith($value, '::entity::')) { + list($marker, $type, $id) = explode('|', $value, 3); + + return $this->getEntityResolver()->resolve($type, $id); + } + + return $value; + } + + /** + * Call the failed method on the job instance. + * + * @return void + */ + public function failed() + { + $payload = json_decode($this->getRawBody(), true); + + list($class, $method) = $this->parseJob($payload['job']); + + $this->instance = $this->resolve($class); + + if (method_exists($this->instance, 'failed')) { + $this->instance->failed($this->resolveQueueableEntities($payload['data'])); + } + } + + /** + * Get an entity resolver instance. + * + * @return \Illuminate\Contracts\Queue\EntityResolver + */ + protected function getEntityResolver() + { + return $this->container->make('Illuminate\Contracts\Queue\EntityResolver'); + } + + /** + * Calculate the number of seconds with the given delay. + * + * @param \DateTime|int $delay + * @return int + */ + protected function getSeconds($delay) + { + if ($delay instanceof DateTime) { + return max(0, $delay->getTimestamp() - $this->getTime()); + } + + return (int) $delay; + } + + /** + * Get the current system time. + * + * @return int + */ + protected function getTime() + { + return time(); + } + + /** + * Get the name of the queued job class. + * + * @return string + */ + public function getName() + { + return json_decode($this->getRawBody(), true)['job']; + } + + /** + * Get the name of the queue the job belongs to. + * + * @return string + */ + public function getQueue() + { + return $this->queue; + } +} diff --git a/vendor/illuminate/queue/Jobs/RedisJob.php b/vendor/illuminate/queue/Jobs/RedisJob.php new file mode 100644 index 0000000..af9ca97 --- /dev/null +++ b/vendor/illuminate/queue/Jobs/RedisJob.php @@ -0,0 +1,139 @@ +job = $job; + $this->redis = $redis; + $this->queue = $queue; + $this->container = $container; + } + + /** + * Fire the job. + * + * @return void + */ + public function fire() + { + $this->resolveAndFire(json_decode($this->getRawBody(), true)); + } + + /** + * Get the raw body string for the job. + * + * @return string + */ + public function getRawBody() + { + return $this->job; + } + + /** + * Delete the job from the queue. + * + * @return void + */ + public function delete() + { + parent::delete(); + + $this->redis->deleteReserved($this->queue, $this->job); + } + + /** + * Release the job back into the queue. + * + * @param int $delay + * @return void + */ + public function release($delay = 0) + { + parent::release($delay); + + $this->delete(); + + $this->redis->release($this->queue, $this->job, $delay, $this->attempts() + 1); + } + + /** + * Get the number of times the job has been attempted. + * + * @return int + */ + public function attempts() + { + return Arr::get(json_decode($this->job, true), 'attempts'); + } + + /** + * Get the job identifier. + * + * @return string + */ + public function getJobId() + { + return Arr::get(json_decode($this->job, true), 'id'); + } + + /** + * Get the IoC container instance. + * + * @return \Illuminate\Container\Container + */ + public function getContainer() + { + return $this->container; + } + + /** + * Get the underlying queue driver instance. + * + * @return \Illuminate\Redis\Database + */ + public function getRedisQueue() + { + return $this->redis; + } + + /** + * Get the underlying Redis job. + * + * @return string + */ + public function getRedisJob() + { + return $this->job; + } +} diff --git a/vendor/illuminate/queue/Jobs/SqsJob.php b/vendor/illuminate/queue/Jobs/SqsJob.php new file mode 100755 index 0000000..b676a52 --- /dev/null +++ b/vendor/illuminate/queue/Jobs/SqsJob.php @@ -0,0 +1,147 @@ +sqs = $sqs; + $this->job = $job; + $this->queue = $queue; + $this->container = $container; + } + + /** + * Fire the job. + * + * @return void + */ + public function fire() + { + $this->resolveAndFire(json_decode($this->getRawBody(), true)); + } + + /** + * Get the raw body string for the job. + * + * @return string + */ + public function getRawBody() + { + return $this->job['Body']; + } + + /** + * Delete the job from the queue. + * + * @return void + */ + public function delete() + { + parent::delete(); + + $this->sqs->deleteMessage([ + + 'QueueUrl' => $this->queue, 'ReceiptHandle' => $this->job['ReceiptHandle'], + + ]); + } + + /** + * Release the job back into the queue. + * + * @param int $delay + * @return void + */ + public function release($delay = 0) + { + parent::release($delay); + + $this->sqs->changeMessageVisibility([ + 'QueueUrl' => $this->queue, + 'ReceiptHandle' => $this->job['ReceiptHandle'], + 'VisibilityTimeout' => $delay, + ]); + } + + /** + * Get the number of times the job has been attempted. + * + * @return int + */ + public function attempts() + { + return (int) $this->job['Attributes']['ApproximateReceiveCount']; + } + + /** + * Get the job identifier. + * + * @return string + */ + public function getJobId() + { + return $this->job['MessageId']; + } + + /** + * Get the IoC container instance. + * + * @return \Illuminate\Container\Container + */ + public function getContainer() + { + return $this->container; + } + + /** + * Get the underlying SQS client instance. + * + * @return \Aws\Sqs\SqsClient + */ + public function getSqs() + { + return $this->sqs; + } + + /** + * Get the underlying raw SQS job. + * + * @return array + */ + public function getSqsJob() + { + return $this->job; + } +} diff --git a/vendor/illuminate/queue/Jobs/SyncJob.php b/vendor/illuminate/queue/Jobs/SyncJob.php new file mode 100755 index 0000000..fe7df17 --- /dev/null +++ b/vendor/illuminate/queue/Jobs/SyncJob.php @@ -0,0 +1,87 @@ +payload = $payload; + $this->container = $container; + } + + /** + * Fire the job. + * + * @return void + */ + public function fire() + { + $this->resolveAndFire(json_decode($this->payload, true)); + } + + /** + * Get the raw body string for the job. + * + * @return string + */ + public function getRawBody() + { + return $this->payload; + } + + /** + * Release the job back into the queue. + * + * @param int $delay + * @return void + */ + public function release($delay = 0) + { + parent::release($delay); + } + + /** + * Get the number of times the job has been attempted. + * + * @return int + */ + public function attempts() + { + return 1; + } + + /** + * Get the job identifier. + * + * @return string + */ + public function getJobId() + { + return ''; + } +} diff --git a/vendor/illuminate/queue/Listener.php b/vendor/illuminate/queue/Listener.php new file mode 100755 index 0000000..b19d46c --- /dev/null +++ b/vendor/illuminate/queue/Listener.php @@ -0,0 +1,265 @@ +commandPath = $commandPath; + $this->workerCommand = $this->buildWorkerCommand(); + } + + /** + * Build the environment specific worker command. + * + * @return string + */ + protected function buildWorkerCommand() + { + $binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)); + + if (defined('HHVM_VERSION')) { + $binary .= ' --php'; + } + + if (defined('ARTISAN_BINARY')) { + $artisan = ProcessUtils::escapeArgument(ARTISAN_BINARY); + } else { + $artisan = 'artisan'; + } + + $command = 'queue:work %s --queue=%s --delay=%s --memory=%s --sleep=%s --tries=%s'; + + return "{$binary} {$artisan} {$command}"; + } + + /** + * Listen to the given queue connection. + * + * @param string $connection + * @param string $queue + * @param string $delay + * @param string $memory + * @param int $timeout + * @return void + */ + public function listen($connection, $queue, $delay, $memory, $timeout = 60) + { + $process = $this->makeProcess($connection, $queue, $delay, $memory, $timeout); + + while (true) { + $this->runProcess($process, $memory); + } + } + + /** + * Run the given process. + * + * @param \Symfony\Component\Process\Process $process + * @param int $memory + * @return void + */ + public function runProcess(Process $process, $memory) + { + $process->run(function ($type, $line) { + $this->handleWorkerOutput($type, $line); + }); + + // Once we have run the job we'll go check if the memory limit has been + // exceeded for the script. If it has, we will kill this script so a + // process manager will restart this with a clean slate of memory. + if ($this->memoryExceeded($memory)) { + $this->stop(); + } + } + + /** + * Create a new Symfony process for the worker. + * + * @param string $connection + * @param string $queue + * @param int $delay + * @param int $memory + * @param int $timeout + * @return \Symfony\Component\Process\Process + */ + public function makeProcess($connection, $queue, $delay, $memory, $timeout) + { + $string = $this->workerCommand; + + // If the environment is set, we will append it to the command string so the + // workers will run under the specified environment. Otherwise, they will + // just run under the production environment which is not always right. + if (isset($this->environment)) { + $string .= ' --env='.ProcessUtils::escapeArgument($this->environment); + } + + // Next, we will just format out the worker commands with all of the various + // options available for the command. This will produce the final command + // line that we will pass into a Symfony process object for processing. + $command = sprintf( + $string, + ProcessUtils::escapeArgument($connection), + ProcessUtils::escapeArgument($queue), + $delay, + $memory, + $this->sleep, + $this->maxTries + ); + + return new Process($command, $this->commandPath, null, null, $timeout); + } + + /** + * Handle output from the worker process. + * + * @param int $type + * @param string $line + * @return void + */ + protected function handleWorkerOutput($type, $line) + { + if (isset($this->outputHandler)) { + call_user_func($this->outputHandler, $type, $line); + } + } + + /** + * Determine if the memory limit has been exceeded. + * + * @param int $memoryLimit + * @return bool + */ + public function memoryExceeded($memoryLimit) + { + return (memory_get_usage() / 1024 / 1024) >= $memoryLimit; + } + + /** + * Stop listening and bail out of the script. + * + * @return void + */ + public function stop() + { + die; + } + + /** + * Set the output handler callback. + * + * @param \Closure $outputHandler + * @return void + */ + public function setOutputHandler(Closure $outputHandler) + { + $this->outputHandler = $outputHandler; + } + + /** + * Get the current listener environment. + * + * @return string + */ + public function getEnvironment() + { + return $this->environment; + } + + /** + * Set the current environment. + * + * @param string $environment + * @return void + */ + public function setEnvironment($environment) + { + $this->environment = $environment; + } + + /** + * Get the amount of seconds to wait before polling the queue. + * + * @return int + */ + public function getSleep() + { + return $this->sleep; + } + + /** + * Set the amount of seconds to wait before polling the queue. + * + * @param int $sleep + * @return void + */ + public function setSleep($sleep) + { + $this->sleep = $sleep; + } + + /** + * Set the amount of times to try a job before logging it failed. + * + * @param int $tries + * @return void + */ + public function setMaxTries($tries) + { + $this->maxTries = $tries; + } +} diff --git a/vendor/illuminate/queue/NullQueue.php b/vendor/illuminate/queue/NullQueue.php new file mode 100644 index 0000000..bdef6cc --- /dev/null +++ b/vendor/illuminate/queue/NullQueue.php @@ -0,0 +1,59 @@ +push($job, $data, $queue); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param string $queue + * @param \DateTime|int $delay + * @param string $job + * @param mixed $data + * @return mixed + */ + public function laterOn($queue, $delay, $job, $data = '') + { + return $this->later($delay, $job, $data, $queue); + } + + /** + * Marshal a push queue request and fire the job. + * + * @throws \RuntimeException + * + * @deprecated since version 5.1. + */ + public function marshal() + { + throw new RuntimeException('Push queues only supported by Iron.'); + } + + /** + * Push an array of jobs onto the queue. + * + * @param array $jobs + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function bulk($jobs, $data = '', $queue = null) + { + foreach ((array) $jobs as $job) { + $this->push($job, $data, $queue); + } + } + + /** + * Create a payload string from the given job and data. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @return string + */ + protected function createPayload($job, $data = '', $queue = null) + { + if ($job instanceof Closure) { + return json_encode($this->createClosurePayload($job, $data)); + } elseif (is_object($job)) { + return json_encode([ + 'job' => 'Illuminate\Queue\CallQueuedHandler@call', + 'data' => ['command' => serialize(clone $job)], + ]); + } + + return json_encode($this->createPlainPayload($job, $data)); + } + + /** + * Create a typical, "plain" queue payload array. + * + * @param string $job + * @param mixed $data + * @return array + */ + protected function createPlainPayload($job, $data) + { + return ['job' => $job, 'data' => $this->prepareQueueableEntities($data)]; + } + + /** + * Prepare any queueable entities for storage in the queue. + * + * @param mixed $data + * @return mixed + */ + protected function prepareQueueableEntities($data) + { + if ($data instanceof QueueableEntity) { + return $this->prepareQueueableEntity($data); + } + + if (is_array($data)) { + $data = array_map(function ($d) { + if (is_array($d)) { + return $this->prepareQueueableEntities($d); + } + + return $this->prepareQueueableEntity($d); + }, $data); + } + + return $data; + } + + /** + * Prepare a single queueable entity for storage on the queue. + * + * @param mixed $value + * @return mixed + */ + protected function prepareQueueableEntity($value) + { + if ($value instanceof QueueableEntity) { + return '::entity::|'.get_class($value).'|'.$value->getQueueableId(); + } + + return $value; + } + + /** + * Create a payload string for the given Closure job. + * + * @param \Closure $job + * @param mixed $data + * @return string + */ + protected function createClosurePayload($job, $data) + { + $closure = $this->crypt->encrypt((new Serializer)->serialize($job)); + + return ['job' => 'IlluminateQueueClosure', 'data' => compact('closure')]; + } + + /** + * Set additional meta on a payload string. + * + * @param string $payload + * @param string $key + * @param string $value + * @return string + */ + protected function setMeta($payload, $key, $value) + { + $payload = json_decode($payload, true); + + return json_encode(Arr::set($payload, $key, $value)); + } + + /** + * Calculate the number of seconds with the given delay. + * + * @param \DateTime|int $delay + * @return int + */ + protected function getSeconds($delay) + { + if ($delay instanceof DateTime) { + return max(0, $delay->getTimestamp() - $this->getTime()); + } + + return (int) $delay; + } + + /** + * Get the current UNIX timestamp. + * + * @return int + */ + protected function getTime() + { + return time(); + } + + /** + * Set the IoC container instance. + * + * @param \Illuminate\Container\Container $container + * @return void + */ + public function setContainer(Container $container) + { + $this->container = $container; + } + + /** + * Set the encrypter instance. + * + * @param \Illuminate\Contracts\Encryption\Encrypter $crypt + * @return void + */ + public function setEncrypter(EncrypterContract $crypt) + { + $this->crypt = $crypt; + } +} diff --git a/vendor/illuminate/queue/QueueManager.php b/vendor/illuminate/queue/QueueManager.php new file mode 100755 index 0000000..cf91bbd --- /dev/null +++ b/vendor/illuminate/queue/QueueManager.php @@ -0,0 +1,243 @@ +app = $app; + } + + /** + * Register an event listener for the after job event. + * + * @param mixed $callback + * @return void + */ + public function after($callback) + { + $this->app['events']->listen('illuminate.queue.after', $callback); + } + + /** + * Register an event listener for the daemon queue loop. + * + * @param mixed $callback + * @return void + */ + public function looping($callback) + { + $this->app['events']->listen('illuminate.queue.looping', $callback); + } + + /** + * Register an event listener for the failed job event. + * + * @param mixed $callback + * @return void + */ + public function failing($callback) + { + $this->app['events']->listen('illuminate.queue.failed', $callback); + } + + /** + * Register an event listener for the daemon queue stopping. + * + * @param mixed $callback + * @return void + */ + public function stopping($callback) + { + $this->app['events']->listen('illuminate.queue.stopping', $callback); + } + + /** + * Determine if the driver is connected. + * + * @param string $name + * @return bool + */ + public function connected($name = null) + { + return isset($this->connections[$name ?: $this->getDefaultDriver()]); + } + + /** + * Resolve a queue connection instance. + * + * @param string $name + * @return \Illuminate\Contracts\Queue\Queue + */ + public function connection($name = null) + { + $name = $name ?: $this->getDefaultDriver(); + + // If the connection has not been resolved yet we will resolve it now as all + // of the connections are resolved when they are actually needed so we do + // not make any unnecessary connection to the various queue end-points. + if (! isset($this->connections[$name])) { + $this->connections[$name] = $this->resolve($name); + + $this->connections[$name]->setContainer($this->app); + + $this->connections[$name]->setEncrypter($this->app['encrypter']); + } + + return $this->connections[$name]; + } + + /** + * Resolve a queue connection. + * + * @param string $name + * @return \Illuminate\Contracts\Queue\Queue + */ + protected function resolve($name) + { + $config = $this->getConfig($name); + + return $this->getConnector($config['driver'])->connect($config); + } + + /** + * Get the connector for a given driver. + * + * @param string $driver + * @return \Illuminate\Queue\Connectors\ConnectorInterface + * + * @throws \InvalidArgumentException + */ + protected function getConnector($driver) + { + if (isset($this->connectors[$driver])) { + return call_user_func($this->connectors[$driver]); + } + + throw new InvalidArgumentException("No connector for [$driver]"); + } + + /** + * Add a queue connection resolver. + * + * @param string $driver + * @param \Closure $resolver + * @return void + */ + public function extend($driver, Closure $resolver) + { + return $this->addConnector($driver, $resolver); + } + + /** + * Add a queue connection resolver. + * + * @param string $driver + * @param \Closure $resolver + * @return void + */ + public function addConnector($driver, Closure $resolver) + { + $this->connectors[$driver] = $resolver; + } + + /** + * Get the queue connection configuration. + * + * @param string $name + * @return array + */ + protected function getConfig($name) + { + return $this->app['config']["queue.connections.{$name}"]; + } + + /** + * Get the name of the default queue connection. + * + * @return string + */ + public function getDefaultDriver() + { + return $this->app['config']['queue.default']; + } + + /** + * Set the name of the default queue connection. + * + * @param string $name + * @return void + */ + public function setDefaultDriver($name) + { + $this->app['config']['queue.default'] = $name; + } + + /** + * Get the full name for the given connection. + * + * @param string $connection + * @return string + */ + public function getName($connection = null) + { + return $connection ?: $this->getDefaultDriver(); + } + + /** + * Determine if the application is in maintenance mode. + * + * @return bool + */ + public function isDownForMaintenance() + { + return $this->app->isDownForMaintenance(); + } + + /** + * Dynamically pass calls to the default connection. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + $callable = [$this->connection(), $method]; + + return call_user_func_array($callable, $parameters); + } +} diff --git a/vendor/illuminate/queue/QueueServiceProvider.php b/vendor/illuminate/queue/QueueServiceProvider.php new file mode 100755 index 0000000..bf61e06 --- /dev/null +++ b/vendor/illuminate/queue/QueueServiceProvider.php @@ -0,0 +1,326 @@ +registerManager(); + + $this->registerWorker(); + + $this->registerListener(); + + $this->registerSubscriber(); + + $this->registerFailedJobServices(); + + $this->registerQueueClosure(); + } + + /** + * Register the queue manager. + * + * @return void + */ + protected function registerManager() + { + $this->app->singleton('queue', function ($app) { + // Once we have an instance of the queue manager, we will register the various + // resolvers for the queue connectors. These connectors are responsible for + // creating the classes that accept queue configs and instantiate queues. + $manager = new QueueManager($app); + + $this->registerConnectors($manager); + + return $manager; + }); + + $this->app->singleton('queue.connection', function ($app) { + return $app['queue']->connection(); + }); + } + + /** + * Register the queue worker. + * + * @return void + */ + protected function registerWorker() + { + $this->registerWorkCommand(); + + $this->registerRestartCommand(); + + $this->app->singleton('queue.worker', function ($app) { + return new Worker($app['queue'], $app['queue.failer'], $app['events']); + }); + } + + /** + * Register the queue worker console command. + * + * @return void + */ + protected function registerWorkCommand() + { + $this->app->singleton('command.queue.work', function ($app) { + return new WorkCommand($app['queue.worker']); + }); + + $this->commands('command.queue.work'); + } + + /** + * Register the queue listener. + * + * @return void + */ + protected function registerListener() + { + $this->registerListenCommand(); + + $this->app->singleton('queue.listener', function ($app) { + return new Listener($app->basePath()); + }); + } + + /** + * Register the queue listener console command. + * + * @return void + */ + protected function registerListenCommand() + { + $this->app->singleton('command.queue.listen', function ($app) { + return new ListenCommand($app['queue.listener']); + }); + + $this->commands('command.queue.listen'); + } + + /** + * Register the queue restart console command. + * + * @return void + */ + public function registerRestartCommand() + { + $this->app->singleton('command.queue.restart', function () { + return new RestartCommand; + }); + + $this->commands('command.queue.restart'); + } + + /** + * Register the push queue subscribe command. + * + * @return void + */ + protected function registerSubscriber() + { + $this->app->singleton('command.queue.subscribe', function () { + return new SubscribeCommand; + }); + + $this->commands('command.queue.subscribe'); + } + + /** + * Register the connectors on the queue manager. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + public function registerConnectors($manager) + { + foreach (['Null', 'Sync', 'Database', 'Beanstalkd', 'Redis', 'Sqs', 'Iron'] as $connector) { + $this->{"register{$connector}Connector"}($manager); + } + } + + /** + * Register the Null queue connector. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + protected function registerNullConnector($manager) + { + $manager->addConnector('null', function () { + return new NullConnector; + }); + } + + /** + * Register the Sync queue connector. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + protected function registerSyncConnector($manager) + { + $manager->addConnector('sync', function () { + return new SyncConnector; + }); + } + + /** + * Register the Beanstalkd queue connector. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + protected function registerBeanstalkdConnector($manager) + { + $manager->addConnector('beanstalkd', function () { + return new BeanstalkdConnector; + }); + } + + /** + * Register the database queue connector. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + protected function registerDatabaseConnector($manager) + { + $manager->addConnector('database', function () { + return new DatabaseConnector($this->app['db']); + }); + } + + /** + * Register the Redis queue connector. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + protected function registerRedisConnector($manager) + { + $app = $this->app; + + $manager->addConnector('redis', function () use ($app) { + return new RedisConnector($app['redis']); + }); + } + + /** + * Register the Amazon SQS queue connector. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + protected function registerSqsConnector($manager) + { + $manager->addConnector('sqs', function () { + return new SqsConnector; + }); + } + + /** + * Register the IronMQ queue connector. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + protected function registerIronConnector($manager) + { + $app = $this->app; + + $manager->addConnector('iron', function () use ($app) { + return new IronConnector($app['encrypter'], $app['request']); + }); + + $this->registerIronRequestBinder(); + } + + /** + * Register the request rebinding event for the Iron queue. + * + * @return void + */ + protected function registerIronRequestBinder() + { + $this->app->rebinding('request', function ($app, $request) { + if ($app['queue']->connected('iron')) { + $app['queue']->connection('iron')->setRequest($request); + } + }); + } + + /** + * Register the failed job services. + * + * @return void + */ + protected function registerFailedJobServices() + { + $this->app->singleton('queue.failer', function ($app) { + $config = $app['config']['queue.failed']; + + if (isset($config['table'])) { + return new DatabaseFailedJobProvider($app['db'], $config['database'], $config['table']); + } else { + return new NullFailedJobProvider; + } + }); + } + + /** + * Register the Illuminate queued closure job. + * + * @return void + */ + protected function registerQueueClosure() + { + $this->app->singleton('IlluminateQueueClosure', function ($app) { + return new IlluminateQueueClosure($app['encrypter']); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + 'queue', 'queue.worker', 'queue.listener', 'queue.failer', + 'command.queue.work', 'command.queue.listen', 'command.queue.restart', + 'command.queue.subscribe', 'queue.connection', + ]; + } +} diff --git a/vendor/illuminate/queue/README.md b/vendor/illuminate/queue/README.md new file mode 100644 index 0000000..e6a715b --- /dev/null +++ b/vendor/illuminate/queue/README.md @@ -0,0 +1,34 @@ +## Illuminate Queue + +The Laravel Queue component provides a unified API across a variety of different queue services. Queues allow you to defer the processing of a time consuming task, such as sending an e-mail, until a later time, thus drastically speeding up the web requests to your application. + +### Usage Instructions + +First, create a new Queue `Capsule` manager instance. Similar to the "Capsule" provided for the Eloquent ORM, the queue Capsule aims to make configuring the library for usage outside of the Laravel framework as easy as possible. + +```PHP +use Illuminate\Queue\Capsule\Manager as Queue; + +$queue = new Queue; + +$queue->addConnection([ + 'driver' => 'beanstalkd', + 'host' => 'localhost', + 'queue' => 'default', +]); + +// Make this Capsule instance available globally via static methods... (optional) +$queue->setAsGlobal(); +``` + +Once the Capsule instance has been registered. You may use it like so: + +```PHP +// As an instance... +$queue->push('SendEmail', array('message' => $message)); + +// If setAsGlobal has been called... +Queue::push('SendEmail', array('message' => $message)); +``` + +For further documentation on using the queue, consult the [Laravel framework documentation](http://laravel.com/docs). diff --git a/vendor/illuminate/queue/RedisQueue.php b/vendor/illuminate/queue/RedisQueue.php new file mode 100644 index 0000000..acd36ab --- /dev/null +++ b/vendor/illuminate/queue/RedisQueue.php @@ -0,0 +1,319 @@ +redis = $redis; + $this->default = $default; + $this->connection = $connection; + } + + /** + * Push a new job onto the queue. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function push($job, $data = '', $queue = null) + { + return $this->pushRaw($this->createPayload($job, $data), $queue); + } + + /** + * Push a raw payload onto the queue. + * + * @param string $payload + * @param string $queue + * @param array $options + * @return mixed + */ + public function pushRaw($payload, $queue = null, array $options = []) + { + $this->getConnection()->rpush($this->getQueue($queue), $payload); + + return Arr::get(json_decode($payload, true), 'id'); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTime|int $delay + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function later($delay, $job, $data = '', $queue = null) + { + $payload = $this->createPayload($job, $data); + + $delay = $this->getSeconds($delay); + + $this->getConnection()->zadd($this->getQueue($queue).':delayed', $this->getTime() + $delay, $payload); + + return Arr::get(json_decode($payload, true), 'id'); + } + + /** + * Release a reserved job back onto the queue. + * + * @param string $queue + * @param string $payload + * @param int $delay + * @param int $attempts + * @return void + */ + public function release($queue, $payload, $delay, $attempts) + { + $payload = $this->setMeta($payload, 'attempts', $attempts); + + $this->getConnection()->zadd($this->getQueue($queue).':delayed', $this->getTime() + $delay, $payload); + } + + /** + * Pop the next job off of the queue. + * + * @param string $queue + * @return \Illuminate\Contracts\Queue\Job|null + */ + public function pop($queue = null) + { + $original = $queue ?: $this->default; + + $queue = $this->getQueue($queue); + + if (! is_null($this->expire)) { + $this->migrateAllExpiredJobs($queue); + } + + $job = $this->getConnection()->lpop($queue); + + if (! is_null($job)) { + $this->getConnection()->zadd($queue.':reserved', $this->getTime() + $this->expire, $job); + + return new RedisJob($this->container, $this, $job, $original); + } + } + + /** + * Delete a reserved job from the queue. + * + * @param string $queue + * @param string $job + * @return void + */ + public function deleteReserved($queue, $job) + { + $this->getConnection()->zrem($this->getQueue($queue).':reserved', $job); + } + + /** + * Migrate all of the waiting jobs in the queue. + * + * @param string $queue + * @return void + */ + protected function migrateAllExpiredJobs($queue) + { + $this->migrateExpiredJobs($queue.':delayed', $queue); + + $this->migrateExpiredJobs($queue.':reserved', $queue); + } + + /** + * Migrate the delayed jobs that are ready to the regular queue. + * + * @param string $from + * @param string $to + * @return void + */ + public function migrateExpiredJobs($from, $to) + { + $options = ['cas' => true, 'watch' => $from, 'retry' => 10]; + + $this->getConnection()->transaction($options, function ($transaction) use ($from, $to) { + // First we need to get all of jobs that have expired based on the current time + // so that we can push them onto the main queue. After we get them we simply + // remove them from this "delay" queues. All of this within a transaction. + $jobs = $this->getExpiredJobs( + $transaction, $from, $time = $this->getTime() + ); + + // If we actually found any jobs, we will remove them from the old queue and we + // will insert them onto the new (ready) "queue". This means they will stand + // ready to be processed by the queue worker whenever their turn comes up. + if (count($jobs) > 0) { + $this->removeExpiredJobs($transaction, $from, $time); + + $this->pushExpiredJobsOntoNewQueue($transaction, $to, $jobs); + } + }); + } + + /** + * Get the expired jobs from a given queue. + * + * @param \Predis\Transaction\MultiExec $transaction + * @param string $from + * @param int $time + * @return array + */ + protected function getExpiredJobs($transaction, $from, $time) + { + return $transaction->zrangebyscore($from, '-inf', $time); + } + + /** + * Remove the expired jobs from a given queue. + * + * @param \Predis\Transaction\MultiExec $transaction + * @param string $from + * @param int $time + * @return void + */ + protected function removeExpiredJobs($transaction, $from, $time) + { + $transaction->multi(); + + $transaction->zremrangebyscore($from, '-inf', $time); + } + + /** + * Push all of the given jobs onto another queue. + * + * @param \Predis\Transaction\MultiExec $transaction + * @param string $to + * @param array $jobs + * @return void + */ + protected function pushExpiredJobsOntoNewQueue($transaction, $to, $jobs) + { + call_user_func_array([$transaction, 'rpush'], array_merge([$to], $jobs)); + } + + /** + * Create a payload string from the given job and data. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @return string + */ + protected function createPayload($job, $data = '', $queue = null) + { + $payload = parent::createPayload($job, $data); + + $payload = $this->setMeta($payload, 'id', $this->getRandomId()); + + return $this->setMeta($payload, 'attempts', 1); + } + + /** + * Get a random ID string. + * + * @return string + */ + protected function getRandomId() + { + return Str::random(32); + } + + /** + * Get the queue or return the default. + * + * @param string|null $queue + * @return string + */ + protected function getQueue($queue) + { + return 'queues:'.($queue ?: $this->default); + } + + /** + * Get the connection for the queue. + * + * @return \Predis\ClientInterface + */ + protected function getConnection() + { + return $this->redis->connection($this->connection); + } + + /** + * Get the underlying Redis instance. + * + * @return \Illuminate\Redis\Database + */ + public function getRedis() + { + return $this->redis; + } + + /** + * Get the expiration time in seconds. + * + * @return int|null + */ + public function getExpire() + { + return $this->expire; + } + + /** + * Set the expiration time in seconds. + * + * @param int|null $seconds + * @return void + */ + public function setExpire($seconds) + { + $this->expire = $seconds; + } +} diff --git a/vendor/illuminate/queue/SerializesModels.php b/vendor/illuminate/queue/SerializesModels.php new file mode 100644 index 0000000..23cdaac --- /dev/null +++ b/vendor/illuminate/queue/SerializesModels.php @@ -0,0 +1,80 @@ +getProperties(); + + foreach ($properties as $property) { + $property->setValue($this, $this->getSerializedPropertyValue( + $this->getPropertyValue($property) + )); + } + + return array_map(function ($p) { return $p->getName(); }, $properties); + } + + /** + * Restore the model after serialization. + * + * @return void + */ + public function __wakeup() + { + foreach ((new ReflectionClass($this))->getProperties() as $property) { + $property->setValue($this, $this->getRestoredPropertyValue( + $this->getPropertyValue($property) + )); + } + } + + /** + * Get the property value prepared for serialization. + * + * @param mixed $value + * @return mixed + */ + protected function getSerializedPropertyValue($value) + { + return $value instanceof QueueableEntity + ? new ModelIdentifier(get_class($value), $value->getQueueableId()) : $value; + } + + /** + * Get the restored property value after deserialization. + * + * @param mixed $value + * @return mixed + */ + protected function getRestoredPropertyValue($value) + { + return $value instanceof ModelIdentifier + ? (new $value->class)->findOrFail($value->id) : $value; + } + + /** + * Get the property value for the given property. + * + * @param \ReflectionProperty $property + * @return mixed + */ + protected function getPropertyValue(ReflectionProperty $property) + { + $property->setAccessible(true); + + return $property->getValue($this); + } +} diff --git a/vendor/illuminate/queue/SqsQueue.php b/vendor/illuminate/queue/SqsQueue.php new file mode 100755 index 0000000..f195ad6 --- /dev/null +++ b/vendor/illuminate/queue/SqsQueue.php @@ -0,0 +1,151 @@ +sqs = $sqs; + $this->default = $default; + } + + /** + * Push a new job onto the queue. + * + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function push($job, $data = '', $queue = null) + { + return $this->pushRaw($this->createPayload($job, $data), $queue); + } + + /** + * Push a raw payload onto the queue. + * + * @param string $payload + * @param string $queue + * @param array $options + * @return mixed + */ + public function pushRaw($payload, $queue = null, array $options = []) + { + $response = $this->sqs->sendMessage(['QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload]); + + return $response->get('MessageId'); + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTime|int $delay + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function later($delay, $job, $data = '', $queue = null) + { + $payload = $this->createPayload($job, $data); + + $delay = $this->getSeconds($delay); + + return $this->sqs->sendMessage([ + + 'QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload, 'DelaySeconds' => $delay, + + ])->get('MessageId'); + } + + /** + * Pop the next job off of the queue. + * + * @param string $queue + * @return \Illuminate\Contracts\Queue\Job|null + */ + public function pop($queue = null) + { + $queue = $this->getQueue($queue); + + $response = $this->sqs->receiveMessage( + ['QueueUrl' => $queue, 'AttributeNames' => ['ApproximateReceiveCount']] + ); + + if (count($response['Messages']) > 0) { + if ($this->jobCreator) { + return call_user_func($this->jobCreator, $this->container, $this->sqs, $queue, $response); + } else { + return new SqsJob($this->container, $this->sqs, $queue, $response['Messages'][0]); + } + } + } + + /** + * Define the job creator callback for the connection. + * + * @param callable $callback + * @return $this + */ + public function createJobsUsing(callable $callback) + { + $this->jobCreator = $callback; + + return $this; + } + + /** + * Get the queue or return the default. + * + * @param string|null $queue + * @return string + */ + public function getQueue($queue) + { + return $queue ?: $this->default; + } + + /** + * Get the underlying SQS instance. + * + * @return \Aws\Sqs\SqsClient + */ + public function getSqs() + { + return $this->sqs; + } +} diff --git a/vendor/illuminate/queue/SyncQueue.php b/vendor/illuminate/queue/SyncQueue.php new file mode 100755 index 0000000..de8db22 --- /dev/null +++ b/vendor/illuminate/queue/SyncQueue.php @@ -0,0 +1,134 @@ +resolveJob($this->createPayload($job, $data, $queue)); + + try { + $queueJob->fire(); + + $this->raiseAfterJobEvent($queueJob); + } catch (Exception $e) { + $this->handleFailedJob($queueJob); + + throw $e; + } catch (Throwable $e) { + $this->handleFailedJob($queueJob); + + throw $e; + } + + return 0; + } + + /** + * Push a raw payload onto the queue. + * + * @param string $payload + * @param string $queue + * @param array $options + * @return mixed + */ + public function pushRaw($payload, $queue = null, array $options = []) + { + // + } + + /** + * Push a new job onto the queue after a delay. + * + * @param \DateTime|int $delay + * @param string $job + * @param mixed $data + * @param string $queue + * @return mixed + */ + public function later($delay, $job, $data = '', $queue = null) + { + return $this->push($job, $data, $queue); + } + + /** + * Pop the next job off of the queue. + * + * @param string $queue + * @return \Illuminate\Contracts\Queue\Job|null + */ + public function pop($queue = null) + { + // + } + + /** + * Resolve a Sync job instance. + * + * @param string $payload + * @return \Illuminate\Queue\Jobs\SyncJob + */ + protected function resolveJob($payload) + { + return new SyncJob($this->container, $payload); + } + + /** + * Raise the after queue job event. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @return void + */ + protected function raiseAfterJobEvent(Job $job) + { + $data = json_decode($job->getRawBody(), true); + + if ($this->container->bound('events')) { + $this->container['events']->fire('illuminate.queue.after', ['sync', $job, $data]); + } + } + + /** + * Handle the failed job. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @return array + */ + protected function handleFailedJob(Job $job) + { + $job->failed(); + + $this->raiseFailedJobEvent($job); + } + + /** + * Raise the failed queue job event. + * + * @param \Illuminate\Contracts\Queue\Job $job + * @return void + */ + protected function raiseFailedJobEvent(Job $job) + { + $data = json_decode($job->getRawBody(), true); + + if ($this->container->bound('events')) { + $this->container['events']->fire('illuminate.queue.failed', ['sync', $job, $data]); + } + } +} diff --git a/vendor/illuminate/queue/Worker.php b/vendor/illuminate/queue/Worker.php new file mode 100755 index 0000000..7f65337 --- /dev/null +++ b/vendor/illuminate/queue/Worker.php @@ -0,0 +1,384 @@ +failer = $failer; + $this->events = $events; + $this->manager = $manager; + } + + /** + * Listen to the given queue in a loop. + * + * @param string $connectionName + * @param string $queue + * @param int $delay + * @param int $memory + * @param int $sleep + * @param int $maxTries + * @return array + */ + public function daemon($connectionName, $queue = null, $delay = 0, $memory = 128, $sleep = 3, $maxTries = 0) + { + $lastRestart = $this->getTimestampOfLastQueueRestart(); + + while (true) { + if ($this->daemonShouldRun()) { + $this->runNextJobForDaemon( + $connectionName, $queue, $delay, $sleep, $maxTries + ); + } else { + $this->sleep($sleep); + } + + if ($this->memoryExceeded($memory) || $this->queueShouldRestart($lastRestart)) { + $this->stop(); + } + } + } + + /** + * Run the next job for the daemon worker. + * + * @param string $connectionName + * @param string $queue + * @param int $delay + * @param int $sleep + * @param int $maxTries + * @return void + */ + protected function runNextJobForDaemon($connectionName, $queue, $delay, $sleep, $maxTries) + { + try { + $this->pop($connectionName, $queue, $delay, $sleep, $maxTries); + } catch (Exception $e) { + if ($this->exceptions) { + $this->exceptions->report($e); + } + } catch (Throwable $e) { + if ($this->exceptions) { + $this->exceptions->report(new FatalThrowableError($e)); + } + } + } + + /** + * Determine if the daemon should process on this iteration. + * + * @return bool + */ + protected function daemonShouldRun() + { + if ($this->manager->isDownForMaintenance()) { + return false; + } + + return $this->events->until('illuminate.queue.looping') !== false; + } + + /** + * Listen to the given queue. + * + * @param string $connectionName + * @param string $queue + * @param int $delay + * @param int $sleep + * @param int $maxTries + * @return array + */ + public function pop($connectionName, $queue = null, $delay = 0, $sleep = 3, $maxTries = 0) + { + $connection = $this->manager->connection($connectionName); + + $job = $this->getNextJob($connection, $queue); + + // If we're able to pull a job off of the stack, we will process it and + // then immediately return back out. If there is no job on the queue + // we will "sleep" the worker for the specified number of seconds. + if (! is_null($job)) { + return $this->process( + $this->manager->getName($connectionName), $job, $maxTries, $delay + ); + } + + $this->sleep($sleep); + + return ['job' => null, 'failed' => false]; + } + + /** + * Get the next job from the queue connection. + * + * @param \Illuminate\Contracts\Queue\Queue $connection + * @param string $queue + * @return \Illuminate\Contracts\Queue\Job|null + */ + protected function getNextJob($connection, $queue) + { + if (is_null($queue)) { + return $connection->pop(); + } + + foreach (explode(',', $queue) as $queue) { + if (! is_null($job = $connection->pop($queue))) { + return $job; + } + } + } + + /** + * Process a given job from the queue. + * + * @param string $connection + * @param \Illuminate\Contracts\Queue\Job $job + * @param int $maxTries + * @param int $delay + * @return array|null + * + * @throws \Throwable + */ + public function process($connection, Job $job, $maxTries = 0, $delay = 0) + { + if ($maxTries > 0 && $job->attempts() > $maxTries) { + return $this->logFailedJob($connection, $job); + } + + try { + // First we will fire off the job. Once it is done we will see if it will + // be auto-deleted after processing and if so we will go ahead and run + // the delete method on the job. Otherwise we will just keep moving. + $job->fire(); + + $this->raiseAfterJobEvent($connection, $job); + + return ['job' => $job, 'failed' => false]; + } catch (Exception $e) { + // If we catch an exception, we will attempt to release the job back onto + // the queue so it is not lost. This will let is be retried at a later + // time by another listener (or the same one). We will do that here. + if (! $job->isDeleted()) { + $job->release($delay); + } + + throw $e; + } catch (Throwable $e) { + if (! $job->isDeleted()) { + $job->release($delay); + } + + throw $e; + } + } + + /** + * Raise the after queue job event. + * + * @param string $connection + * @param \Illuminate\Contracts\Queue\Job $job + * @return void + */ + protected function raiseAfterJobEvent($connection, Job $job) + { + if ($this->events) { + $data = json_decode($job->getRawBody(), true); + + $this->events->fire('illuminate.queue.after', [$connection, $job, $data]); + } + } + + /** + * Log a failed job into storage. + * + * @param string $connection + * @param \Illuminate\Contracts\Queue\Job $job + * @return array + */ + protected function logFailedJob($connection, Job $job) + { + if ($this->failer) { + $this->failer->log($connection, $job->getQueue(), $job->getRawBody()); + + $job->delete(); + + $job->failed(); + + $this->raiseFailedJobEvent($connection, $job); + } + + return ['job' => $job, 'failed' => true]; + } + + /** + * Raise the failed queue job event. + * + * @param string $connection + * @param \Illuminate\Contracts\Queue\Job $job + * @return void + */ + protected function raiseFailedJobEvent($connection, Job $job) + { + if ($this->events) { + $data = json_decode($job->getRawBody(), true); + + $this->events->fire('illuminate.queue.failed', [$connection, $job, $data]); + } + } + + /** + * Determine if the memory limit has been exceeded. + * + * @param int $memoryLimit + * @return bool + */ + public function memoryExceeded($memoryLimit) + { + return (memory_get_usage() / 1024 / 1024) >= $memoryLimit; + } + + /** + * Stop listening and bail out of the script. + * + * @return void + */ + public function stop() + { + $this->events->fire('illuminate.queue.stopping'); + + die; + } + + /** + * Sleep the script for a given number of seconds. + * + * @param int $seconds + * @return void + */ + public function sleep($seconds) + { + sleep($seconds); + } + + /** + * Get the last queue restart timestamp, or null. + * + * @return int|null + */ + protected function getTimestampOfLastQueueRestart() + { + if ($this->cache) { + return $this->cache->get('illuminate:queue:restart'); + } + } + + /** + * Determine if the queue worker should restart. + * + * @param int|null $lastRestart + * @return bool + */ + protected function queueShouldRestart($lastRestart) + { + return $this->getTimestampOfLastQueueRestart() != $lastRestart; + } + + /** + * Set the exception handler to use in Daemon mode. + * + * @param \Illuminate\Contracts\Debug\ExceptionHandler $handler + * @return void + */ + public function setDaemonExceptionHandler(ExceptionHandler $handler) + { + $this->exceptions = $handler; + } + + /** + * Set the cache repository implementation. + * + * @param \Illuminate\Contracts\Cache\Repository $cache + * @return void + */ + public function setCache(CacheContract $cache) + { + $this->cache = $cache; + } + + /** + * Get the queue manager instance. + * + * @return \Illuminate\Queue\QueueManager + */ + public function getManager() + { + return $this->manager; + } + + /** + * Set the queue manager instance. + * + * @param \Illuminate\Queue\QueueManager $manager + * @return void + */ + public function setManager(QueueManager $manager) + { + $this->manager = $manager; + } +} diff --git a/vendor/illuminate/queue/composer.json b/vendor/illuminate/queue/composer.json new file mode 100755 index 0000000..c198ec4 --- /dev/null +++ b/vendor/illuminate/queue/composer.json @@ -0,0 +1,46 @@ +{ + "name": "illuminate/queue", + "description": "The Illuminate Queue package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/console": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/container": "5.1.*", + "illuminate/http": "5.1.*", + "illuminate/support": "5.1.*", + "symfony/process": "2.7.*", + "nesbot/carbon": "~1.19" + }, + "autoload": { + "psr-4": { + "Illuminate\\Queue\\": "" + }, + "classmap": [ + "IlluminateQueueClosure.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "aws/aws-sdk-php": "Required to use the SQS queue driver (~3.0).", + "illuminate/redis": "Required to use the redis queue driver (5.1.*).", + "iron-io/iron_mq": "Required to use the iron queue driver (~2.0).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/session/CacheBasedSessionHandler.php b/vendor/illuminate/session/CacheBasedSessionHandler.php new file mode 100755 index 0000000..a2990bd --- /dev/null +++ b/vendor/illuminate/session/CacheBasedSessionHandler.php @@ -0,0 +1,94 @@ +cache = $cache; + $this->minutes = $minutes; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + return $this->cache->get($sessionId, ''); + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + return $this->cache->put($sessionId, $data, $this->minutes); + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + return $this->cache->forget($sessionId); + } + + /** + * {@inheritdoc} + */ + public function gc($lifetime) + { + return true; + } + + /** + * Get the underlying cache repository. + * + * @return \Illuminate\Contracts\Cache\Repository + */ + public function getCache() + { + return $this->cache; + } +} diff --git a/vendor/illuminate/session/CommandsServiceProvider.php b/vendor/illuminate/session/CommandsServiceProvider.php new file mode 100755 index 0000000..9514c4f --- /dev/null +++ b/vendor/illuminate/session/CommandsServiceProvider.php @@ -0,0 +1,40 @@ +app->singleton('command.session.database', function ($app) { + return new SessionTableCommand($app['files'], $app['composer']); + }); + + $this->commands('command.session.database'); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return ['command.session.database']; + } +} diff --git a/vendor/illuminate/session/Console/SessionTableCommand.php b/vendor/illuminate/session/Console/SessionTableCommand.php new file mode 100644 index 0000000..2290d3c --- /dev/null +++ b/vendor/illuminate/session/Console/SessionTableCommand.php @@ -0,0 +1,81 @@ +files = $files; + $this->composer = $composer; + } + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + $fullPath = $this->createBaseMigration(); + + $this->files->put($fullPath, $this->files->get(__DIR__.'/stubs/database.stub')); + + $this->info('Migration created successfully!'); + + $this->composer->dumpAutoloads(); + } + + /** + * Create a base migration file for the session. + * + * @return string + */ + protected function createBaseMigration() + { + $name = 'create_sessions_table'; + + $path = $this->laravel->databasePath().'/migrations'; + + return $this->laravel['migration.creator']->create($name, $path); + } +} diff --git a/vendor/illuminate/session/Console/stubs/database.stub b/vendor/illuminate/session/Console/stubs/database.stub new file mode 100755 index 0000000..0529755 --- /dev/null +++ b/vendor/illuminate/session/Console/stubs/database.stub @@ -0,0 +1,31 @@ +string('id')->unique(); + $table->text('payload'); + $table->integer('last_activity'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('sessions'); + } +} diff --git a/vendor/illuminate/session/CookieSessionHandler.php b/vendor/illuminate/session/CookieSessionHandler.php new file mode 100755 index 0000000..e377c94 --- /dev/null +++ b/vendor/illuminate/session/CookieSessionHandler.php @@ -0,0 +1,96 @@ +cookie = $cookie; + $this->minutes = $minutes; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + return $this->request->cookies->get($sessionId) ?: ''; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + $this->cookie->queue($sessionId, $data, $this->minutes); + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + $this->cookie->queue($this->cookie->forget($sessionId)); + } + + /** + * {@inheritdoc} + */ + public function gc($lifetime) + { + return true; + } + + /** + * Set the request instance. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * @return void + */ + public function setRequest(Request $request) + { + $this->request = $request; + } +} diff --git a/vendor/illuminate/session/DatabaseSessionHandler.php b/vendor/illuminate/session/DatabaseSessionHandler.php new file mode 100644 index 0000000..5fdc823 --- /dev/null +++ b/vendor/illuminate/session/DatabaseSessionHandler.php @@ -0,0 +1,130 @@ +table = $table; + $this->connection = $connection; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + $session = (object) $this->getQuery()->find($sessionId); + + if (isset($session->payload)) { + $this->exists = true; + + return base64_decode($session->payload); + } + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + if ($this->exists) { + $this->getQuery()->where('id', $sessionId)->update([ + 'payload' => base64_encode($data), 'last_activity' => time(), + ]); + } else { + $this->getQuery()->insert([ + 'id' => $sessionId, 'payload' => base64_encode($data), 'last_activity' => time(), + ]); + } + + $this->exists = true; + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + $this->getQuery()->where('id', $sessionId)->delete(); + } + + /** + * {@inheritdoc} + */ + public function gc($lifetime) + { + $this->getQuery()->where('last_activity', '<=', time() - $lifetime)->delete(); + } + + /** + * Get a fresh query builder instance for the table. + * + * @return \Illuminate\Database\Query\Builder + */ + protected function getQuery() + { + return $this->connection->table($this->table); + } + + /** + * Set the existence state for the session. + * + * @param bool $value + * @return $this + */ + public function setExists($value) + { + $this->exists = $value; + + return $this; + } +} diff --git a/vendor/illuminate/session/EncryptedStore.php b/vendor/illuminate/session/EncryptedStore.php new file mode 100644 index 0000000..9811d97 --- /dev/null +++ b/vendor/illuminate/session/EncryptedStore.php @@ -0,0 +1,69 @@ +encrypter = $encrypter; + + parent::__construct($name, $handler, $id); + } + + /** + * Prepare the raw string data from the session for unserialization. + * + * @param string $data + * @return string + */ + protected function prepareForUnserialize($data) + { + try { + return $this->encrypter->decrypt($data); + } catch (DecryptException $e) { + return json_encode([]); + } + } + + /** + * Prepare the serialized session data for storage. + * + * @param string $data + * @return string + */ + protected function prepareForStorage($data) + { + return $this->encrypter->encrypt($data); + } + + /** + * Get the encrypter instance. + * + * @return \Illuminate\Contracts\Encryption\Encrypter + */ + public function getEncrypter() + { + return $this->encrypter; + } +} diff --git a/vendor/illuminate/session/ExistenceAwareInterface.php b/vendor/illuminate/session/ExistenceAwareInterface.php new file mode 100644 index 0000000..4a6bd98 --- /dev/null +++ b/vendor/illuminate/session/ExistenceAwareInterface.php @@ -0,0 +1,14 @@ +path = $path; + $this->files = $files; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + if ($this->files->exists($path = $this->path.'/'.$sessionId)) { + return $this->files->get($path); + } + + return ''; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + $this->files->put($this->path.'/'.$sessionId, $data, true); + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + $this->files->delete($this->path.'/'.$sessionId); + } + + /** + * {@inheritdoc} + */ + public function gc($lifetime) + { + $files = Finder::create() + ->in($this->path) + ->files() + ->ignoreDotFiles(true) + ->date('<= now - '.$lifetime.' seconds'); + + foreach ($files as $file) { + $this->files->delete($file->getRealPath()); + } + } +} diff --git a/vendor/illuminate/session/Middleware/StartSession.php b/vendor/illuminate/session/Middleware/StartSession.php new file mode 100644 index 0000000..cf216e9 --- /dev/null +++ b/vendor/illuminate/session/Middleware/StartSession.php @@ -0,0 +1,244 @@ +manager = $manager; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + $this->sessionHandled = true; + + // If a session driver has been configured, we will need to start the session here + // so that the data is ready for an application. Note that the Laravel sessions + // do not make use of PHP "native" sessions in any way since they are crappy. + if ($this->sessionConfigured()) { + $session = $this->startSession($request); + + $request->setSession($session); + } + + $response = $next($request); + + // Again, if the session has been configured we will need to close out the session + // so that the attributes may be persisted to some storage medium. We will also + // add the session identifier cookie to the application response headers now. + if ($this->sessionConfigured()) { + $this->storeCurrentUrl($request, $session); + + $this->collectGarbage($session); + + $this->addCookieToResponse($response, $session); + } + + return $response; + } + + /** + * Perform any final actions for the request lifecycle. + * + * @param \Illuminate\Http\Request $request + * @param \Symfony\Component\HttpFoundation\Response $response + * @return void + */ + public function terminate($request, $response) + { + if ($this->sessionHandled && $this->sessionConfigured() && ! $this->usingCookieSessions()) { + $this->manager->driver()->save(); + } + } + + /** + * Start the session for the given request. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Session\SessionInterface + */ + protected function startSession(Request $request) + { + with($session = $this->getSession($request))->setRequestOnHandler($request); + + $session->start(); + + return $session; + } + + /** + * Get the session implementation from the manager. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Session\SessionInterface + */ + public function getSession(Request $request) + { + $session = $this->manager->driver(); + + $session->setId($request->cookies->get($session->getName())); + + return $session; + } + + /** + * Store the current URL for the request if necessary. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Session\SessionInterface $session + * @return void + */ + protected function storeCurrentUrl(Request $request, $session) + { + if ($request->method() === 'GET' && $request->route() && ! $request->ajax()) { + $session->setPreviousUrl($request->fullUrl()); + } + } + + /** + * Remove the garbage from the session if necessary. + * + * @param \Illuminate\Session\SessionInterface $session + * @return void + */ + protected function collectGarbage(SessionInterface $session) + { + $config = $this->manager->getSessionConfig(); + + // Here we will see if this request hits the garbage collection lottery by hitting + // the odds needed to perform garbage collection on any given request. If we do + // hit it, we'll call this handler to let it delete all the expired sessions. + if ($this->configHitsLottery($config)) { + $session->getHandler()->gc($this->getSessionLifetimeInSeconds()); + } + } + + /** + * Determine if the configuration odds hit the lottery. + * + * @param array $config + * @return bool + */ + protected function configHitsLottery(array $config) + { + return mt_rand(1, $config['lottery'][1]) <= $config['lottery'][0]; + } + + /** + * Add the session cookie to the application response. + * + * @param \Symfony\Component\HttpFoundation\Response $response + * @param \Illuminate\Session\SessionInterface $session + * @return void + */ + protected function addCookieToResponse(Response $response, SessionInterface $session) + { + if ($this->usingCookieSessions()) { + $this->manager->driver()->save(); + } + + if ($this->sessionIsPersistent($config = $this->manager->getSessionConfig())) { + $response->headers->setCookie(new Cookie( + $session->getName(), $session->getId(), $this->getCookieExpirationDate(), + $config['path'], $config['domain'], Arr::get($config, 'secure', false) + )); + } + } + + /** + * Get the session lifetime in seconds. + * + * @return int + */ + protected function getSessionLifetimeInSeconds() + { + return Arr::get($this->manager->getSessionConfig(), 'lifetime') * 60; + } + + /** + * Get the cookie lifetime in seconds. + * + * @return int + */ + protected function getCookieExpirationDate() + { + $config = $this->manager->getSessionConfig(); + + return $config['expire_on_close'] ? 0 : Carbon::now()->addMinutes($config['lifetime']); + } + + /** + * Determine if a session driver has been configured. + * + * @return bool + */ + protected function sessionConfigured() + { + return ! is_null(Arr::get($this->manager->getSessionConfig(), 'driver')); + } + + /** + * Determine if the configured session driver is persistent. + * + * @param array|null $config + * @return bool + */ + protected function sessionIsPersistent(array $config = null) + { + $config = $config ?: $this->manager->getSessionConfig(); + + return ! in_array($config['driver'], [null, 'array']); + } + + /** + * Determine if the session is using cookie sessions. + * + * @return bool + */ + protected function usingCookieSessions() + { + if (! $this->sessionConfigured()) { + return false; + } + + return $this->manager->driver()->getHandler() instanceof CookieSessionHandler; + } +} diff --git a/vendor/illuminate/session/SessionInterface.php b/vendor/illuminate/session/SessionInterface.php new file mode 100644 index 0000000..1d7f18d --- /dev/null +++ b/vendor/illuminate/session/SessionInterface.php @@ -0,0 +1,31 @@ +buildSession(parent::callCustomCreator($driver)); + } + + /** + * Create an instance of the "array" session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createArrayDriver() + { + return $this->buildSession(new NullSessionHandler); + } + + /** + * Create an instance of the "cookie" session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createCookieDriver() + { + $lifetime = $this->app['config']['session.lifetime']; + + return $this->buildSession(new CookieSessionHandler($this->app['cookie'], $lifetime)); + } + + /** + * Create an instance of the file session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createFileDriver() + { + return $this->createNativeDriver(); + } + + /** + * Create an instance of the file session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createNativeDriver() + { + $path = $this->app['config']['session.files']; + + return $this->buildSession(new FileSessionHandler($this->app['files'], $path)); + } + + /** + * Create an instance of the database session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createDatabaseDriver() + { + $connection = $this->getDatabaseConnection(); + + $table = $this->app['config']['session.table']; + + return $this->buildSession(new DatabaseSessionHandler($connection, $table)); + } + + /** + * Get the database connection for the database driver. + * + * @return \Illuminate\Database\Connection + */ + protected function getDatabaseConnection() + { + $connection = $this->app['config']['session.connection']; + + return $this->app['db']->connection($connection); + } + + /** + * Create an instance of the APC session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createApcDriver() + { + return $this->createCacheBased('apc'); + } + + /** + * Create an instance of the Memcached session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createMemcachedDriver() + { + return $this->createCacheBased('memcached'); + } + + /** + * Create an instance of the Wincache session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createWincacheDriver() + { + return $this->createCacheBased('wincache'); + } + + /** + * Create an instance of the Redis session driver. + * + * @return \Illuminate\Session\Store + */ + protected function createRedisDriver() + { + $handler = $this->createCacheHandler('redis'); + + $handler->getCache()->getStore()->setConnection($this->app['config']['session.connection']); + + return $this->buildSession($handler); + } + + /** + * Create an instance of a cache driven driver. + * + * @param string $driver + * @return \Illuminate\Session\Store + */ + protected function createCacheBased($driver) + { + return $this->buildSession($this->createCacheHandler($driver)); + } + + /** + * Create the cache based session handler instance. + * + * @param string $driver + * @return \Illuminate\Session\CacheBasedSessionHandler + */ + protected function createCacheHandler($driver) + { + $minutes = $this->app['config']['session.lifetime']; + + return new CacheBasedSessionHandler(clone $this->app['cache']->driver($driver), $minutes); + } + + /** + * Build the session instance. + * + * @param \SessionHandlerInterface $handler + * @return \Illuminate\Session\Store + */ + protected function buildSession($handler) + { + if ($this->app['config']['session.encrypt']) { + return new EncryptedStore( + $this->app['config']['session.cookie'], $handler, $this->app['encrypter'] + ); + } else { + return new Store($this->app['config']['session.cookie'], $handler); + } + } + + /** + * Get the session configuration. + * + * @return array + */ + public function getSessionConfig() + { + return $this->app['config']['session']; + } + + /** + * Get the default session driver name. + * + * @return string + */ + public function getDefaultDriver() + { + return $this->app['config']['session.driver']; + } + + /** + * Set the default session driver name. + * + * @param string $name + * @return void + */ + public function setDefaultDriver($name) + { + $this->app['config']['session.driver'] = $name; + } +} diff --git a/vendor/illuminate/session/SessionServiceProvider.php b/vendor/illuminate/session/SessionServiceProvider.php new file mode 100755 index 0000000..bc49ebc --- /dev/null +++ b/vendor/illuminate/session/SessionServiceProvider.php @@ -0,0 +1,51 @@ +registerSessionManager(); + + $this->registerSessionDriver(); + + $this->app->singleton('Illuminate\Session\Middleware\StartSession'); + } + + /** + * Register the session manager instance. + * + * @return void + */ + protected function registerSessionManager() + { + $this->app->singleton('session', function ($app) { + return new SessionManager($app); + }); + } + + /** + * Register the session driver instance. + * + * @return void + */ + protected function registerSessionDriver() + { + $this->app->singleton('session.store', function ($app) { + // First, we will create the session manager which is responsible for the + // creation of the various session drivers when they are needed by the + // application instance, and will resolve them on a lazy load basis. + $manager = $app['session']; + + return $manager->driver(); + }); + } +} diff --git a/vendor/illuminate/session/Store.php b/vendor/illuminate/session/Store.php new file mode 100755 index 0000000..3f0cf11 --- /dev/null +++ b/vendor/illuminate/session/Store.php @@ -0,0 +1,682 @@ +setId($id); + $this->name = $name; + $this->handler = $handler; + $this->metaBag = new MetadataBag; + } + + /** + * {@inheritdoc} + */ + public function start() + { + $this->loadSession(); + + if (! $this->has('_token')) { + $this->regenerateToken(); + } + + return $this->started = true; + } + + /** + * Load the session data from the handler. + * + * @return void + */ + protected function loadSession() + { + $this->attributes = array_merge($this->attributes, $this->readFromHandler()); + + foreach (array_merge($this->bags, [$this->metaBag]) as $bag) { + $this->initializeLocalBag($bag); + + $bag->initialize($this->bagData[$bag->getStorageKey()]); + } + } + + /** + * Read the session data from the handler. + * + * @return array + */ + protected function readFromHandler() + { + $data = $this->handler->read($this->getId()); + + if ($data) { + $data = @unserialize($this->prepareForUnserialize($data)); + + if ($data !== false && $data !== null && is_array($data)) { + return $data; + } + } + + return []; + } + + /** + * Prepare the raw string data from the session for unserialization. + * + * @param string $data + * @return string + */ + protected function prepareForUnserialize($data) + { + return $data; + } + + /** + * Initialize a bag in storage if it doesn't exist. + * + * @param \Symfony\Component\HttpFoundation\Session\SessionBagInterface $bag + * @return void + */ + protected function initializeLocalBag($bag) + { + $this->bagData[$bag->getStorageKey()] = $this->pull($bag->getStorageKey(), []); + } + + /** + * {@inheritdoc} + */ + public function getId() + { + return $this->id; + } + + /** + * {@inheritdoc} + */ + public function setId($id) + { + if (! $this->isValidId($id)) { + $id = $this->generateSessionId(); + } + + $this->id = $id; + } + + /** + * Determine if this is a valid session ID. + * + * @param string $id + * @return bool + */ + public function isValidId($id) + { + return is_string($id) && preg_match('/^[a-f0-9]{40}$/', $id); + } + + /** + * Get a new, random session ID. + * + * @return string + */ + protected function generateSessionId() + { + return sha1(uniqid('', true).Str::random(25).microtime(true)); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * {@inheritdoc} + */ + public function invalidate($lifetime = null) + { + $this->clear(); + + return $this->migrate(true, $lifetime); + } + + /** + * {@inheritdoc} + */ + public function migrate($destroy = false, $lifetime = null) + { + if ($destroy) { + $this->handler->destroy($this->getId()); + } + + $this->setExists(false); + + $this->id = $this->generateSessionId(); + + return true; + } + + /** + * Generate a new session identifier. + * + * @param bool $destroy + * @return bool + */ + public function regenerate($destroy = false) + { + return $this->migrate($destroy); + } + + /** + * {@inheritdoc} + */ + public function save() + { + $this->addBagDataToSession(); + + $this->ageFlashData(); + + $this->handler->write($this->getId(), $this->prepareForStorage(serialize($this->attributes))); + + $this->started = false; + } + + /** + * Prepare the serialized session data for storage. + * + * @param string $data + * @return string + */ + protected function prepareForStorage($data) + { + return $data; + } + + /** + * Merge all of the bag data into the session. + * + * @return void + */ + protected function addBagDataToSession() + { + foreach (array_merge($this->bags, [$this->metaBag]) as $bag) { + $this->put($bag->getStorageKey(), $this->bagData[$bag->getStorageKey()]); + } + } + + /** + * Age the flash data for the session. + * + * @return void + */ + public function ageFlashData() + { + foreach ($this->get('flash.old', []) as $old) { + $this->forget($old); + } + + $this->put('flash.old', $this->get('flash.new', [])); + + $this->put('flash.new', []); + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + return ! is_null($this->get($name)); + } + + /** + * {@inheritdoc} + */ + public function get($name, $default = null) + { + return Arr::get($this->attributes, $name, $default); + } + + /** + * Get the value of a given key and then forget it. + * + * @param string $key + * @param string $default + * @return mixed + */ + public function pull($key, $default = null) + { + return Arr::pull($this->attributes, $key, $default); + } + + /** + * Determine if the session contains old input. + * + * @param string $key + * @return bool + */ + public function hasOldInput($key = null) + { + $old = $this->getOldInput($key); + + return is_null($key) ? count($old) > 0 : ! is_null($old); + } + + /** + * Get the requested item from the flashed input array. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function getOldInput($key = null, $default = null) + { + $input = $this->get('_old_input', []); + + // Input that is flashed to the session can be easily retrieved by the + // developer, making repopulating old forms and the like much more + // convenient, since the request's previous input is available. + return Arr::get($input, $key, $default); + } + + /** + * {@inheritdoc} + */ + public function set($name, $value) + { + Arr::set($this->attributes, $name, $value); + } + + /** + * Put a key / value pair or array of key / value pairs in the session. + * + * @param string|array $key + * @param mixed $value + * @return void + */ + public function put($key, $value = null) + { + if (! is_array($key)) { + $key = [$key => $value]; + } + + foreach ($key as $arrayKey => $arrayValue) { + $this->set($arrayKey, $arrayValue); + } + } + + /** + * Push a value onto a session array. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function push($key, $value) + { + $array = $this->get($key, []); + + $array[] = $value; + + $this->put($key, $array); + } + + /** + * Flash a key / value pair to the session. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function flash($key, $value) + { + $this->put($key, $value); + + $this->push('flash.new', $key); + + $this->removeFromOldFlashData([$key]); + } + + /** + * Flash an input array to the session. + * + * @param array $value + * @return void + */ + public function flashInput(array $value) + { + $this->flash('_old_input', $value); + } + + /** + * Reflash all of the session flash data. + * + * @return void + */ + public function reflash() + { + $this->mergeNewFlashes($this->get('flash.old', [])); + + $this->put('flash.old', []); + } + + /** + * Reflash a subset of the current flash data. + * + * @param array|mixed $keys + * @return void + */ + public function keep($keys = null) + { + $keys = is_array($keys) ? $keys : func_get_args(); + + $this->mergeNewFlashes($keys); + + $this->removeFromOldFlashData($keys); + } + + /** + * Merge new flash keys into the new flash array. + * + * @param array $keys + * @return void + */ + protected function mergeNewFlashes(array $keys) + { + $values = array_unique(array_merge($this->get('flash.new', []), $keys)); + + $this->put('flash.new', $values); + } + + /** + * Remove the given keys from the old flash data. + * + * @param array $keys + * @return void + */ + protected function removeFromOldFlashData(array $keys) + { + $this->put('flash.old', array_diff($this->get('flash.old', []), $keys)); + } + + /** + * {@inheritdoc} + */ + public function all() + { + return $this->attributes; + } + + /** + * {@inheritdoc} + */ + public function replace(array $attributes) + { + $this->put($attributes); + } + + /** + * {@inheritdoc} + */ + public function remove($name) + { + return Arr::pull($this->attributes, $name); + } + + /** + * Remove an item from the session. + * + * @param string $key + * @return void + */ + public function forget($key) + { + Arr::forget($this->attributes, $key); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $this->attributes = []; + + foreach ($this->bags as $bag) { + $bag->clear(); + } + } + + /** + * Remove all of the items from the session. + * + * @return void + */ + public function flush() + { + $this->clear(); + } + + /** + * {@inheritdoc} + */ + public function isStarted() + { + return $this->started; + } + + /** + * {@inheritdoc} + */ + public function registerBag(SessionBagInterface $bag) + { + $this->bags[$bag->getStorageKey()] = $bag; + } + + /** + * {@inheritdoc} + */ + public function getBag($name) + { + return Arr::get($this->bags, $name, function () { + throw new InvalidArgumentException('Bag not registered.'); + }); + } + + /** + * {@inheritdoc} + */ + public function getMetadataBag() + { + return $this->metaBag; + } + + /** + * Get the raw bag data array for a given bag. + * + * @param string $name + * @return array + */ + public function getBagData($name) + { + return Arr::get($this->bagData, $name, []); + } + + /** + * Get the CSRF token value. + * + * @return string + */ + public function token() + { + return $this->get('_token'); + } + + /** + * Get the CSRF token value. + * + * @return string + */ + public function getToken() + { + return $this->token(); + } + + /** + * Regenerate the CSRF token value. + * + * @return void + */ + public function regenerateToken() + { + $this->put('_token', Str::random(40)); + } + + /** + * Get the previous URL from the session. + * + * @return string|null + */ + public function previousUrl() + { + return $this->get('_previous.url'); + } + + /** + * Set the "previous" URL in the session. + * + * @param string $url + * @return void + */ + public function setPreviousUrl($url) + { + return $this->put('_previous.url', $url); + } + + /** + * Set the existence of the session on the handler if applicable. + * + * @param bool $value + * @return void + */ + public function setExists($value) + { + if ($this->handler instanceof ExistenceAwareInterface) { + $this->handler->setExists($value); + } + } + + /** + * Get the underlying session handler implementation. + * + * @return \SessionHandlerInterface + */ + public function getHandler() + { + return $this->handler; + } + + /** + * Determine if the session handler needs a request. + * + * @return bool + */ + public function handlerNeedsRequest() + { + return $this->handler instanceof CookieSessionHandler; + } + + /** + * Set the request on the handler instance. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * @return void + */ + public function setRequestOnHandler(Request $request) + { + if ($this->handlerNeedsRequest()) { + $this->handler->setRequest($request); + } + } +} diff --git a/vendor/illuminate/session/TokenMismatchException.php b/vendor/illuminate/session/TokenMismatchException.php new file mode 100755 index 0000000..98d99a1 --- /dev/null +++ b/vendor/illuminate/session/TokenMismatchException.php @@ -0,0 +1,10 @@ +=5.5.9", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "nesbot/carbon": "~1.19", + "symfony/finder": "2.7.*", + "symfony/http-foundation": "2.7.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Session\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "illuminate/console": "Required to use the session:table command (5.1.*)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/support/AggregateServiceProvider.php b/vendor/illuminate/support/AggregateServiceProvider.php new file mode 100644 index 0000000..ca5f9a8 --- /dev/null +++ b/vendor/illuminate/support/AggregateServiceProvider.php @@ -0,0 +1,52 @@ +instances = []; + + foreach ($this->providers as $provider) { + $this->instances[] = $this->app->register($provider); + } + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + $provides = []; + + foreach ($this->providers as $provider) { + $instance = $this->app->resolveProviderClass($provider); + + $provides = array_merge($provides, $instance->provides()); + } + + return $provides; + } +} diff --git a/vendor/illuminate/support/Arr.php b/vendor/illuminate/support/Arr.php new file mode 100755 index 0000000..1817897 --- /dev/null +++ b/vendor/illuminate/support/Arr.php @@ -0,0 +1,459 @@ + $value) { + list($innerKey, $innerValue) = call_user_func($callback, $key, $value); + + $results[$innerKey] = $innerValue; + } + + return $results; + } + + /** + * Collapse an array of arrays into a single array. + * + * @param array|\ArrayAccess $array + * @return array + */ + public static function collapse($array) + { + $results = []; + + foreach ($array as $values) { + if ($values instanceof Collection) { + $values = $values->all(); + } + + $results = array_merge($results, $values); + } + + return $results; + } + + /** + * Divide an array into two arrays. One with keys and the other with values. + * + * @param array $array + * @return array + */ + public static function divide($array) + { + return [array_keys($array), array_values($array)]; + } + + /** + * Flatten a multi-dimensional associative array with dots. + * + * @param array $array + * @param string $prepend + * @return array + */ + public static function dot($array, $prepend = '') + { + $results = []; + + foreach ($array as $key => $value) { + if (is_array($value)) { + $results = array_merge($results, static::dot($value, $prepend.$key.'.')); + } else { + $results[$prepend.$key] = $value; + } + } + + return $results; + } + + /** + * Get all of the given array except for a specified array of items. + * + * @param array $array + * @param array|string $keys + * @return array + */ + public static function except($array, $keys) + { + static::forget($array, $keys); + + return $array; + } + + /** + * Fetch a flattened array of a nested array element. + * + * @param array $array + * @param string $key + * @return array + * + * @deprecated since version 5.1. Use pluck instead. + */ + public static function fetch($array, $key) + { + foreach (explode('.', $key) as $segment) { + $results = []; + + foreach ($array as $value) { + if (array_key_exists($segment, $value = (array) $value)) { + $results[] = $value[$segment]; + } + } + + $array = array_values($results); + } + + return array_values($results); + } + + /** + * Return the first element in an array passing a given truth test. + * + * @param array $array + * @param callable $callback + * @param mixed $default + * @return mixed + */ + public static function first($array, callable $callback, $default = null) + { + foreach ($array as $key => $value) { + if (call_user_func($callback, $key, $value)) { + return $value; + } + } + + return value($default); + } + + /** + * Return the last element in an array passing a given truth test. + * + * @param array $array + * @param callable $callback + * @param mixed $default + * @return mixed + */ + public static function last($array, callable $callback, $default = null) + { + return static::first(array_reverse($array), $callback, $default); + } + + /** + * Flatten a multi-dimensional array into a single level. + * + * @param array $array + * @return array + */ + public static function flatten($array) + { + $return = []; + + array_walk_recursive($array, function ($x) use (&$return) { $return[] = $x; }); + + return $return; + } + + /** + * Remove one or many array items from a given array using "dot" notation. + * + * @param array $array + * @param array|string $keys + * @return void + */ + public static function forget(&$array, $keys) + { + $original = &$array; + + foreach ((array) $keys as $key) { + $parts = explode('.', $key); + + while (count($parts) > 1) { + $part = array_shift($parts); + + if (isset($array[$part]) && is_array($array[$part])) { + $array = &$array[$part]; + } else { + $parts = []; + } + } + + unset($array[array_shift($parts)]); + + // clean up after each pass + $array = &$original; + } + } + + /** + * Get an item from an array using "dot" notation. + * + * @param array $array + * @param string $key + * @param mixed $default + * @return mixed + */ + public static function get($array, $key, $default = null) + { + if (is_null($key)) { + return $array; + } + + if (isset($array[$key])) { + return $array[$key]; + } + + foreach (explode('.', $key) as $segment) { + if (! is_array($array) || ! array_key_exists($segment, $array)) { + return value($default); + } + + $array = $array[$segment]; + } + + return $array; + } + + /** + * Check if an item exists in an array using "dot" notation. + * + * @param array $array + * @param string $key + * @return bool + */ + public static function has($array, $key) + { + if (empty($array) || is_null($key)) { + return false; + } + + if (array_key_exists($key, $array)) { + return true; + } + + foreach (explode('.', $key) as $segment) { + if (! is_array($array) || ! array_key_exists($segment, $array)) { + return false; + } + + $array = $array[$segment]; + } + + return true; + } + + /** + * Determines if an array is associative. + * + * An array is "associative" if it doesn't have sequential numerical keys beginning with zero. + * + * @param array $array + * @return bool + */ + public static function isAssoc(array $array) + { + $keys = array_keys($array); + + return array_keys($keys) !== $keys; + } + + /** + * Get a subset of the items from the given array. + * + * @param array $array + * @param array|string $keys + * @return array + */ + public static function only($array, $keys) + { + return array_intersect_key($array, array_flip((array) $keys)); + } + + /** + * Pluck an array of values from an array. + * + * @param array $array + * @param string|array $value + * @param string|array|null $key + * @return array + */ + public static function pluck($array, $value, $key = null) + { + $results = []; + + list($value, $key) = static::explodePluckParameters($value, $key); + + foreach ($array as $item) { + $itemValue = data_get($item, $value); + + // If the key is "null", we will just append the value to the array and keep + // looping. Otherwise we will key the array using the value of the key we + // received from the developer. Then we'll return the final array form. + if (is_null($key)) { + $results[] = $itemValue; + } else { + $itemKey = data_get($item, $key); + + $results[$itemKey] = $itemValue; + } + } + + return $results; + } + + /** + * Explode the "value" and "key" arguments passed to "pluck". + * + * @param string|array $value + * @param string|array|null $key + * @return array + */ + protected static function explodePluckParameters($value, $key) + { + $value = is_string($value) ? explode('.', $value) : $value; + + $key = is_null($key) || is_array($key) ? $key : explode('.', $key); + + return [$value, $key]; + } + + /** + * Get a value from the array, and remove it. + * + * @param array $array + * @param string $key + * @param mixed $default + * @return mixed + */ + public static function pull(&$array, $key, $default = null) + { + $value = static::get($array, $key, $default); + + static::forget($array, $key); + + return $value; + } + + /** + * Set an array item to a given value using "dot" notation. + * + * If no key is given to the method, the entire array will be replaced. + * + * @param array $array + * @param string $key + * @param mixed $value + * @return array + */ + public static function set(&$array, $key, $value) + { + if (is_null($key)) { + return $array = $value; + } + + $keys = explode('.', $key); + + while (count($keys) > 1) { + $key = array_shift($keys); + + // If the key doesn't exist at this depth, we will just create an empty array + // to hold the next value, allowing us to create the arrays to hold final + // values at the correct depth. Then we'll keep digging into the array. + if (! isset($array[$key]) || ! is_array($array[$key])) { + $array[$key] = []; + } + + $array = &$array[$key]; + } + + $array[array_shift($keys)] = $value; + + return $array; + } + + /** + * Sort the array using the given callback. + * + * @param array $array + * @param callable $callback + * @return array + */ + public static function sort($array, callable $callback) + { + return Collection::make($array)->sortBy($callback)->all(); + } + + /** + * Recursively sort an array by keys and values. + * + * @param array $array + * @return array + */ + public static function sortRecursive($array) + { + foreach ($array as &$value) { + if (is_array($value)) { + $value = static::sortRecursive($value); + } + } + + if (static::isAssoc($array)) { + ksort($array); + } else { + sort($array); + } + + return $array; + } + + /** + * Filter the array using the given callback. + * + * @param array $array + * @param callable $callback + * @return array + */ + public static function where($array, callable $callback) + { + $filtered = []; + + foreach ($array as $key => $value) { + if (call_user_func($callback, $key, $value)) { + $filtered[$key] = $value; + } + } + + return $filtered; + } +} diff --git a/vendor/illuminate/support/ClassLoader.php b/vendor/illuminate/support/ClassLoader.php new file mode 100644 index 0000000..97ac5d6 --- /dev/null +++ b/vendor/illuminate/support/ClassLoader.php @@ -0,0 +1,104 @@ +items = is_array($items) ? $items : $this->getArrayableItems($items); + } + + /** + * Create a new collection instance if the value isn't one already. + * + * @param mixed $items + * @return static + */ + public static function make($items = []) + { + return new static($items); + } + + /** + * Get all of the items in the collection. + * + * @return array + */ + public function all() + { + return $this->items; + } + + /** + * Get the average value of a given key. + * + * @param string|null $key + * @return mixed + */ + public function avg($key = null) + { + if ($count = $this->count()) { + return $this->sum($key) / $count; + } + } + + /** + * Alias for the "avg" method. + * + * @param string|null $key + * @return mixed + */ + public function average($key = null) + { + return $this->avg($key); + } + + /** + * Collapse the collection of items into a single array. + * + * @return static + */ + public function collapse() + { + return new static(Arr::collapse($this->items)); + } + + /** + * Determine if an item exists in the collection. + * + * @param mixed $key + * @param mixed $value + * @return bool + */ + public function contains($key, $value = null) + { + if (func_num_args() == 2) { + return $this->contains(function ($k, $item) use ($key, $value) { + return data_get($item, $key) == $value; + }); + } + + if ($this->useAsCallable($key)) { + return ! is_null($this->first($key)); + } + + return in_array($key, $this->items); + } + + /** + * Get the items in the collection that are not present in the given items. + * + * @param mixed $items + * @return static + */ + public function diff($items) + { + return new static(array_diff($this->items, $this->getArrayableItems($items))); + } + + /** + * Execute a callback over each item. + * + * @param callable $callback + * @return $this + */ + public function each(callable $callback) + { + foreach ($this->items as $key => $item) { + if ($callback($item, $key) === false) { + break; + } + } + + return $this; + } + + /** + * Create a new collection consisting of every n-th element. + * + * @param int $step + * @param int $offset + * @return static + */ + public function every($step, $offset = 0) + { + $new = []; + + $position = 0; + + foreach ($this->items as $key => $item) { + if ($position % $step === $offset) { + $new[] = $item; + } + + $position++; + } + + return new static($new); + } + + /** + * Fetch a nested element of the collection. + * + * @param string $key + * @return static + * + * @deprecated since version 5.1. Use pluck instead. + */ + public function fetch($key) + { + return new static(Arr::fetch($this->items, $key)); + } + + /** + * Run a filter over each of the items. + * + * @param callable|null $callback + * @return static + */ + public function filter(callable $callback = null) + { + if ($callback) { + return new static(array_filter($this->items, $callback)); + } + + return new static(array_filter($this->items)); + } + + /** + * Filter items by the given key value pair. + * + * @param string $key + * @param mixed $value + * @param bool $strict + * @return static + */ + public function where($key, $value, $strict = true) + { + return $this->filter(function ($item) use ($key, $value, $strict) { + return $strict ? data_get($item, $key) === $value + : data_get($item, $key) == $value; + }); + } + + /** + * Filter items by the given key value pair using loose comparison. + * + * @param string $key + * @param mixed $value + * @return static + */ + public function whereLoose($key, $value) + { + return $this->where($key, $value, false); + } + + /** + * Get the first item from the collection. + * + * @param callable|null $callback + * @param mixed $default + * @return mixed + */ + public function first(callable $callback = null, $default = null) + { + if (is_null($callback)) { + return count($this->items) > 0 ? reset($this->items) : null; + } + + return Arr::first($this->items, $callback, $default); + } + + /** + * Get a flattened array of the items in the collection. + * + * @return static + */ + public function flatten() + { + return new static(Arr::flatten($this->items)); + } + + /** + * Flip the items in the collection. + * + * @return static + */ + public function flip() + { + return new static(array_flip($this->items)); + } + + /** + * Remove an item from the collection by key. + * + * @param string|array $keys + * @return $this + */ + public function forget($keys) + { + foreach ((array) $keys as $key) { + $this->offsetUnset($key); + } + + return $this; + } + + /** + * Get an item from the collection by key. + * + * @param mixed $key + * @param mixed $default + * @return mixed + */ + public function get($key, $default = null) + { + if ($this->offsetExists($key)) { + return $this->items[$key]; + } + + return value($default); + } + + /** + * Group an associative array by a field or using a callback. + * + * @param callable|string $groupBy + * @param bool $preserveKeys + * @return static + */ + public function groupBy($groupBy, $preserveKeys = false) + { + $groupBy = $this->valueRetriever($groupBy); + + $results = []; + + foreach ($this->items as $key => $value) { + $groupKey = $groupBy($value, $key); + + if (! array_key_exists($groupKey, $results)) { + $results[$groupKey] = new static; + } + + $results[$groupKey]->offsetSet($preserveKeys ? $key : null, $value); + } + + return new static($results); + } + + /** + * Key an associative array by a field or using a callback. + * + * @param callable|string $keyBy + * @return static + */ + public function keyBy($keyBy) + { + $keyBy = $this->valueRetriever($keyBy); + + $results = []; + + foreach ($this->items as $item) { + $results[$keyBy($item)] = $item; + } + + return new static($results); + } + + /** + * Determine if an item exists in the collection by key. + * + * @param mixed $key + * @return bool + */ + public function has($key) + { + return $this->offsetExists($key); + } + + /** + * Concatenate values of a given key as a string. + * + * @param string $value + * @param string $glue + * @return string + */ + public function implode($value, $glue = null) + { + $first = $this->first(); + + if (is_array($first) || is_object($first)) { + return implode($glue, $this->pluck($value)->all()); + } + + return implode($value, $this->items); + } + + /** + * Intersect the collection with the given items. + * + * @param mixed $items + * @return static + */ + public function intersect($items) + { + return new static(array_intersect($this->items, $this->getArrayableItems($items))); + } + + /** + * Determine if the collection is empty or not. + * + * @return bool + */ + public function isEmpty() + { + return empty($this->items); + } + + /** + * Determine if the given value is callable, but not a string. + * + * @param mixed $value + * @return bool + */ + protected function useAsCallable($value) + { + return ! is_string($value) && is_callable($value); + } + + /** + * Get the keys of the collection items. + * + * @return static + */ + public function keys() + { + return new static(array_keys($this->items)); + } + + /** + * Get the last item from the collection. + * + * @param callable|null $callback + * @param mixed $default + * @return mixed + */ + public function last(callable $callback = null, $default = null) + { + if (is_null($callback)) { + return count($this->items) > 0 ? end($this->items) : value($default); + } + + return Arr::last($this->items, $callback, $default); + } + + /** + * Get an array with the values of a given key. + * + * @param string $value + * @param string $key + * @return static + */ + public function pluck($value, $key = null) + { + return new static(Arr::pluck($this->items, $value, $key)); + } + + /** + * Alias for the "pluck" method. + * + * @param string $value + * @param string $key + * @return static + */ + public function lists($value, $key = null) + { + return $this->pluck($value, $key); + } + + /** + * Run a map over each of the items. + * + * @param callable $callback + * @return static + */ + public function map(callable $callback) + { + $keys = array_keys($this->items); + + $items = array_map($callback, $this->items, $keys); + + return new static(array_combine($keys, $items)); + } + + /** + * Get the max value of a given key. + * + * @param string|null $key + * @return mixed + */ + public function max($key = null) + { + return $this->reduce(function ($result, $item) use ($key) { + $value = data_get($item, $key); + + return is_null($result) || $value > $result ? $value : $result; + }); + } + + /** + * Merge the collection with the given items. + * + * @param mixed $items + * @return static + */ + public function merge($items) + { + return new static(array_merge($this->items, $this->getArrayableItems($items))); + } + + /** + * Get the min value of a given key. + * + * @param string|null $key + * @return mixed + */ + public function min($key = null) + { + return $this->reduce(function ($result, $item) use ($key) { + $value = data_get($item, $key); + + return is_null($result) || $value < $result ? $value : $result; + }); + } + + /** + * "Paginate" the collection by slicing it into a smaller collection. + * + * @param int $page + * @param int $perPage + * @return static + */ + public function forPage($page, $perPage) + { + return $this->slice(($page - 1) * $perPage, $perPage); + } + + /** + * Get and remove the last item from the collection. + * + * @return mixed + */ + public function pop() + { + return array_pop($this->items); + } + + /** + * Push an item onto the beginning of the collection. + * + * @param mixed $value + * @return $this + */ + public function prepend($value) + { + array_unshift($this->items, $value); + + return $this; + } + + /** + * Push an item onto the end of the collection. + * + * @param mixed $value + * @return $this + */ + public function push($value) + { + $this->offsetSet(null, $value); + + return $this; + } + + /** + * Pulls an item from the collection. + * + * @param mixed $key + * @param mixed $default + * @return mixed + */ + public function pull($key, $default = null) + { + return Arr::pull($this->items, $key, $default); + } + + /** + * Put an item in the collection by key. + * + * @param mixed $key + * @param mixed $value + * @return $this + */ + public function put($key, $value) + { + $this->offsetSet($key, $value); + + return $this; + } + + /** + * Get one or more items randomly from the collection. + * + * @param int $amount + * @return mixed + * + * @throws \InvalidArgumentException + */ + public function random($amount = 1) + { + if ($amount > ($count = $this->count())) { + throw new InvalidArgumentException("You requested {$amount} items, but there are only {$count} items in the collection"); + } + + $keys = array_rand($this->items, $amount); + + if ($amount == 1) { + return $this->items[$keys]; + } + + return new static(array_intersect_key($this->items, array_flip($keys))); + } + + /** + * Reduce the collection to a single value. + * + * @param callable $callback + * @param mixed $initial + * @return mixed + */ + public function reduce(callable $callback, $initial = null) + { + return array_reduce($this->items, $callback, $initial); + } + + /** + * Create a collection of all elements that do not pass a given truth test. + * + * @param callable|mixed $callback + * @return static + */ + public function reject($callback) + { + if ($this->useAsCallable($callback)) { + return $this->filter(function ($item) use ($callback) { + return ! $callback($item); + }); + } + + return $this->filter(function ($item) use ($callback) { + return $item != $callback; + }); + } + + /** + * Reverse items order. + * + * @return static + */ + public function reverse() + { + return new static(array_reverse($this->items)); + } + + /** + * Search the collection for a given value and return the corresponding key if successful. + * + * @param mixed $value + * @param bool $strict + * @return mixed + */ + public function search($value, $strict = false) + { + if (! $this->useAsCallable($value)) { + return array_search($value, $this->items, $strict); + } + + foreach ($this->items as $key => $item) { + if (call_user_func($value, $item, $key)) { + return $key; + } + } + + return false; + } + + /** + * Get and remove the first item from the collection. + * + * @return mixed + */ + public function shift() + { + return array_shift($this->items); + } + + /** + * Shuffle the items in the collection. + * + * @return static + */ + public function shuffle() + { + $items = $this->items; + + shuffle($items); + + return new static($items); + } + + /** + * Slice the underlying collection array. + * + * @param int $offset + * @param int $length + * @param bool $preserveKeys + * @return static + */ + public function slice($offset, $length = null, $preserveKeys = false) + { + return new static(array_slice($this->items, $offset, $length, $preserveKeys)); + } + + /** + * Chunk the underlying collection array. + * + * @param int $size + * @param bool $preserveKeys + * @return static + */ + public function chunk($size, $preserveKeys = false) + { + $chunks = []; + + foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) { + $chunks[] = new static($chunk); + } + + return new static($chunks); + } + + /** + * Sort through each item with a callback. + * + * @param callable|null $callback + * @return static + */ + public function sort(callable $callback = null) + { + $items = $this->items; + + $callback ? uasort($items, $callback) : uasort($items, function ($a, $b) { + + if ($a == $b) { + return 0; + } + + return ($a < $b) ? -1 : 1; + }); + + return new static($items); + } + + /** + * Sort the collection using the given callback. + * + * @param callable|string $callback + * @param int $options + * @param bool $descending + * @return static + */ + public function sortBy($callback, $options = SORT_REGULAR, $descending = false) + { + $results = []; + + $callback = $this->valueRetriever($callback); + + // First we will loop through the items and get the comparator from a callback + // function which we were given. Then, we will sort the returned values and + // and grab the corresponding values for the sorted keys from this array. + foreach ($this->items as $key => $value) { + $results[$key] = $callback($value, $key); + } + + $descending ? arsort($results, $options) + : asort($results, $options); + + // Once we have sorted all of the keys in the array, we will loop through them + // and grab the corresponding model so we can set the underlying items list + // to the sorted version. Then we'll just return the collection instance. + foreach (array_keys($results) as $key) { + $results[$key] = $this->items[$key]; + } + + return new static($results); + } + + /** + * Sort the collection in descending order using the given callback. + * + * @param callable|string $callback + * @param int $options + * @return static + */ + public function sortByDesc($callback, $options = SORT_REGULAR) + { + return $this->sortBy($callback, $options, true); + } + + /** + * Splice a portion of the underlying collection array. + * + * @param int $offset + * @param int|null $length + * @param mixed $replacement + * @return static + */ + public function splice($offset, $length = null, $replacement = []) + { + if (func_num_args() == 1) { + return new static(array_splice($this->items, $offset)); + } + + return new static(array_splice($this->items, $offset, $length, $replacement)); + } + + /** + * Get the sum of the given values. + * + * @param callable|string|null $callback + * @return mixed + */ + public function sum($callback = null) + { + if (is_null($callback)) { + return array_sum($this->items); + } + + $callback = $this->valueRetriever($callback); + + return $this->reduce(function ($result, $item) use ($callback) { + return $result += $callback($item); + }, 0); + } + + /** + * Take the first or last {$limit} items. + * + * @param int $limit + * @return static + */ + public function take($limit) + { + if ($limit < 0) { + return $this->slice($limit, abs($limit)); + } + + return $this->slice(0, $limit); + } + + /** + * Transform each item in the collection using a callback. + * + * @param callable $callback + * @return $this + */ + public function transform(callable $callback) + { + $this->items = $this->map($callback)->all(); + + return $this; + } + + /** + * Return only unique items from the collection array. + * + * @param string|callable|null $key + * @return static + */ + public function unique($key = null) + { + if (is_null($key)) { + return new static(array_unique($this->items, SORT_REGULAR)); + } + + $key = $this->valueRetriever($key); + + $exists = []; + + return $this->reject(function ($item) use ($key, &$exists) { + if (in_array($id = $key($item), $exists)) { + return true; + } + + $exists[] = $id; + }); + } + + /** + * Reset the keys on the underlying array. + * + * @return static + */ + public function values() + { + return new static(array_values($this->items)); + } + + /** + * Get a value retrieving callback. + * + * @param string $value + * @return callable + */ + protected function valueRetriever($value) + { + if ($this->useAsCallable($value)) { + return $value; + } + + return function ($item) use ($value) { + return data_get($item, $value); + }; + } + + /** + * Zip the collection together with one or more arrays. + * + * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); + * => [[1, 4], [2, 5], [3, 6]] + * + * @param mixed ...$items + * @return static + */ + public function zip($items) + { + $arrayableItems = array_map(function ($items) { + return $this->getArrayableItems($items); + }, func_get_args()); + + $params = array_merge([function () { + return new static(func_get_args()); + }, $this->items], $arrayableItems); + + return new static(call_user_func_array('array_map', $params)); + } + + /** + * Get the collection of items as a plain array. + * + * @return array + */ + public function toArray() + { + return array_map(function ($value) { + return $value instanceof Arrayable ? $value->toArray() : $value; + + }, $this->items); + } + + /** + * Convert the object into something JSON serializable. + * + * @return array + */ + public function jsonSerialize() + { + return $this->toArray(); + } + + /** + * Get the collection of items as JSON. + * + * @param int $options + * @return string + */ + public function toJson($options = 0) + { + return json_encode($this->toArray(), $options); + } + + /** + * Get an iterator for the items. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->items); + } + + /** + * Get a CachingIterator instance. + * + * @param int $flags + * @return \CachingIterator + */ + public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING) + { + return new CachingIterator($this->getIterator(), $flags); + } + + /** + * Count the number of items in the collection. + * + * @return int + */ + public function count() + { + return count($this->items); + } + + /** + * Determine if an item exists at an offset. + * + * @param mixed $key + * @return bool + */ + public function offsetExists($key) + { + return array_key_exists($key, $this->items); + } + + /** + * Get an item at a given offset. + * + * @param mixed $key + * @return mixed + */ + public function offsetGet($key) + { + return $this->items[$key]; + } + + /** + * Set the item at a given offset. + * + * @param mixed $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + if (is_null($key)) { + $this->items[] = $value; + } else { + $this->items[$key] = $value; + } + } + + /** + * Unset the item at a given offset. + * + * @param string $key + * @return void + */ + public function offsetUnset($key) + { + unset($this->items[$key]); + } + + /** + * Convert the collection to its string representation. + * + * @return string + */ + public function __toString() + { + return $this->toJson(); + } + + /** + * Results array of items from Collection or Arrayable. + * + * @param mixed $items + * @return array + */ + protected function getArrayableItems($items) + { + if ($items instanceof self) { + return $items->all(); + } elseif ($items instanceof Arrayable) { + return $items->toArray(); + } elseif ($items instanceof Jsonable) { + return json_decode($items->toJson(), true); + } + + return (array) $items; + } +} diff --git a/vendor/illuminate/support/Debug/Dumper.php b/vendor/illuminate/support/Debug/Dumper.php new file mode 100644 index 0000000..7463ddb --- /dev/null +++ b/vendor/illuminate/support/Debug/Dumper.php @@ -0,0 +1,22 @@ +dump((new VarCloner)->cloneVar($value)); + } +} diff --git a/vendor/illuminate/support/Debug/HtmlDumper.php b/vendor/illuminate/support/Debug/HtmlDumper.php new file mode 100644 index 0000000..5825ac8 --- /dev/null +++ b/vendor/illuminate/support/Debug/HtmlDumper.php @@ -0,0 +1,29 @@ + 'background-color:#fff; color:#222; line-height:1.2em; font-weight:normal; font:12px Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:100000', + 'num' => 'color:#a71d5d', + 'const' => 'color:#795da3', + 'str' => 'color:#df5000', + 'cchr' => 'color:#222', + 'note' => 'color:#a71d5d', + 'ref' => 'color:#a0a0a0', + 'public' => 'color:#795da3', + 'protected' => 'color:#795da3', + 'private' => 'color:#795da3', + 'meta' => 'color:#b729d9', + 'key' => 'color:#df5000', + 'index' => 'color:#a71d5d', + ]; +} diff --git a/vendor/illuminate/support/Facades/App.php b/vendor/illuminate/support/Facades/App.php new file mode 100755 index 0000000..2675d56 --- /dev/null +++ b/vendor/illuminate/support/Facades/App.php @@ -0,0 +1,19 @@ +getEngineResolver()->resolve('blade')->getCompiler(); + } +} diff --git a/vendor/illuminate/support/Facades/Bus.php b/vendor/illuminate/support/Facades/Bus.php new file mode 100644 index 0000000..7c42e9e --- /dev/null +++ b/vendor/illuminate/support/Facades/Bus.php @@ -0,0 +1,19 @@ +cookie($key, null)); + } + + /** + * Retrieve a cookie from the request. + * + * @param string $key + * @param mixed $default + * @return string + */ + public static function get($key = null, $default = null) + { + return static::$app['request']->cookie($key, $default); + } + + /** + * Get the registered name of the component. + * + * @return string + */ + protected static function getFacadeAccessor() + { + return 'cookie'; + } +} diff --git a/vendor/illuminate/support/Facades/Crypt.php b/vendor/illuminate/support/Facades/Crypt.php new file mode 100755 index 0000000..0eef08d --- /dev/null +++ b/vendor/illuminate/support/Facades/Crypt.php @@ -0,0 +1,19 @@ +instance(static::getFacadeAccessor(), $instance); + } + + /** + * Initiate a mock expectation on the facade. + * + * @param mixed + * @return \Mockery\Expectation + */ + public static function shouldReceive() + { + $name = static::getFacadeAccessor(); + + if (static::isMock()) { + $mock = static::$resolvedInstance[$name]; + } else { + $mock = static::createFreshMockInstance($name); + } + + return call_user_func_array([$mock, 'shouldReceive'], func_get_args()); + } + + /** + * Create a fresh mock instance for the given class. + * + * @param string $name + * @return \Mockery\Expectation + */ + protected static function createFreshMockInstance($name) + { + static::$resolvedInstance[$name] = $mock = static::createMockByName($name); + + if (isset(static::$app)) { + static::$app->instance($name, $mock); + } + + return $mock; + } + + /** + * Create a fresh mock instance for the given class. + * + * @param string $name + * @return \Mockery\Expectation + */ + protected static function createMockByName($name) + { + $class = static::getMockableClass($name); + + return $class ? Mockery::mock($class) : Mockery::mock(); + } + + /** + * Determines whether a mock is set as the instance of the facade. + * + * @return bool + */ + protected static function isMock() + { + $name = static::getFacadeAccessor(); + + return isset(static::$resolvedInstance[$name]) && static::$resolvedInstance[$name] instanceof MockInterface; + } + + /** + * Get the mockable class for the bound instance. + * + * @return string|null + */ + protected static function getMockableClass() + { + if ($root = static::getFacadeRoot()) { + return get_class($root); + } + } + + /** + * Get the root object behind the facade. + * + * @return mixed + */ + public static function getFacadeRoot() + { + return static::resolveFacadeInstance(static::getFacadeAccessor()); + } + + /** + * Get the registered name of the component. + * + * @return string + * + * @throws \RuntimeException + */ + protected static function getFacadeAccessor() + { + throw new RuntimeException('Facade does not implement getFacadeAccessor method.'); + } + + /** + * Resolve the facade root instance from the container. + * + * @param string|object $name + * @return mixed + */ + protected static function resolveFacadeInstance($name) + { + if (is_object($name)) { + return $name; + } + + if (isset(static::$resolvedInstance[$name])) { + return static::$resolvedInstance[$name]; + } + + return static::$resolvedInstance[$name] = static::$app[$name]; + } + + /** + * Clear a resolved facade instance. + * + * @param string $name + * @return void + */ + public static function clearResolvedInstance($name) + { + unset(static::$resolvedInstance[$name]); + } + + /** + * Clear all of the resolved instances. + * + * @return void + */ + public static function clearResolvedInstances() + { + static::$resolvedInstance = []; + } + + /** + * Get the application instance behind the facade. + * + * @return \Illuminate\Contracts\Foundation\Application + */ + public static function getFacadeApplication() + { + return static::$app; + } + + /** + * Set the application instance. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @return void + */ + public static function setFacadeApplication($app) + { + static::$app = $app; + } + + /** + * Handle dynamic, static calls to the object. + * + * @param string $method + * @param array $args + * @return mixed + */ + public static function __callStatic($method, $args) + { + $instance = static::getFacadeRoot(); + + if (! $instance) { + throw new RuntimeException('A facade root has not been set.'); + } + + switch (count($args)) { + case 0: + return $instance->$method(); + + case 1: + return $instance->$method($args[0]); + + case 2: + return $instance->$method($args[0], $args[1]); + + case 3: + return $instance->$method($args[0], $args[1], $args[2]); + + case 4: + return $instance->$method($args[0], $args[1], $args[2], $args[3]); + + default: + return call_user_func_array([$instance, $method], $args); + } + } +} diff --git a/vendor/illuminate/support/Facades/File.php b/vendor/illuminate/support/Facades/File.php new file mode 100755 index 0000000..0f81bf6 --- /dev/null +++ b/vendor/illuminate/support/Facades/File.php @@ -0,0 +1,19 @@ +input($key, $default); + } + + /** + * Get the registered name of the component. + * + * @return string + */ + protected static function getFacadeAccessor() + { + return 'request'; + } +} diff --git a/vendor/illuminate/support/Facades/Lang.php b/vendor/illuminate/support/Facades/Lang.php new file mode 100755 index 0000000..e5862b9 --- /dev/null +++ b/vendor/illuminate/support/Facades/Lang.php @@ -0,0 +1,19 @@ +connection($name)->getSchemaBuilder(); + } + + /** + * Get a schema builder instance for the default connection. + * + * @return \Illuminate\Database\Schema\Builder + */ + protected static function getFacadeAccessor() + { + return static::$app['db']->connection()->getSchemaBuilder(); + } +} diff --git a/vendor/illuminate/support/Facades/Session.php b/vendor/illuminate/support/Facades/Session.php new file mode 100755 index 0000000..bc9b5fd --- /dev/null +++ b/vendor/illuminate/support/Facades/Session.php @@ -0,0 +1,20 @@ + $value) { + $this->attributes[$key] = $value; + } + } + + /** + * Get an attribute from the container. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function get($key, $default = null) + { + if (array_key_exists($key, $this->attributes)) { + return $this->attributes[$key]; + } + + return value($default); + } + + /** + * Get the attributes from the container. + * + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * Convert the Fluent instance to an array. + * + * @return array + */ + public function toArray() + { + return $this->attributes; + } + + /** + * Convert the object into something JSON serializable. + * + * @return array + */ + public function jsonSerialize() + { + return $this->toArray(); + } + + /** + * Convert the Fluent instance to JSON. + * + * @param int $options + * @return string + */ + public function toJson($options = 0) + { + return json_encode($this->toArray(), $options); + } + + /** + * Determine if the given offset exists. + * + * @param string $offset + * @return bool + */ + public function offsetExists($offset) + { + return isset($this->{$offset}); + } + + /** + * Get the value for a given offset. + * + * @param string $offset + * @return mixed + */ + public function offsetGet($offset) + { + return $this->{$offset}; + } + + /** + * Set the value at the given offset. + * + * @param string $offset + * @param mixed $value + * @return void + */ + public function offsetSet($offset, $value) + { + $this->{$offset} = $value; + } + + /** + * Unset the value at the given offset. + * + * @param string $offset + * @return void + */ + public function offsetUnset($offset) + { + unset($this->{$offset}); + } + + /** + * Handle dynamic calls to the container to set attributes. + * + * @param string $method + * @param array $parameters + * @return $this + */ + public function __call($method, $parameters) + { + $this->attributes[$method] = count($parameters) > 0 ? $parameters[0] : true; + + return $this; + } + + /** + * Dynamically retrieve the value of an attribute. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + return $this->get($key); + } + + /** + * Dynamically set the value of an attribute. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function __set($key, $value) + { + $this->attributes[$key] = $value; + } + + /** + * Dynamically check if an attribute is set. + * + * @param string $key + * @return bool + */ + public function __isset($key) + { + return isset($this->attributes[$key]); + } + + /** + * Dynamically unset an attribute. + * + * @param string $key + * @return void + */ + public function __unset($key) + { + unset($this->attributes[$key]); + } +} diff --git a/vendor/illuminate/support/HtmlString.php b/vendor/illuminate/support/HtmlString.php new file mode 100644 index 0000000..8d246cf --- /dev/null +++ b/vendor/illuminate/support/HtmlString.php @@ -0,0 +1,46 @@ +html = $html; + } + + /** + * Get the the HTML string. + * + * @return string + */ + public function toHtml() + { + return $this->html; + } + + /** + * Get the the HTML string. + * + * @return string + */ + public function __toString() + { + return $this->toHtml(); + } +} diff --git a/vendor/illuminate/support/Manager.php b/vendor/illuminate/support/Manager.php new file mode 100755 index 0000000..29154c6 --- /dev/null +++ b/vendor/illuminate/support/Manager.php @@ -0,0 +1,139 @@ +app = $app; + } + + /** + * Get the default driver name. + * + * @return string + */ + abstract public function getDefaultDriver(); + + /** + * Get a driver instance. + * + * @param string $driver + * @return mixed + */ + public function driver($driver = null) + { + $driver = $driver ?: $this->getDefaultDriver(); + + // If the given driver has not been created before, we will create the instances + // here and cache it so we can return it next time very quickly. If there is + // already a driver created by this name, we'll just return that instance. + if (! isset($this->drivers[$driver])) { + $this->drivers[$driver] = $this->createDriver($driver); + } + + return $this->drivers[$driver]; + } + + /** + * Create a new driver instance. + * + * @param string $driver + * @return mixed + * + * @throws \InvalidArgumentException + */ + protected function createDriver($driver) + { + $method = 'create'.ucfirst($driver).'Driver'; + + // We'll check to see if a creator method exists for the given driver. If not we + // will check for a custom driver creator, which allows developers to create + // drivers using their own customized driver creator Closure to create it. + if (isset($this->customCreators[$driver])) { + return $this->callCustomCreator($driver); + } elseif (method_exists($this, $method)) { + return $this->$method(); + } + + throw new InvalidArgumentException("Driver [$driver] not supported."); + } + + /** + * Call a custom driver creator. + * + * @param string $driver + * @return mixed + */ + protected function callCustomCreator($driver) + { + return $this->customCreators[$driver]($this->app); + } + + /** + * Register a custom driver creator Closure. + * + * @param string $driver + * @param \Closure $callback + * @return $this + */ + public function extend($driver, Closure $callback) + { + $this->customCreators[$driver] = $callback; + + return $this; + } + + /** + * Get all of the created "drivers". + * + * @return array + */ + public function getDrivers() + { + return $this->drivers; + } + + /** + * Dynamically call the default driver instance. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->driver(), $method], $parameters); + } +} diff --git a/vendor/illuminate/support/MessageBag.php b/vendor/illuminate/support/MessageBag.php new file mode 100755 index 0000000..a58b154 --- /dev/null +++ b/vendor/illuminate/support/MessageBag.php @@ -0,0 +1,309 @@ + $value) { + $this->messages[$key] = (array) $value; + } + } + + /** + * Get the keys present in the message bag. + * + * @return array + */ + public function keys() + { + return array_keys($this->messages); + } + + /** + * Add a message to the bag. + * + * @param string $key + * @param string $message + * @return $this + */ + public function add($key, $message) + { + if ($this->isUnique($key, $message)) { + $this->messages[$key][] = $message; + } + + return $this; + } + + /** + * Merge a new array of messages into the bag. + * + * @param \Illuminate\Contracts\Support\MessageProvider|array $messages + * @return $this + */ + public function merge($messages) + { + if ($messages instanceof MessageProvider) { + $messages = $messages->getMessageBag()->getMessages(); + } + + $this->messages = array_merge_recursive($this->messages, $messages); + + return $this; + } + + /** + * Determine if a key and message combination already exists. + * + * @param string $key + * @param string $message + * @return bool + */ + protected function isUnique($key, $message) + { + $messages = (array) $this->messages; + + return ! isset($messages[$key]) || ! in_array($message, $messages[$key]); + } + + /** + * Determine if messages exist for a given key. + * + * @param string $key + * @return bool + */ + public function has($key = null) + { + return $this->first($key) !== ''; + } + + /** + * Get the first message from the bag for a given key. + * + * @param string $key + * @param string $format + * @return string + */ + public function first($key = null, $format = null) + { + $messages = is_null($key) ? $this->all($format) : $this->get($key, $format); + + return count($messages) > 0 ? $messages[0] : ''; + } + + /** + * Get all of the messages from the bag for a given key. + * + * @param string $key + * @param string $format + * @return array + */ + public function get($key, $format = null) + { + // If the message exists in the container, we will transform it and return + // the message. Otherwise, we'll return an empty array since the entire + // methods is to return back an array of messages in the first place. + if (array_key_exists($key, $this->messages)) { + return $this->transform($this->messages[$key], $this->checkFormat($format), $key); + } + + return []; + } + + /** + * Get all of the messages for every key in the bag. + * + * @param string $format + * @return array + */ + public function all($format = null) + { + $format = $this->checkFormat($format); + + $all = []; + + foreach ($this->messages as $key => $messages) { + $all = array_merge($all, $this->transform($messages, $format, $key)); + } + + return $all; + } + + /** + * Format an array of messages. + * + * @param array $messages + * @param string $format + * @param string $messageKey + * @return array + */ + protected function transform($messages, $format, $messageKey) + { + $messages = (array) $messages; + + // We will simply spin through the given messages and transform each one + // replacing the :message place holder with the real message allowing + // the messages to be easily formatted to each developer's desires. + $replace = [':message', ':key']; + + foreach ($messages as &$message) { + $message = str_replace($replace, [$message, $messageKey], $format); + } + + return $messages; + } + + /** + * Get the appropriate format based on the given format. + * + * @param string $format + * @return string + */ + protected function checkFormat($format) + { + return $format ?: $this->format; + } + + /** + * Get the raw messages in the container. + * + * @return array + */ + public function getMessages() + { + return $this->messages; + } + + /** + * Get the messages for the instance. + * + * @return \Illuminate\Support\MessageBag + */ + public function getMessageBag() + { + return $this; + } + + /** + * Get the default message format. + * + * @return string + */ + public function getFormat() + { + return $this->format; + } + + /** + * Set the default message format. + * + * @param string $format + * @return \Illuminate\Support\MessageBag + */ + public function setFormat($format = ':message') + { + $this->format = $format; + + return $this; + } + + /** + * Determine if the message bag has any messages. + * + * @return bool + */ + public function isEmpty() + { + return ! $this->any(); + } + + /** + * Determine if the message bag has any messages. + * + * @return bool + */ + public function any() + { + return $this->count() > 0; + } + + /** + * Get the number of messages in the container. + * + * @return int + */ + public function count() + { + return count($this->messages, COUNT_RECURSIVE) - count($this->messages); + } + + /** + * Get the instance as an array. + * + * @return array + */ + public function toArray() + { + return $this->getMessages(); + } + + /** + * Convert the object into something JSON serializable. + * + * @return array + */ + public function jsonSerialize() + { + return $this->toArray(); + } + + /** + * Convert the object to its JSON representation. + * + * @param int $options + * @return string + */ + public function toJson($options = 0) + { + return json_encode($this->toArray(), $options); + } + + /** + * Convert the message bag to its string representation. + * + * @return string + */ + public function __toString() + { + return $this->toJson(); + } +} diff --git a/vendor/illuminate/support/NamespacedItemResolver.php b/vendor/illuminate/support/NamespacedItemResolver.php new file mode 100755 index 0000000..a111985 --- /dev/null +++ b/vendor/illuminate/support/NamespacedItemResolver.php @@ -0,0 +1,104 @@ +parsed[$key])) { + return $this->parsed[$key]; + } + + // If the key does not contain a double colon, it means the key is not in a + // namespace, and is just a regular configuration item. Namespaces are a + // tool for organizing configuration items for things such as modules. + if (strpos($key, '::') === false) { + $segments = explode('.', $key); + + $parsed = $this->parseBasicSegments($segments); + } else { + $parsed = $this->parseNamespacedSegments($key); + } + + // Once we have the parsed array of this key's elements, such as its groups + // and namespace, we will cache each array inside a simple list that has + // the key and the parsed array for quick look-ups for later requests. + return $this->parsed[$key] = $parsed; + } + + /** + * Parse an array of basic segments. + * + * @param array $segments + * @return array + */ + protected function parseBasicSegments(array $segments) + { + // The first segment in a basic array will always be the group, so we can go + // ahead and grab that segment. If there is only one total segment we are + // just pulling an entire group out of the array and not a single item. + $group = $segments[0]; + + if (count($segments) == 1) { + return [null, $group, null]; + } + + // If there is more than one segment in this group, it means we are pulling + // a specific item out of a groups and will need to return the item name + // as well as the group so we know which item to pull from the arrays. + else { + $item = implode('.', array_slice($segments, 1)); + + return [null, $group, $item]; + } + } + + /** + * Parse an array of namespaced segments. + * + * @param string $key + * @return array + */ + protected function parseNamespacedSegments($key) + { + list($namespace, $item) = explode('::', $key); + + // First we'll just explode the first segment to get the namespace and group + // since the item should be in the remaining segments. Once we have these + // two pieces of data we can proceed with parsing out the item's value. + $itemSegments = explode('.', $item); + + $groupAndItem = array_slice($this->parseBasicSegments($itemSegments), 1); + + return array_merge([$namespace], $groupAndItem); + } + + /** + * Set the parsed value of a key. + * + * @param string $key + * @param array $parsed + * @return void + */ + public function setParsedKey($key, $parsed) + { + $this->parsed[$key] = $parsed; + } +} diff --git a/vendor/illuminate/support/Pluralizer.php b/vendor/illuminate/support/Pluralizer.php new file mode 100755 index 0000000..ca8d902 --- /dev/null +++ b/vendor/illuminate/support/Pluralizer.php @@ -0,0 +1,101 @@ +app = $app; + } + + /** + * Register the service provider. + * + * @return void + */ + abstract public function register(); + + /** + * Merge the given configuration with the existing configuration. + * + * @param string $path + * @param string $key + * @return void + */ + protected function mergeConfigFrom($path, $key) + { + $config = $this->app['config']->get($key, []); + + $this->app['config']->set($key, array_merge(require $path, $config)); + } + + /** + * Register a view file namespace. + * + * @param string $path + * @param string $namespace + * @return void + */ + protected function loadViewsFrom($path, $namespace) + { + if (is_dir($appPath = $this->app->basePath().'/resources/views/vendor/'.$namespace)) { + $this->app['view']->addNamespace($namespace, $appPath); + } + + $this->app['view']->addNamespace($namespace, $path); + } + + /** + * Register a translation file namespace. + * + * @param string $path + * @param string $namespace + * @return void + */ + protected function loadTranslationsFrom($path, $namespace) + { + $this->app['translator']->addNamespace($namespace, $path); + } + + /** + * Register paths to be published by the publish command. + * + * @param array $paths + * @param string $group + * @return void + */ + protected function publishes(array $paths, $group = null) + { + $class = get_class($this); + + if (! array_key_exists($class, static::$publishes)) { + static::$publishes[$class] = []; + } + + static::$publishes[$class] = array_merge(static::$publishes[$class], $paths); + + if ($group) { + if (! array_key_exists($group, static::$publishGroups)) { + static::$publishGroups[$group] = []; + } + + static::$publishGroups[$group] = array_merge(static::$publishGroups[$group], $paths); + } + } + + /** + * Get the paths to publish. + * + * @param string $provider + * @param string $group + * @return array + */ + public static function pathsToPublish($provider = null, $group = null) + { + if ($provider && $group) { + if (empty(static::$publishes[$provider]) || empty(static::$publishGroups[$group])) { + return []; + } + + return array_intersect(static::$publishes[$provider], static::$publishGroups[$group]); + } + + if ($group && array_key_exists($group, static::$publishGroups)) { + return static::$publishGroups[$group]; + } + + if ($provider && array_key_exists($provider, static::$publishes)) { + return static::$publishes[$provider]; + } + + if ($group || $provider) { + return []; + } + + $paths = []; + + foreach (static::$publishes as $class => $publish) { + $paths = array_merge($paths, $publish); + } + + return $paths; + } + + /** + * Register the package's custom Artisan commands. + * + * @param array|mixed $commands + * @return void + */ + public function commands($commands) + { + $commands = is_array($commands) ? $commands : func_get_args(); + + // To register the commands with Artisan, we will grab each of the arguments + // passed into the method and listen for Artisan "start" event which will + // give us the Artisan console instance which we will give commands to. + $events = $this->app['events']; + + $events->listen('artisan.start', function ($artisan) use ($commands) { + $artisan->resolveCommands($commands); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return []; + } + + /** + * Get the events that trigger this service provider to register. + * + * @return array + */ + public function when() + { + return []; + } + + /** + * Determine if the provider is deferred. + * + * @return bool + */ + public function isDeferred() + { + return $this->defer; + } + + /** + * Get a list of files that should be compiled for the package. + * + * @return array + */ + public static function compiles() + { + return []; + } + + /** + * Dynamically handle missing method calls. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if ($method == 'boot') { + return; + } + + throw new BadMethodCallException("Call to undefined method [{$method}]"); + } +} diff --git a/vendor/illuminate/support/Str.php b/vendor/illuminate/support/Str.php new file mode 100755 index 0000000..6e5b854 --- /dev/null +++ b/vendor/illuminate/support/Str.php @@ -0,0 +1,460 @@ += 7 || defined('RANDOM_COMPAT_READ_BUFFER')) { + $bytes = random_bytes($length); + } elseif (function_exists('openssl_random_pseudo_bytes')) { + $bytes = openssl_random_pseudo_bytes($length, $strong); + + if ($bytes === false || $strong === false) { + throw new RuntimeException('Unable to generate random string.'); + } + } else { + throw new RuntimeException('OpenSSL extension or paragonie/random_compat is required for PHP 5 users.'); + } + + return $bytes; + } + + /** + * Generate a "random" alpha-numeric string. + * + * Should not be considered sufficient for cryptography, etc. + * + * @param int $length + * @return string + */ + public static function quickRandom($length = 16) + { + $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + return substr(str_shuffle(str_repeat($pool, $length)), 0, $length); + } + + /** + * Compares two strings using a constant-time algorithm. + * + * Note: This method will leak length information. + * + * Note: Adapted from Symfony\Component\Security\Core\Util\StringUtils. + * + * @param string $knownString + * @param string $userInput + * @return bool + */ + public static function equals($knownString, $userInput) + { + if (! is_string($knownString)) { + $knownString = (string) $knownString; + } + + if (! is_string($userInput)) { + $userInput = (string) $userInput; + } + + if (function_exists('hash_equals')) { + return hash_equals($knownString, $userInput); + } + + $knownLength = mb_strlen($knownString, '8bit'); + + if (mb_strlen($userInput, '8bit') !== $knownLength) { + return false; + } + + $result = 0; + + for ($i = 0; $i < $knownLength; ++$i) { + $result |= (ord($knownString[$i]) ^ ord($userInput[$i])); + } + + return 0 === $result; + } + + /** + * Convert the given string to upper-case. + * + * @param string $value + * @return string + */ + public static function upper($value) + { + return mb_strtoupper($value, 'UTF-8'); + } + + /** + * Convert the given string to title case. + * + * @param string $value + * @return string + */ + public static function title($value) + { + return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8'); + } + + /** + * Get the singular form of an English word. + * + * @param string $value + * @return string + */ + public static function singular($value) + { + return Pluralizer::singular($value); + } + + /** + * Generate a URL friendly "slug" from a given string. + * + * @param string $title + * @param string $separator + * @return string + */ + public static function slug($title, $separator = '-') + { + $title = static::ascii($title); + + // Convert all dashes/underscores into separator + $flip = $separator == '-' ? '_' : '-'; + + $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title); + + // Remove all characters that are not the separator, letters, numbers, or whitespace. + $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', mb_strtolower($title)); + + // Replace all separator characters and whitespace by a single separator + $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title); + + return trim($title, $separator); + } + + /** + * Convert a string to snake case. + * + * @param string $value + * @param string $delimiter + * @return string + */ + public static function snake($value, $delimiter = '_') + { + $key = $value.$delimiter; + + if (isset(static::$snakeCache[$key])) { + return static::$snakeCache[$key]; + } + + if (! ctype_lower($value)) { + $value = preg_replace('/\s+/', '', $value); + + $value = strtolower(preg_replace('/(.)(?=[A-Z])/', '$1'.$delimiter, $value)); + } + + return static::$snakeCache[$key] = $value; + } + + /** + * Determine if a given string starts with a given substring. + * + * @param string $haystack + * @param string|array $needles + * @return bool + */ + public static function startsWith($haystack, $needles) + { + foreach ((array) $needles as $needle) { + if ($needle != '' && strpos($haystack, $needle) === 0) { + return true; + } + } + + return false; + } + + /** + * Convert a value to studly caps case. + * + * @param string $value + * @return string + */ + public static function studly($value) + { + $key = $value; + + if (isset(static::$studlyCache[$key])) { + return static::$studlyCache[$key]; + } + + $value = ucwords(str_replace(['-', '_'], ' ', $value)); + + return static::$studlyCache[$key] = str_replace(' ', '', $value); + } + + /** + * Returns the portion of string specified by the start and length parameters. + * + * @param string $string + * @param int $start + * @param int|null $length + * @return string + */ + public static function substr($string, $start, $length = null) + { + return mb_substr($string, $start, $length, 'UTF-8'); + } + + /** + * Make a string's first character uppercase. + * + * @param string $string + * @return string + */ + public static function ucfirst($string) + { + return static::upper(static::substr($string, 0, 1)).static::substr($string, 1); + } +} diff --git a/vendor/illuminate/support/Traits/CapsuleManagerTrait.php b/vendor/illuminate/support/Traits/CapsuleManagerTrait.php new file mode 100644 index 0000000..08089ef --- /dev/null +++ b/vendor/illuminate/support/Traits/CapsuleManagerTrait.php @@ -0,0 +1,69 @@ +container = $container; + + if (! $this->container->bound('config')) { + $this->container->instance('config', new Fluent); + } + } + + /** + * Make this capsule instance available globally. + * + * @return void + */ + public function setAsGlobal() + { + static::$instance = $this; + } + + /** + * Get the IoC container instance. + * + * @return \Illuminate\Contracts\Container\Container + */ + public function getContainer() + { + return $this->container; + } + + /** + * Set the IoC container instance. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return void + */ + public function setContainer(Container $container) + { + $this->container = $container; + } +} diff --git a/vendor/illuminate/support/Traits/Macroable.php b/vendor/illuminate/support/Traits/Macroable.php new file mode 100644 index 0000000..a6a54fd --- /dev/null +++ b/vendor/illuminate/support/Traits/Macroable.php @@ -0,0 +1,83 @@ +bindTo($this, get_class($this)), $parameters); + } else { + return call_user_func_array(static::$macros[$method], $parameters); + } + } + + throw new BadMethodCallException("Method {$method} does not exist."); + } +} diff --git a/vendor/illuminate/support/ViewErrorBag.php b/vendor/illuminate/support/ViewErrorBag.php new file mode 100644 index 0000000..eed64c3 --- /dev/null +++ b/vendor/illuminate/support/ViewErrorBag.php @@ -0,0 +1,107 @@ +bags[$key]); + } + + /** + * Get a MessageBag instance from the bags. + * + * @param string $key + * @return \Illuminate\Contracts\Support\MessageBag + */ + public function getBag($key) + { + return Arr::get($this->bags, $key, new MessageBag); + } + + /** + * Get all the bags. + * + * @return array + */ + public function getBags() + { + return $this->bags; + } + + /** + * Add a new MessageBag instance to the bags. + * + * @param string $key + * @param \Illuminate\Contracts\Support\MessageBag $bag + * @return $this + */ + public function put($key, MessageBagContract $bag) + { + $this->bags[$key] = $bag; + + return $this; + } + + /** + * Get the number of messages in the default bag. + * + * @return int + */ + public function count() + { + return $this->default->count(); + } + + /** + * Dynamically call methods on the default bag. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return call_user_func_array([$this->default, $method], $parameters); + } + + /** + * Dynamically access a view error bag. + * + * @param string $key + * @return \Illuminate\Contracts\Support\MessageBag + */ + public function __get($key) + { + return Arr::get($this->bags, $key, new MessageBag); + } + + /** + * Dynamically set a view error bag. + * + * @param string $key + * @param \Illuminate\Contracts\Support\MessageBag $value + * @return void + */ + public function __set($key, $value) + { + Arr::set($this->bags, $key, $value); + } +} diff --git a/vendor/illuminate/support/composer.json b/vendor/illuminate/support/composer.json new file mode 100755 index 0000000..feb8bd4 --- /dev/null +++ b/vendor/illuminate/support/composer.json @@ -0,0 +1,42 @@ +{ + "name": "illuminate/support", + "description": "The Illuminate Support package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "ext-mbstring": "*", + "illuminate/contracts": "5.1.*", + "doctrine/inflector": "~1.0", + "danielstjules/stringy": "~1.8" + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + }, + "files": [ + "helpers.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "jeremeamia/superclosure": "Required to be able to serialize closures (~2.0).", + "paragonie/random_compat": "Provides a compatible interface like PHP7's random_bytes() in PHP 5 projects (^1.0.6).", + "symfony/var-dumper": "Required to use the dd function (2.7.*)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/support/helpers.php b/vendor/illuminate/support/helpers.php new file mode 100755 index 0000000..6a8fbe9 --- /dev/null +++ b/vendor/illuminate/support/helpers.php @@ -0,0 +1,774 @@ + $value) { + if (is_numeric($key)) { + $start++; + + $array[$start] = Arr::pull($array, $key); + } + } + + return $array; + } +} + +if (! function_exists('array_add')) { + /** + * Add an element to an array using "dot" notation if it doesn't exist. + * + * @param array $array + * @param string $key + * @param mixed $value + * @return array + */ + function array_add($array, $key, $value) + { + return Arr::add($array, $key, $value); + } +} + +if (! function_exists('array_build')) { + /** + * Build a new array using a callback. + * + * @param array $array + * @param callable $callback + * @return array + */ + function array_build($array, callable $callback) + { + return Arr::build($array, $callback); + } +} + +if (! function_exists('array_collapse')) { + /** + * Collapse an array of arrays into a single array. + * + * @param array|\ArrayAccess $array + * @return array + */ + function array_collapse($array) + { + return Arr::collapse($array); + } +} + +if (! function_exists('array_divide')) { + /** + * Divide an array into two arrays. One with keys and the other with values. + * + * @param array $array + * @return array + */ + function array_divide($array) + { + return Arr::divide($array); + } +} + +if (! function_exists('array_dot')) { + /** + * Flatten a multi-dimensional associative array with dots. + * + * @param array $array + * @param string $prepend + * @return array + */ + function array_dot($array, $prepend = '') + { + return Arr::dot($array, $prepend); + } +} + +if (! function_exists('array_except')) { + /** + * Get all of the given array except for a specified array of items. + * + * @param array $array + * @param array|string $keys + * @return array + */ + function array_except($array, $keys) + { + return Arr::except($array, $keys); + } +} + +if (! function_exists('array_fetch')) { + /** + * Fetch a flattened array of a nested array element. + * + * @param array $array + * @param string $key + * @return array + * + * @deprecated since version 5.1. Use array_pluck instead. + */ + function array_fetch($array, $key) + { + return Arr::fetch($array, $key); + } +} + +if (! function_exists('array_first')) { + /** + * Return the first element in an array passing a given truth test. + * + * @param array $array + * @param callable $callback + * @param mixed $default + * @return mixed + */ + function array_first($array, callable $callback, $default = null) + { + return Arr::first($array, $callback, $default); + } +} + +if (! function_exists('array_flatten')) { + /** + * Flatten a multi-dimensional array into a single level. + * + * @param array $array + * @return array + */ + function array_flatten($array) + { + return Arr::flatten($array); + } +} + +if (! function_exists('array_forget')) { + /** + * Remove one or many array items from a given array using "dot" notation. + * + * @param array $array + * @param array|string $keys + * @return void + */ + function array_forget(&$array, $keys) + { + return Arr::forget($array, $keys); + } +} + +if (! function_exists('array_get')) { + /** + * Get an item from an array using "dot" notation. + * + * @param array $array + * @param string $key + * @param mixed $default + * @return mixed + */ + function array_get($array, $key, $default = null) + { + return Arr::get($array, $key, $default); + } +} + +if (! function_exists('array_has')) { + /** + * Check if an item exists in an array using "dot" notation. + * + * @param array $array + * @param string $key + * @return bool + */ + function array_has($array, $key) + { + return Arr::has($array, $key); + } +} + +if (! function_exists('array_last')) { + /** + * Return the last element in an array passing a given truth test. + * + * @param array $array + * @param callable $callback + * @param mixed $default + * @return mixed + */ + function array_last($array, $callback, $default = null) + { + return Arr::last($array, $callback, $default); + } +} + +if (! function_exists('array_only')) { + /** + * Get a subset of the items from the given array. + * + * @param array $array + * @param array|string $keys + * @return array + */ + function array_only($array, $keys) + { + return Arr::only($array, $keys); + } +} + +if (! function_exists('array_pluck')) { + /** + * Pluck an array of values from an array. + * + * @param array $array + * @param string|array $value + * @param string|array|null $key + * @return array + */ + function array_pluck($array, $value, $key = null) + { + return Arr::pluck($array, $value, $key); + } +} + +if (! function_exists('array_pull')) { + /** + * Get a value from the array, and remove it. + * + * @param array $array + * @param string $key + * @param mixed $default + * @return mixed + */ + function array_pull(&$array, $key, $default = null) + { + return Arr::pull($array, $key, $default); + } +} + +if (! function_exists('array_set')) { + /** + * Set an array item to a given value using "dot" notation. + * + * If no key is given to the method, the entire array will be replaced. + * + * @param array $array + * @param string $key + * @param mixed $value + * @return array + */ + function array_set(&$array, $key, $value) + { + return Arr::set($array, $key, $value); + } +} + +if (! function_exists('array_sort')) { + /** + * Sort the array using the given callback. + * + * @param array $array + * @param callable $callback + * @return array + */ + function array_sort($array, callable $callback) + { + return Arr::sort($array, $callback); + } +} + +if (! function_exists('array_sort_recursive')) { + /** + * Recursively sort an array by keys and values. + * + * @param array $array + * @return array + */ + function array_sort_recursive($array) + { + return Arr::sortRecursive($array); + } +} + +if (! function_exists('array_where')) { + /** + * Filter the array using the given callback. + * + * @param array $array + * @param callable $callback + * @return array + */ + function array_where($array, callable $callback) + { + return Arr::where($array, $callback); + } +} + +if (! function_exists('camel_case')) { + /** + * Convert a value to camel case. + * + * @param string $value + * @return string + */ + function camel_case($value) + { + return Str::camel($value); + } +} + +if (! function_exists('class_basename')) { + /** + * Get the class "basename" of the given object / class. + * + * @param string|object $class + * @return string + */ + function class_basename($class) + { + $class = is_object($class) ? get_class($class) : $class; + + return basename(str_replace('\\', '/', $class)); + } +} + +if (! function_exists('class_uses_recursive')) { + /** + * Returns all traits used by a class, its subclasses and trait of their traits. + * + * @param string $class + * @return array + */ + function class_uses_recursive($class) + { + $results = []; + + foreach (array_merge([$class => $class], class_parents($class)) as $class) { + $results += trait_uses_recursive($class); + } + + return array_unique($results); + } +} + +if (! function_exists('collect')) { + /** + * Create a collection from the given value. + * + * @param mixed $value + * @return \Illuminate\Support\Collection + */ + function collect($value = null) + { + return new Collection($value); + } +} + +if (! function_exists('data_get')) { + /** + * Get an item from an array or object using "dot" notation. + * + * @param mixed $target + * @param string|array $key + * @param mixed $default + * @return mixed + */ + function data_get($target, $key, $default = null) + { + if (is_null($key)) { + return $target; + } + + $key = is_array($key) ? $key : explode('.', $key); + + foreach ($key as $segment) { + if (is_array($target)) { + if (! array_key_exists($segment, $target)) { + return value($default); + } + + $target = $target[$segment]; + } elseif ($target instanceof ArrayAccess) { + if (! isset($target[$segment])) { + return value($default); + } + + $target = $target[$segment]; + } elseif (is_object($target)) { + if (! isset($target->{$segment})) { + return value($default); + } + + $target = $target->{$segment}; + } else { + return value($default); + } + } + + return $target; + } +} + +if (! function_exists('dd')) { + /** + * Dump the passed variables and end the script. + * + * @param mixed + * @return void + */ + function dd() + { + array_map(function ($x) { + (new Dumper)->dump($x); + }, func_get_args()); + + die(1); + } +} + +if (! function_exists('e')) { + /** + * Escape HTML entities in a string. + * + * @param \Illuminate\Support\Htmlable|string $value + * @return string + */ + function e($value) + { + if ($value instanceof Htmlable) { + return $value->toHtml(); + } + + return htmlentities($value, ENT_QUOTES, 'UTF-8', false); + } +} + +if (! function_exists('ends_with')) { + /** + * Determine if a given string ends with a given substring. + * + * @param string $haystack + * @param string|array $needles + * @return bool + */ + function ends_with($haystack, $needles) + { + return Str::endsWith($haystack, $needles); + } +} + +if (! function_exists('head')) { + /** + * Get the first element of an array. Useful for method chaining. + * + * @param array $array + * @return mixed + */ + function head($array) + { + return reset($array); + } +} + +if (! function_exists('last')) { + /** + * Get the last element from an array. + * + * @param array $array + * @return mixed + */ + function last($array) + { + return end($array); + } +} + +if (! function_exists('object_get')) { + /** + * Get an item from an object using "dot" notation. + * + * @param object $object + * @param string $key + * @param mixed $default + * @return mixed + */ + function object_get($object, $key, $default = null) + { + if (is_null($key) || trim($key) == '') { + return $object; + } + + foreach (explode('.', $key) as $segment) { + if (! is_object($object) || ! isset($object->{$segment})) { + return value($default); + } + + $object = $object->{$segment}; + } + + return $object; + } +} + +if (! function_exists('preg_replace_sub')) { + /** + * Replace a given pattern with each value in the array in sequentially. + * + * @param string $pattern + * @param array $replacements + * @param string $subject + * @return string + */ + function preg_replace_sub($pattern, &$replacements, $subject) + { + return preg_replace_callback($pattern, function ($match) use (&$replacements) { + foreach ($replacements as $key => $value) { + return array_shift($replacements); + } + + }, $subject); + } +} + +if (! function_exists('snake_case')) { + /** + * Convert a string to snake case. + * + * @param string $value + * @param string $delimiter + * @return string + */ + function snake_case($value, $delimiter = '_') + { + return Str::snake($value, $delimiter); + } +} + +if (! function_exists('starts_with')) { + /** + * Determine if a given string starts with a given substring. + * + * @param string $haystack + * @param string|array $needles + * @return bool + */ + function starts_with($haystack, $needles) + { + return Str::startsWith($haystack, $needles); + } +} + +if (! function_exists('str_contains')) { + /** + * Determine if a given string contains a given substring. + * + * @param string $haystack + * @param string|array $needles + * @return bool + */ + function str_contains($haystack, $needles) + { + return Str::contains($haystack, $needles); + } +} + +if (! function_exists('str_finish')) { + /** + * Cap a string with a single instance of a given value. + * + * @param string $value + * @param string $cap + * @return string + */ + function str_finish($value, $cap) + { + return Str::finish($value, $cap); + } +} + +if (! function_exists('str_is')) { + /** + * Determine if a given string matches a given pattern. + * + * @param string $pattern + * @param string $value + * @return bool + */ + function str_is($pattern, $value) + { + return Str::is($pattern, $value); + } +} + +if (! function_exists('str_limit')) { + /** + * Limit the number of characters in a string. + * + * @param string $value + * @param int $limit + * @param string $end + * @return string + */ + function str_limit($value, $limit = 100, $end = '...') + { + return Str::limit($value, $limit, $end); + } +} + +if (! function_exists('str_plural')) { + /** + * Get the plural form of an English word. + * + * @param string $value + * @param int $count + * @return string + */ + function str_plural($value, $count = 2) + { + return Str::plural($value, $count); + } +} + +if (! function_exists('str_random')) { + /** + * Generate a more truly "random" alpha-numeric string. + * + * @param int $length + * @return string + * + * @throws \RuntimeException + */ + function str_random($length = 16) + { + return Str::random($length); + } +} + +if (! function_exists('str_replace_array')) { + /** + * Replace a given value in the string sequentially with an array. + * + * @param string $search + * @param array $replace + * @param string $subject + * @return string + */ + function str_replace_array($search, array $replace, $subject) + { + foreach ($replace as $value) { + $subject = preg_replace('/'.$search.'/', $value, $subject, 1); + } + + return $subject; + } +} + +if (! function_exists('str_singular')) { + /** + * Get the singular form of an English word. + * + * @param string $value + * @return string + */ + function str_singular($value) + { + return Str::singular($value); + } +} + +if (! function_exists('str_slug')) { + /** + * Generate a URL friendly "slug" from a given string. + * + * @param string $title + * @param string $separator + * @return string + */ + function str_slug($title, $separator = '-') + { + return Str::slug($title, $separator); + } +} + +if (! function_exists('studly_case')) { + /** + * Convert a value to studly caps case. + * + * @param string $value + * @return string + */ + function studly_case($value) + { + return Str::studly($value); + } +} + +if (! function_exists('title_case')) { + /** + * Convert a value to title case. + * + * @param string $value + * @return string + */ + function title_case($value) + { + return Str::title($value); + } +} + +if (! function_exists('trait_uses_recursive')) { + /** + * Returns all traits used by a trait and its traits. + * + * @param string $trait + * @return array + */ + function trait_uses_recursive($trait) + { + $traits = class_uses($trait); + + foreach ($traits as $trait) { + $traits += trait_uses_recursive($trait); + } + + return $traits; + } +} + +if (! function_exists('value')) { + /** + * Return the default value of the given value. + * + * @param mixed $value + * @return mixed + */ + function value($value) + { + return $value instanceof Closure ? $value() : $value; + } +} + +if (! function_exists('with')) { + /** + * Return the given object. Useful for chaining. + * + * @param mixed $object + * @return mixed + */ + function with($object) + { + return $object; + } +} diff --git a/vendor/illuminate/translation/FileLoader.php b/vendor/illuminate/translation/FileLoader.php new file mode 100755 index 0000000..835accc --- /dev/null +++ b/vendor/illuminate/translation/FileLoader.php @@ -0,0 +1,127 @@ +path = $path; + $this->files = $files; + } + + /** + * Load the messages for the given locale. + * + * @param string $locale + * @param string $group + * @param string $namespace + * @return array + */ + public function load($locale, $group, $namespace = null) + { + if (is_null($namespace) || $namespace == '*') { + return $this->loadPath($this->path, $locale, $group); + } + + return $this->loadNamespaced($locale, $group, $namespace); + } + + /** + * Load a namespaced translation group. + * + * @param string $locale + * @param string $group + * @param string $namespace + * @return array + */ + protected function loadNamespaced($locale, $group, $namespace) + { + if (isset($this->hints[$namespace])) { + $lines = $this->loadPath($this->hints[$namespace], $locale, $group); + + return $this->loadNamespaceOverrides($lines, $locale, $group, $namespace); + } + + return []; + } + + /** + * Load a local namespaced translation group for overrides. + * + * @param array $lines + * @param string $locale + * @param string $group + * @param string $namespace + * @return array + */ + protected function loadNamespaceOverrides(array $lines, $locale, $group, $namespace) + { + $file = "{$this->path}/vendor/{$namespace}/{$locale}/{$group}.php"; + + if ($this->files->exists($file)) { + return array_replace_recursive($lines, $this->files->getRequire($file)); + } + + return $lines; + } + + /** + * Load a locale from a given path. + * + * @param string $path + * @param string $locale + * @param string $group + * @return array + */ + protected function loadPath($path, $locale, $group) + { + if ($this->files->exists($full = "{$path}/{$locale}/{$group}.php")) { + return $this->files->getRequire($full); + } + + return []; + } + + /** + * Add a new namespace to the loader. + * + * @param string $namespace + * @param string $hint + * @return void + */ + public function addNamespace($namespace, $hint) + { + $this->hints[$namespace] = $hint; + } +} diff --git a/vendor/illuminate/translation/LoaderInterface.php b/vendor/illuminate/translation/LoaderInterface.php new file mode 100755 index 0000000..9e45572 --- /dev/null +++ b/vendor/illuminate/translation/LoaderInterface.php @@ -0,0 +1,25 @@ +registerLoader(); + + $this->app->singleton('translator', function ($app) { + $loader = $app['translation.loader']; + + // When registering the translator component, we'll need to set the default + // locale as well as the fallback locale. So, we'll grab the application + // configuration so we can easily get both of these values from there. + $locale = $app['config']['app.locale']; + + $trans = new Translator($loader, $locale); + + $trans->setFallback($app['config']['app.fallback_locale']); + + return $trans; + }); + } + + /** + * Register the translation line loader. + * + * @return void + */ + protected function registerLoader() + { + $this->app->singleton('translation.loader', function ($app) { + return new FileLoader($app['files'], $app['path.lang']); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return ['translator', 'translation.loader']; + } +} diff --git a/vendor/illuminate/translation/Translator.php b/vendor/illuminate/translation/Translator.php new file mode 100755 index 0000000..3ac09a4 --- /dev/null +++ b/vendor/illuminate/translation/Translator.php @@ -0,0 +1,367 @@ +loader = $loader; + $this->locale = $locale; + } + + /** + * Determine if a translation exists. + * + * @param string $key + * @param string $locale + * @return bool + */ + public function has($key, $locale = null) + { + return $this->get($key, [], $locale) !== $key; + } + + /** + * Get the translation for the given key. + * + * @param string $key + * @param array $replace + * @param string $locale + * @return string + */ + public function get($key, array $replace = [], $locale = null) + { + list($namespace, $group, $item) = $this->parseKey($key); + + // Here we will get the locale that should be used for the language line. If one + // was not passed, we will use the default locales which was given to us when + // the translator was instantiated. Then, we can load the lines and return. + foreach ($this->parseLocale($locale) as $locale) { + $this->load($namespace, $group, $locale); + + $line = $this->getLine( + $namespace, $group, $locale, $item, $replace + ); + + if (! is_null($line)) { + break; + } + } + + // If the line doesn't exist, we will return back the key which was requested as + // that will be quick to spot in the UI if language keys are wrong or missing + // from the application's language files. Otherwise we can return the line. + if (! isset($line)) { + return $key; + } + + return $line; + } + + /** + * Retrieve a language line out the loaded array. + * + * @param string $namespace + * @param string $group + * @param string $locale + * @param string $item + * @param array $replace + * @return string|array|null + */ + protected function getLine($namespace, $group, $locale, $item, array $replace) + { + $line = Arr::get($this->loaded[$namespace][$group][$locale], $item); + + if (is_string($line)) { + return $this->makeReplacements($line, $replace); + } elseif (is_array($line) && count($line) > 0) { + return $line; + } + } + + /** + * Make the place-holder replacements on a line. + * + * @param string $line + * @param array $replace + * @return string + */ + protected function makeReplacements($line, array $replace) + { + $replace = $this->sortReplacements($replace); + + foreach ($replace as $key => $value) { + $line = str_replace(':'.$key, $value, $line); + } + + return $line; + } + + /** + * Sort the replacements array. + * + * @param array $replace + * @return array + */ + protected function sortReplacements(array $replace) + { + return (new Collection($replace))->sortBy(function ($value, $key) { + return mb_strlen($key) * -1; + }); + } + + /** + * Get a translation according to an integer value. + * + * @param string $key + * @param int $number + * @param array $replace + * @param string $locale + * @return string + */ + public function choice($key, $number, array $replace = [], $locale = null) + { + $line = $this->get($key, $replace, $locale = $locale ?: $this->locale ?: $this->fallback); + + $replace['count'] = $number; + + return $this->makeReplacements($this->getSelector()->choose($line, $number, $locale), $replace); + } + + /** + * Get the translation for a given key. + * + * @param string $id + * @param array $parameters + * @param string $domain + * @param string $locale + * @return string + */ + public function trans($id, array $parameters = [], $domain = 'messages', $locale = null) + { + return $this->get($id, $parameters, $locale); + } + + /** + * Get a translation according to an integer value. + * + * @param string $id + * @param int $number + * @param array $parameters + * @param string $domain + * @param string $locale + * @return string + */ + public function transChoice($id, $number, array $parameters = [], $domain = 'messages', $locale = null) + { + return $this->choice($id, $number, $parameters, $locale); + } + + /** + * Load the specified language group. + * + * @param string $namespace + * @param string $group + * @param string $locale + * @return void + */ + public function load($namespace, $group, $locale) + { + if ($this->isLoaded($namespace, $group, $locale)) { + return; + } + + // The loader is responsible for returning the array of language lines for the + // given namespace, group, and locale. We'll set the lines in this array of + // lines that have already been loaded so that we can easily access them. + $lines = $this->loader->load($locale, $group, $namespace); + + $this->loaded[$namespace][$group][$locale] = $lines; + } + + /** + * Determine if the given group has been loaded. + * + * @param string $namespace + * @param string $group + * @param string $locale + * @return bool + */ + protected function isLoaded($namespace, $group, $locale) + { + return isset($this->loaded[$namespace][$group][$locale]); + } + + /** + * Add a new namespace to the loader. + * + * @param string $namespace + * @param string $hint + * @return void + */ + public function addNamespace($namespace, $hint) + { + $this->loader->addNamespace($namespace, $hint); + } + + /** + * Parse a key into namespace, group, and item. + * + * @param string $key + * @return array + */ + public function parseKey($key) + { + $segments = parent::parseKey($key); + + if (is_null($segments[0])) { + $segments[0] = '*'; + } + + return $segments; + } + + /** + * Get the array of locales to be checked. + * + * @param string|null $locale + * @return array + */ + protected function parseLocale($locale) + { + if (! is_null($locale)) { + return array_filter([$locale, $this->fallback]); + } + + return array_filter([$this->locale, $this->fallback]); + } + + /** + * Get the message selector instance. + * + * @return \Symfony\Component\Translation\MessageSelector + */ + public function getSelector() + { + if (! isset($this->selector)) { + $this->selector = new MessageSelector; + } + + return $this->selector; + } + + /** + * Set the message selector instance. + * + * @param \Symfony\Component\Translation\MessageSelector $selector + * @return void + */ + public function setSelector(MessageSelector $selector) + { + $this->selector = $selector; + } + + /** + * Get the language line loader implementation. + * + * @return \Illuminate\Translation\LoaderInterface + */ + public function getLoader() + { + return $this->loader; + } + + /** + * Get the default locale being used. + * + * @return string + */ + public function locale() + { + return $this->getLocale(); + } + + /** + * Get the default locale being used. + * + * @return string + */ + public function getLocale() + { + return $this->locale; + } + + /** + * Set the default locale. + * + * @param string $locale + * @return void + */ + public function setLocale($locale) + { + $this->locale = $locale; + } + + /** + * Get the fallback locale being used. + * + * @return string + */ + public function getFallback() + { + return $this->fallback; + } + + /** + * Set the fallback locale being used. + * + * @param string $fallback + * @return void + */ + public function setFallback($fallback) + { + $this->fallback = $fallback; + } +} diff --git a/vendor/illuminate/translation/composer.json b/vendor/illuminate/translation/composer.json new file mode 100755 index 0000000..e3e355d --- /dev/null +++ b/vendor/illuminate/translation/composer.json @@ -0,0 +1,33 @@ +{ + "name": "illuminate/translation", + "description": "The Illuminate Translation package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/filesystem": "5.1.*", + "illuminate/support": "5.1.*", + "symfony/translation": "2.7.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Translation\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/validation/DatabasePresenceVerifier.php b/vendor/illuminate/validation/DatabasePresenceVerifier.php new file mode 100755 index 0000000..1704f37 --- /dev/null +++ b/vendor/illuminate/validation/DatabasePresenceVerifier.php @@ -0,0 +1,120 @@ +db = $db; + } + + /** + * Count the number of objects in a collection having the given value. + * + * @param string $collection + * @param string $column + * @param string $value + * @param int $excludeId + * @param string $idColumn + * @param array $extra + * @return int + */ + public function getCount($collection, $column, $value, $excludeId = null, $idColumn = null, array $extra = []) + { + $query = $this->table($collection)->where($column, '=', $value); + + if (! is_null($excludeId) && $excludeId != 'NULL') { + $query->where($idColumn ?: 'id', '<>', $excludeId); + } + + foreach ($extra as $key => $extraValue) { + $this->addWhere($query, $key, $extraValue); + } + + return $query->count(); + } + + /** + * Count the number of objects in a collection with the given values. + * + * @param string $collection + * @param string $column + * @param array $values + * @param array $extra + * @return int + */ + public function getMultiCount($collection, $column, array $values, array $extra = []) + { + $query = $this->table($collection)->whereIn($column, $values); + + foreach ($extra as $key => $extraValue) { + $this->addWhere($query, $key, $extraValue); + } + + return $query->count(); + } + + /** + * Add a "where" clause to the given query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param string $key + * @param string $extraValue + * @return void + */ + protected function addWhere($query, $key, $extraValue) + { + if ($extraValue === 'NULL') { + $query->whereNull($key); + } elseif ($extraValue === 'NOT_NULL') { + $query->whereNotNull($key); + } else { + $query->where($key, $extraValue); + } + } + + /** + * Get a query builder for the given table. + * + * @param string $table + * @return \Illuminate\Database\Query\Builder + */ + protected function table($table) + { + return $this->db->connection($this->connection)->table($table); + } + + /** + * Set the connection to be used. + * + * @param string $connection + * @return void + */ + public function setConnection($connection) + { + $this->connection = $connection; + } +} diff --git a/vendor/illuminate/validation/Factory.php b/vendor/illuminate/validation/Factory.php new file mode 100755 index 0000000..bbc5e22 --- /dev/null +++ b/vendor/illuminate/validation/Factory.php @@ -0,0 +1,241 @@ +container = $container; + $this->translator = $translator; + } + + /** + * Create a new Validator instance. + * + * @param array $data + * @param array $rules + * @param array $messages + * @param array $customAttributes + * @return \Illuminate\Validation\Validator + */ + public function make(array $data, array $rules, array $messages = [], array $customAttributes = []) + { + // The presence verifier is responsible for checking the unique and exists data + // for the validator. It is behind an interface so that multiple versions of + // it may be written besides database. We'll inject it into the validator. + $validator = $this->resolve($data, $rules, $messages, $customAttributes); + + if (! is_null($this->verifier)) { + $validator->setPresenceVerifier($this->verifier); + } + + // Next we'll set the IoC container instance of the validator, which is used to + // resolve out class based validator extensions. If it is not set then these + // types of extensions will not be possible on these validation instances. + if (! is_null($this->container)) { + $validator->setContainer($this->container); + } + + $this->addExtensions($validator); + + return $validator; + } + + /** + * Add the extensions to a validator instance. + * + * @param \Illuminate\Validation\Validator $validator + * @return void + */ + protected function addExtensions(Validator $validator) + { + $validator->addExtensions($this->extensions); + + // Next, we will add the implicit extensions, which are similar to the required + // and accepted rule in that they are run even if the attributes is not in a + // array of data that is given to a validator instances via instantiation. + $implicit = $this->implicitExtensions; + + $validator->addImplicitExtensions($implicit); + + $validator->addReplacers($this->replacers); + + $validator->setFallbackMessages($this->fallbackMessages); + } + + /** + * Resolve a new Validator instance. + * + * @param array $data + * @param array $rules + * @param array $messages + * @param array $customAttributes + * @return \Illuminate\Validation\Validator + */ + protected function resolve(array $data, array $rules, array $messages, array $customAttributes) + { + if (is_null($this->resolver)) { + return new Validator($this->translator, $data, $rules, $messages, $customAttributes); + } + + return call_user_func($this->resolver, $this->translator, $data, $rules, $messages, $customAttributes); + } + + /** + * Register a custom validator extension. + * + * @param string $rule + * @param \Closure|string $extension + * @param string $message + * @return void + */ + public function extend($rule, $extension, $message = null) + { + $this->extensions[$rule] = $extension; + + if ($message) { + $this->fallbackMessages[Str::snake($rule)] = $message; + } + } + + /** + * Register a custom implicit validator extension. + * + * @param string $rule + * @param \Closure|string $extension + * @param string $message + * @return void + */ + public function extendImplicit($rule, $extension, $message = null) + { + $this->implicitExtensions[$rule] = $extension; + + if ($message) { + $this->fallbackMessages[Str::snake($rule)] = $message; + } + } + + /** + * Register a custom implicit validator message replacer. + * + * @param string $rule + * @param \Closure|string $replacer + * @return void + */ + public function replacer($rule, $replacer) + { + $this->replacers[$rule] = $replacer; + } + + /** + * Set the Validator instance resolver. + * + * @param \Closure $resolver + * @return void + */ + public function resolver(Closure $resolver) + { + $this->resolver = $resolver; + } + + /** + * Get the Translator implementation. + * + * @return \Symfony\Component\Translation\TranslatorInterface + */ + public function getTranslator() + { + return $this->translator; + } + + /** + * Get the Presence Verifier implementation. + * + * @return \Illuminate\Validation\PresenceVerifierInterface + */ + public function getPresenceVerifier() + { + return $this->verifier; + } + + /** + * Set the Presence Verifier implementation. + * + * @param \Illuminate\Validation\PresenceVerifierInterface $presenceVerifier + * @return void + */ + public function setPresenceVerifier(PresenceVerifierInterface $presenceVerifier) + { + $this->verifier = $presenceVerifier; + } +} diff --git a/vendor/illuminate/validation/PresenceVerifierInterface.php b/vendor/illuminate/validation/PresenceVerifierInterface.php new file mode 100755 index 0000000..7449629 --- /dev/null +++ b/vendor/illuminate/validation/PresenceVerifierInterface.php @@ -0,0 +1,30 @@ +getValidatorInstance(); + + if (! $this->passesAuthorization()) { + $this->failedAuthorization(); + } elseif (! $instance->passes()) { + $this->failedValidation($instance); + } + } + + /** + * Get the validator instance for the request. + * + * @return \Illuminate\Validation\Validator + */ + protected function getValidatorInstance() + { + return $this->validator(); + } + + /** + * Handle a failed validation attempt. + * + * @param \Illuminate\Validation\Validator $validator + * @return mixed + */ + protected function failedValidation(Validator $validator) + { + throw new ValidationException($validator); + } + + /** + * Determine if the request passes the authorization check. + * + * @return bool + */ + protected function passesAuthorization() + { + if (method_exists($this, 'authorize')) { + return $this->authorize(); + } + + return true; + } + + /** + * Handle a failed authorization attempt. + * + * @return mixed + */ + protected function failedAuthorization() + { + throw new UnauthorizedException; + } +} diff --git a/vendor/illuminate/validation/ValidationServiceProvider.php b/vendor/illuminate/validation/ValidationServiceProvider.php new file mode 100755 index 0000000..5eaf08f --- /dev/null +++ b/vendor/illuminate/validation/ValidationServiceProvider.php @@ -0,0 +1,68 @@ +registerValidationResolverHook(); + + $this->registerPresenceVerifier(); + + $this->registerValidationFactory(); + } + + /** + * Register the "ValidatesWhenResolved" container hook. + * + * @return void + */ + protected function registerValidationResolverHook() + { + $this->app->afterResolving(function (ValidatesWhenResolved $resolved) { + $resolved->validate(); + }); + } + + /** + * Register the validation factory. + * + * @return void + */ + protected function registerValidationFactory() + { + $this->app->singleton('validator', function ($app) { + $validator = new Factory($app['translator'], $app); + + // The validation presence verifier is responsible for determining the existence + // of values in a given data collection, typically a relational database or + // other persistent data stores. And it is used to check for uniqueness. + if (isset($app['validation.presence'])) { + $validator->setPresenceVerifier($app['validation.presence']); + } + + return $validator; + }); + } + + /** + * Register the database presence verifier. + * + * @return void + */ + protected function registerPresenceVerifier() + { + $this->app->singleton('validation.presence', function ($app) { + return new DatabasePresenceVerifier($app['db']); + }); + } +} diff --git a/vendor/illuminate/validation/Validator.php b/vendor/illuminate/validation/Validator.php new file mode 100755 index 0000000..0a1a61e --- /dev/null +++ b/vendor/illuminate/validation/Validator.php @@ -0,0 +1,2639 @@ +translator = $translator; + $this->customMessages = $messages; + $this->data = $this->parseData($data); + $this->rules = $this->explodeRules($rules); + $this->customAttributes = $customAttributes; + } + + /** + * Parse the data and hydrate the files array. + * + * @param array $data + * @param string $arrayKey + * @return array + */ + protected function parseData(array $data, $arrayKey = null) + { + if (is_null($arrayKey)) { + $this->files = []; + } + + foreach ($data as $key => $value) { + $key = ($arrayKey) ? "$arrayKey.$key" : $key; + + // If this value is an instance of the HttpFoundation File class we will + // remove it from the data array and add it to the files array, which + // we use to conveniently separate out these files from other data. + if ($value instanceof File) { + $this->files[$key] = $value; + + unset($data[$key]); + } elseif (is_array($value)) { + $this->parseData($value, $key); + } + } + + return $data; + } + + /** + * Explode the rules into an array of rules. + * + * @param string|array $rules + * @return array + */ + protected function explodeRules($rules) + { + foreach ($rules as $key => &$rule) { + $rule = (is_string($rule)) ? explode('|', $rule) : $rule; + } + + return $rules; + } + + /** + * After an after validation callback. + * + * @param callable|string $callback + * @return $this + */ + public function after($callback) + { + $this->after[] = function () use ($callback) { + return call_user_func_array($callback, [$this]); + }; + + return $this; + } + + /** + * Add conditions to a given field based on a Closure. + * + * @param string $attribute + * @param string|array $rules + * @param callable $callback + * @return void + */ + public function sometimes($attribute, $rules, callable $callback) + { + $payload = new Fluent(array_merge($this->data, $this->files)); + + if (call_user_func($callback, $payload)) { + foreach ((array) $attribute as $key) { + $this->mergeRules($key, $rules); + } + } + } + + /** + * Define a set of rules that apply to each element in an array attribute. + * + * @param string $attribute + * @param string|array $rules + * @return void + * + * @throws \InvalidArgumentException + */ + public function each($attribute, $rules) + { + $data = Arr::get($this->data, $attribute); + + if (! is_array($data)) { + if ($this->hasRule($attribute, 'Array')) { + return; + } + + throw new InvalidArgumentException('Attribute for each() must be an array.'); + } + + foreach ($data as $dataKey => $dataValue) { + foreach ((array) $rules as $ruleKey => $ruleValue) { + if (! is_string($ruleKey)) { + $this->mergeRules("$attribute.$dataKey", $ruleValue); + } else { + $this->mergeRules("$attribute.$dataKey.$ruleKey", $ruleValue); + } + } + } + } + + /** + * Merge additional rules into a given attribute. + * + * @param string $attribute + * @param string|array $rules + * @return void + */ + public function mergeRules($attribute, $rules) + { + $current = isset($this->rules[$attribute]) ? $this->rules[$attribute] : []; + + $merge = head($this->explodeRules([$rules])); + + $this->rules[$attribute] = array_merge($current, $merge); + } + + /** + * Determine if the data passes the validation rules. + * + * @return bool + */ + public function passes() + { + $this->messages = new MessageBag; + + // We'll spin through each rule, validating the attributes attached to that + // rule. Any error messages will be added to the containers with each of + // the other error messages, returning true if we don't have messages. + foreach ($this->rules as $attribute => $rules) { + foreach ($rules as $rule) { + $this->validate($attribute, $rule); + } + } + + // Here we will spin through all of the "after" hooks on this validator and + // fire them off. This gives the callbacks a chance to perform all kinds + // of other validation that needs to get wrapped up in this operation. + foreach ($this->after as $after) { + call_user_func($after); + } + + return count($this->messages->all()) === 0; + } + + /** + * Determine if the data fails the validation rules. + * + * @return bool + */ + public function fails() + { + return ! $this->passes(); + } + + /** + * Validate a given attribute against a rule. + * + * @param string $attribute + * @param string $rule + * @return void + */ + protected function validate($attribute, $rule) + { + list($rule, $parameters) = $this->parseRule($rule); + + if ($rule == '') { + return; + } + + // We will get the value for the given attribute from the array of data and then + // verify that the attribute is indeed validatable. Unless the rule implies + // that the attribute is required, rules are not run for missing values. + $value = $this->getValue($attribute); + + $validatable = $this->isValidatable($rule, $attribute, $value); + + $method = "validate{$rule}"; + + if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) { + $this->addFailure($attribute, $rule, $parameters); + } + } + + /** + * Returns the data which was valid. + * + * @return array + */ + public function valid() + { + if (! $this->messages) { + $this->passes(); + } + + return array_diff_key($this->data, $this->messages()->toArray()); + } + + /** + * Returns the data which was invalid. + * + * @return array + */ + public function invalid() + { + if (! $this->messages) { + $this->passes(); + } + + return array_intersect_key($this->data, $this->messages()->toArray()); + } + + /** + * Get the value of a given attribute. + * + * @param string $attribute + * @return mixed + */ + protected function getValue($attribute) + { + if (! is_null($value = Arr::get($this->data, $attribute))) { + return $value; + } elseif (! is_null($value = Arr::get($this->files, $attribute))) { + return $value; + } + } + + /** + * Determine if the attribute is validatable. + * + * @param string $rule + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function isValidatable($rule, $attribute, $value) + { + return $this->presentOrRuleIsImplicit($rule, $attribute, $value) && + $this->passesOptionalCheck($attribute) && + $this->hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute); + } + + /** + * Determine if the field is present, or the rule implies required. + * + * @param string $rule + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function presentOrRuleIsImplicit($rule, $attribute, $value) + { + return $this->validateRequired($attribute, $value) || $this->isImplicit($rule); + } + + /** + * Determine if the attribute passes any optional check. + * + * @param string $attribute + * @return bool + */ + protected function passesOptionalCheck($attribute) + { + if ($this->hasRule($attribute, ['Sometimes'])) { + return array_key_exists($attribute, Arr::dot($this->data)) + || in_array($attribute, array_keys($this->data)) + || array_key_exists($attribute, $this->files); + } + + return true; + } + + /** + * Determine if a given rule implies the attribute is required. + * + * @param string $rule + * @return bool + */ + protected function isImplicit($rule) + { + return in_array($rule, $this->implicitRules); + } + + /** + * Determine if it's a necessary presence validation. + * + * This is to avoid possible database type comparison errors. + * + * @param string $rule + * @param string $attribute + * @return bool + */ + protected function hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute) + { + return in_array($rule, ['Unique', 'Exists']) + ? ! $this->messages->has($attribute) : true; + } + + /** + * Add a failed rule and error message to the collection. + * + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return void + */ + protected function addFailure($attribute, $rule, $parameters) + { + $this->addError($attribute, $rule, $parameters); + + $this->failedRules[$attribute][$rule] = $parameters; + } + + /** + * Add an error message to the validator's collection of messages. + * + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return void + */ + protected function addError($attribute, $rule, $parameters) + { + $message = $this->getMessage($attribute, $rule); + + $message = $this->doReplacements($message, $attribute, $rule, $parameters); + + $this->messages->add($attribute, $message); + } + + /** + * "Validate" optional attributes. + * + * Always returns true, just lets us put sometimes in rules. + * + * @return bool + */ + protected function validateSometimes() + { + return true; + } + + /** + * Validate that a required attribute exists. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateRequired($attribute, $value) + { + if (is_null($value)) { + return false; + } elseif (is_string($value) && trim($value) === '') { + return false; + } elseif ((is_array($value) || $value instanceof Countable) && count($value) < 1) { + return false; + } elseif ($value instanceof File) { + return (string) $value->getPath() != ''; + } + + return true; + } + + /** + * Validate the given attribute is filled if it is present. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateFilled($attribute, $value) + { + if (array_key_exists($attribute, $this->data) || array_key_exists($attribute, $this->files)) { + return $this->validateRequired($attribute, $value); + } + + return true; + } + + /** + * Determine if any of the given attributes fail the required test. + * + * @param array $attributes + * @return bool + */ + protected function anyFailingRequired(array $attributes) + { + foreach ($attributes as $key) { + if (! $this->validateRequired($key, $this->getValue($key))) { + return true; + } + } + + return false; + } + + /** + * Determine if all of the given attributes fail the required test. + * + * @param array $attributes + * @return bool + */ + protected function allFailingRequired(array $attributes) + { + foreach ($attributes as $key) { + if ($this->validateRequired($key, $this->getValue($key))) { + return false; + } + } + + return true; + } + + /** + * Validate that an attribute exists when any other attribute exists. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + protected function validateRequiredWith($attribute, $value, $parameters) + { + if (! $this->allFailingRequired($parameters)) { + return $this->validateRequired($attribute, $value); + } + + return true; + } + + /** + * Validate that an attribute exists when all other attributes exists. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + protected function validateRequiredWithAll($attribute, $value, $parameters) + { + if (! $this->anyFailingRequired($parameters)) { + return $this->validateRequired($attribute, $value); + } + + return true; + } + + /** + * Validate that an attribute exists when another attribute does not. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + protected function validateRequiredWithout($attribute, $value, $parameters) + { + if ($this->anyFailingRequired($parameters)) { + return $this->validateRequired($attribute, $value); + } + + return true; + } + + /** + * Validate that an attribute exists when all other attributes do not. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + protected function validateRequiredWithoutAll($attribute, $value, $parameters) + { + if ($this->allFailingRequired($parameters)) { + return $this->validateRequired($attribute, $value); + } + + return true; + } + + /** + * Validate that an attribute exists when another attribute has a given value. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + protected function validateRequiredIf($attribute, $value, $parameters) + { + $this->requireParameterCount(2, $parameters, 'required_if'); + + $data = Arr::get($this->data, $parameters[0]); + + $values = array_slice($parameters, 1); + + if (in_array($data, $values)) { + return $this->validateRequired($attribute, $value); + } + + return true; + } + + /** + * Get the number of attributes in a list that are present. + * + * @param array $attributes + * @return int + */ + protected function getPresentCount($attributes) + { + $count = 0; + + foreach ($attributes as $key) { + if (Arr::get($this->data, $key) || Arr::get($this->files, $key)) { + $count++; + } + } + + return $count; + } + + /** + * Validate that an attribute has a matching confirmation. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateConfirmed($attribute, $value) + { + return $this->validateSame($attribute, $value, [$attribute.'_confirmation']); + } + + /** + * Validate that two attributes match. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateSame($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'same'); + + $other = Arr::get($this->data, $parameters[0]); + + return isset($other) && $value === $other; + } + + /** + * Validate that an attribute is different from another attribute. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateDifferent($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'different'); + + $other = Arr::get($this->data, $parameters[0]); + + return isset($other) && $value !== $other; + } + + /** + * Validate that an attribute was "accepted". + * + * This validation rule implies the attribute is "required". + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateAccepted($attribute, $value) + { + $acceptable = ['yes', 'on', '1', 1, true, 'true']; + + return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true); + } + + /** + * Validate that an attribute is an array. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateArray($attribute, $value) + { + return is_array($value); + } + + /** + * Validate that an attribute is a boolean. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateBoolean($attribute, $value) + { + $acceptable = [true, false, 0, 1, '0', '1']; + + return in_array($value, $acceptable, true); + } + + /** + * Validate that an attribute is an integer. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateInteger($attribute, $value) + { + return filter_var($value, FILTER_VALIDATE_INT) !== false; + } + + /** + * Validate that an attribute is numeric. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateNumeric($attribute, $value) + { + return is_numeric($value); + } + + /** + * Validate that an attribute is a string. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateString($attribute, $value) + { + return is_string($value); + } + + /** + * Validate the attribute is a valid JSON string. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateJson($attribute, $value) + { + json_decode($value); + + return json_last_error() === JSON_ERROR_NONE; + } + + /** + * Validate that an attribute has a given number of digits. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateDigits($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'digits'); + + return $this->validateNumeric($attribute, $value) + && strlen((string) $value) == $parameters[0]; + } + + /** + * Validate that an attribute is between a given number of digits. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateDigitsBetween($attribute, $value, $parameters) + { + $this->requireParameterCount(2, $parameters, 'digits_between'); + + $length = strlen((string) $value); + + return $this->validateNumeric($attribute, $value) + && $length >= $parameters[0] && $length <= $parameters[1]; + } + + /** + * Validate the size of an attribute. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateSize($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'size'); + + return $this->getSize($attribute, $value) == $parameters[0]; + } + + /** + * Validate the size of an attribute is between a set of values. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateBetween($attribute, $value, $parameters) + { + $this->requireParameterCount(2, $parameters, 'between'); + + $size = $this->getSize($attribute, $value); + + return $size >= $parameters[0] && $size <= $parameters[1]; + } + + /** + * Validate the size of an attribute is greater than a minimum value. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateMin($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'min'); + + return $this->getSize($attribute, $value) >= $parameters[0]; + } + + /** + * Validate the size of an attribute is less than a maximum value. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateMax($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'max'); + + if ($value instanceof UploadedFile && ! $value->isValid()) { + return false; + } + + return $this->getSize($attribute, $value) <= $parameters[0]; + } + + /** + * Get the size of an attribute. + * + * @param string $attribute + * @param mixed $value + * @return mixed + */ + protected function getSize($attribute, $value) + { + $hasNumeric = $this->hasRule($attribute, $this->numericRules); + + // This method will determine if the attribute is a number, string, or file and + // return the proper size accordingly. If it is a number, then number itself + // is the size. If it is a file, we take kilobytes, and for a string the + // entire length of the string will be considered the attribute size. + if (is_numeric($value) && $hasNumeric) { + return $value; + } elseif (is_array($value)) { + return count($value); + } elseif ($value instanceof File) { + return $value->getSize() / 1024; + } + + return mb_strlen($value); + } + + /** + * Validate an attribute is contained within a list of values. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateIn($attribute, $value, $parameters) + { + if (is_array($value) && $this->hasRule($attribute, 'Array')) { + return count(array_diff($value, $parameters)) == 0; + } + + return ! is_array($value) && in_array((string) $value, $parameters); + } + + /** + * Validate an attribute is not contained within a list of values. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateNotIn($attribute, $value, $parameters) + { + return ! $this->validateIn($attribute, $value, $parameters); + } + + /** + * Validate the uniqueness of an attribute value on a given database table. + * + * If a database column is not specified, the attribute will be used. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateUnique($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'unique'); + + list($connection, $table) = $this->parseTable($parameters[0]); + + // The second parameter position holds the name of the column that needs to + // be verified as unique. If this parameter isn't specified we will just + // assume that this column to be verified shares the attribute's name. + $column = isset($parameters[1]) ? $parameters[1] : $attribute; + + list($idColumn, $id) = [null, null]; + + if (isset($parameters[2])) { + list($idColumn, $id) = $this->getUniqueIds($parameters); + + if (strtolower($id) == 'null') { + $id = null; + } + } + + // The presence verifier is responsible for counting rows within this store + // mechanism which might be a relational database or any other permanent + // data store like Redis, etc. We will use it to determine uniqueness. + $verifier = $this->getPresenceVerifier(); + + if (! is_null($connection)) { + $verifier->setConnection($connection); + } + + $extra = $this->getUniqueExtra($parameters); + + return $verifier->getCount( + + $table, $column, $value, $id, $idColumn, $extra + + ) == 0; + } + + /** + * Parse the connection / table for the unique / exists rules. + * + * @param string $table + * @return array + */ + protected function parseTable($table) + { + return Str::contains($table, '.') ? explode('.', $table, 2) : [null, $table]; + } + + /** + * Get the excluded ID column and value for the unique rule. + * + * @param array $parameters + * @return array + */ + protected function getUniqueIds($parameters) + { + $idColumn = isset($parameters[3]) ? $parameters[3] : 'id'; + + return [$idColumn, $parameters[2]]; + } + + /** + * Get the extra conditions for a unique rule. + * + * @param array $parameters + * @return array + */ + protected function getUniqueExtra($parameters) + { + if (isset($parameters[4])) { + return $this->getExtraConditions(array_slice($parameters, 4)); + } + + return []; + } + + /** + * Validate the existence of an attribute value in a database table. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateExists($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'exists'); + + list($connection, $table) = $this->parseTable($parameters[0]); + + // The second parameter position holds the name of the column that should be + // verified as existing. If this parameter is not specified we will guess + // that the columns being "verified" shares the given attribute's name. + $column = isset($parameters[1]) ? $parameters[1] : $attribute; + + $expected = (is_array($value)) ? count($value) : 1; + + return $this->getExistCount($connection, $table, $column, $value, $parameters) >= $expected; + } + + /** + * Get the number of records that exist in storage. + * + * @param mixed $connection + * @param string $table + * @param string $column + * @param mixed $value + * @param array $parameters + * @return int + */ + protected function getExistCount($connection, $table, $column, $value, $parameters) + { + $verifier = $this->getPresenceVerifier(); + + if (! is_null($connection)) { + $verifier->setConnection($connection); + } + + $extra = $this->getExtraExistConditions($parameters); + + if (is_array($value)) { + return $verifier->getMultiCount($table, $column, $value, $extra); + } + + return $verifier->getCount($table, $column, $value, null, null, $extra); + } + + /** + * Get the extra exist conditions. + * + * @param array $parameters + * @return array + */ + protected function getExtraExistConditions(array $parameters) + { + return $this->getExtraConditions(array_values(array_slice($parameters, 2))); + } + + /** + * Get the extra conditions for a unique / exists rule. + * + * @param array $segments + * @return array + */ + protected function getExtraConditions(array $segments) + { + $extra = []; + + $count = count($segments); + + for ($i = 0; $i < $count; $i = $i + 2) { + $extra[$segments[$i]] = $segments[$i + 1]; + } + + return $extra; + } + + /** + * Validate that an attribute is a valid IP. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateIp($attribute, $value) + { + return filter_var($value, FILTER_VALIDATE_IP) !== false; + } + + /** + * Validate that an attribute is a valid e-mail address. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateEmail($attribute, $value) + { + return filter_var($value, FILTER_VALIDATE_EMAIL) !== false; + } + + /** + * Validate that an attribute is a valid URL. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateUrl($attribute, $value) + { + return filter_var($value, FILTER_VALIDATE_URL) !== false; + } + + /** + * Validate that an attribute is an active URL. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateActiveUrl($attribute, $value) + { + $url = str_replace(['http://', 'https://', 'ftp://'], '', strtolower($value)); + + return checkdnsrr($url, 'A'); + } + + /** + * Validate the MIME type of a file is an image MIME type. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateImage($attribute, $value) + { + return $this->validateMimes($attribute, $value, ['jpeg', 'png', 'gif', 'bmp', 'svg']); + } + + /** + * Validate the guessed extension of a file upload is in a set of file extensions. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateMimes($attribute, $value, $parameters) + { + if (! $this->isAValidFileInstance($value)) { + return false; + } + + return $value->getPath() != '' && in_array($value->guessExtension(), $parameters); + } + + /** + * Validate the MIME type of a file upload attribute is in a set of MIME types. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateMimetypes($attribute, $value, $parameters) + { + if (! $this->isAValidFileInstance($value)) { + return false; + } + + return $value->getPath() != '' && in_array($value->getMimeType(), $parameters); + } + + /** + * Check that the given value is a valid file instance. + * + * @param mixed $value + * @return bool + */ + protected function isAValidFileInstance($value) + { + if ($value instanceof UploadedFile && ! $value->isValid()) { + return false; + } + + return $value instanceof File; + } + + /** + * Validate that an attribute contains only alphabetic characters. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateAlpha($attribute, $value) + { + return is_string($value) && preg_match('/^[\pL\pM]+$/u', $value); + } + + /** + * Validate that an attribute contains only alpha-numeric characters. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateAlphaNum($attribute, $value) + { + if (! is_string($value) && ! is_numeric($value)) { + return false; + } + + return preg_match('/^[\pL\pM\pN]+$/u', $value); + } + + /** + * Validate that an attribute contains only alpha-numeric characters, dashes, and underscores. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateAlphaDash($attribute, $value) + { + if (! is_string($value) && ! is_numeric($value)) { + return false; + } + + return preg_match('/^[\pL\pM\pN_-]+$/u', $value); + } + + /** + * Validate that an attribute passes a regular expression check. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateRegex($attribute, $value, $parameters) + { + if (! is_string($value) && ! is_numeric($value)) { + return false; + } + + $this->requireParameterCount(1, $parameters, 'regex'); + + return preg_match($parameters[0], $value); + } + + /** + * Validate that an attribute is a valid date. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateDate($attribute, $value) + { + if ($value instanceof DateTime) { + return true; + } + + if (strtotime($value) === false) { + return false; + } + + $date = date_parse($value); + + return checkdate($date['month'], $date['day'], $date['year']); + } + + /** + * Validate that an attribute matches a date format. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateDateFormat($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'date_format'); + + $parsed = date_parse_from_format($parameters[0], $value); + + return $parsed['error_count'] === 0 && $parsed['warning_count'] === 0; + } + + /** + * Validate the date is before a given date. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateBefore($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'before'); + + if ($format = $this->getDateFormat($attribute)) { + return $this->validateBeforeWithFormat($format, $value, $parameters); + } + + if (! ($date = strtotime($parameters[0]))) { + return strtotime($value) < strtotime($this->getValue($parameters[0])); + } + + return strtotime($value) < $date; + } + + /** + * Validate the date is before a given date with a given format. + * + * @param string $format + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateBeforeWithFormat($format, $value, $parameters) + { + $param = $this->getValue($parameters[0]) ?: $parameters[0]; + + return $this->checkDateTimeOrder($format, $value, $param); + } + + /** + * Validate the date is after a given date. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateAfter($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'after'); + + if ($format = $this->getDateFormat($attribute)) { + return $this->validateAfterWithFormat($format, $value, $parameters); + } + + if (! ($date = strtotime($parameters[0]))) { + return strtotime($value) > strtotime($this->getValue($parameters[0])); + } + + return strtotime($value) > $date; + } + + /** + * Validate the date is after a given date with a given format. + * + * @param string $format + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validateAfterWithFormat($format, $value, $parameters) + { + $param = $this->getValue($parameters[0]) ?: $parameters[0]; + + return $this->checkDateTimeOrder($format, $param, $value); + } + + /** + * Given two date/time strings, check that one is after the other. + * + * @param string $format + * @param string $before + * @param string $after + * @return bool + */ + protected function checkDateTimeOrder($format, $before, $after) + { + $before = $this->getDateTimeWithOptionalFormat($format, $before); + + $after = $this->getDateTimeWithOptionalFormat($format, $after); + + return ($before && $after) && ($after > $before); + } + + /** + * Get a DateTime instance from a string. + * + * @param string $format + * @param string $value + * @return \DateTime|null + */ + protected function getDateTimeWithOptionalFormat($format, $value) + { + $date = DateTime::createFromFormat($format, $value); + + if ($date) { + return $date; + } + + try { + return new DateTime($value); + } catch (Exception $e) { + // + } + } + + /** + * Validate that an attribute is a valid timezone. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + protected function validateTimezone($attribute, $value) + { + try { + new DateTimeZone($value); + } catch (Exception $e) { + return false; + } + + return true; + } + + /** + * Get the date format for an attribute if it has one. + * + * @param string $attribute + * @return string|null + */ + protected function getDateFormat($attribute) + { + if ($result = $this->getRule($attribute, 'DateFormat')) { + return $result[1][0]; + } + } + + /** + * Get the validation message for an attribute and rule. + * + * @param string $attribute + * @param string $rule + * @return string + */ + protected function getMessage($attribute, $rule) + { + $lowerRule = Str::snake($rule); + + $inlineMessage = $this->getInlineMessage($attribute, $lowerRule); + + // First we will retrieve the custom message for the validation rule if one + // exists. If a custom validation message is being used we'll return the + // custom message, otherwise we'll keep searching for a valid message. + if (! is_null($inlineMessage)) { + return $inlineMessage; + } + + $customKey = "validation.custom.{$attribute}.{$lowerRule}"; + + $customMessage = $this->translator->trans($customKey); + + // First we check for a custom defined validation message for the attribute + // and rule. This allows the developer to specify specific messages for + // only some attributes and rules that need to get specially formed. + if ($customMessage !== $customKey) { + return $customMessage; + } + + // If the rule being validated is a "size" rule, we will need to gather the + // specific error message for the type of attribute being validated such + // as a number, file or string which all have different message types. + elseif (in_array($rule, $this->sizeRules)) { + return $this->getSizeMessage($attribute, $rule); + } + + // Finally, if no developer specified messages have been set, and no other + // special messages apply for this rule, we will just pull the default + // messages out of the translator service for this validation rule. + $key = "validation.{$lowerRule}"; + + if ($key != ($value = $this->translator->trans($key))) { + return $value; + } + + return $this->getInlineMessage( + $attribute, $lowerRule, $this->fallbackMessages + ) ?: $key; + } + + /** + * Get the inline message for a rule if it exists. + * + * @param string $attribute + * @param string $lowerRule + * @param array $source + * @return string|null + */ + protected function getInlineMessage($attribute, $lowerRule, $source = null) + { + $source = $source ?: $this->customMessages; + + $keys = ["{$attribute}.{$lowerRule}", $lowerRule]; + + // First we will check for a custom message for an attribute specific rule + // message for the fields, then we will check for a general custom line + // that is not attribute specific. If we find either we'll return it. + foreach ($keys as $key) { + if (isset($source[$key])) { + return $source[$key]; + } + } + } + + /** + * Get the proper error message for an attribute and size rule. + * + * @param string $attribute + * @param string $rule + * @return string + */ + protected function getSizeMessage($attribute, $rule) + { + $lowerRule = Str::snake($rule); + + // There are three different types of size validations. The attribute may be + // either a number, file, or string so we will check a few things to know + // which type of value it is and return the correct line for that type. + $type = $this->getAttributeType($attribute); + + $key = "validation.{$lowerRule}.{$type}"; + + return $this->translator->trans($key); + } + + /** + * Get the data type of the given attribute. + * + * @param string $attribute + * @return string + */ + protected function getAttributeType($attribute) + { + // We assume that the attributes present in the file array are files so that + // means that if the attribute does not have a numeric rule and the files + // list doesn't have it we'll just consider it a string by elimination. + if ($this->hasRule($attribute, $this->numericRules)) { + return 'numeric'; + } elseif ($this->hasRule($attribute, ['Array'])) { + return 'array'; + } elseif (array_key_exists($attribute, $this->files)) { + return 'file'; + } + + return 'string'; + } + + /** + * Replace all error message place-holders with actual values. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function doReplacements($message, $attribute, $rule, $parameters) + { + $message = str_replace(':attribute', $this->getAttribute($attribute), $message); + + if (isset($this->replacers[Str::snake($rule)])) { + $message = $this->callReplacer($message, $attribute, Str::snake($rule), $parameters); + } elseif (method_exists($this, $replacer = "replace{$rule}")) { + $message = $this->$replacer($message, $attribute, $rule, $parameters); + } + + return $message; + } + + /** + * Transform an array of attributes to their displayable form. + * + * @param array $values + * @return array + */ + protected function getAttributeList(array $values) + { + $attributes = []; + + // For each attribute in the list we will simply get its displayable form as + // this is convenient when replacing lists of parameters like some of the + // replacement functions do when formatting out the validation message. + foreach ($values as $key => $value) { + $attributes[$key] = $this->getAttribute($value); + } + + return $attributes; + } + + /** + * Get the displayable name of the attribute. + * + * @param string $attribute + * @return string + */ + protected function getAttribute($attribute) + { + // The developer may dynamically specify the array of custom attributes + // on this Validator instance. If the attribute exists in this array + // it takes precedence over all other ways we can pull attributes. + if (isset($this->customAttributes[$attribute])) { + return $this->customAttributes[$attribute]; + } + + $key = "validation.attributes.{$attribute}"; + + // We allow for the developer to specify language lines for each of the + // attributes allowing for more displayable counterparts of each of + // the attributes. This provides the ability for simple formats. + if (($line = $this->translator->trans($key)) !== $key) { + return $line; + } + + // If no language line has been specified for the attribute all of the + // underscores are removed from the attribute name and that will be + // used as default versions of the attribute's displayable names. + return str_replace('_', ' ', Str::snake($attribute)); + } + + /** + * Get the displayable name of the value. + * + * @param string $attribute + * @param mixed $value + * @return string + */ + public function getDisplayableValue($attribute, $value) + { + if (isset($this->customValues[$attribute][$value])) { + return $this->customValues[$attribute][$value]; + } + + $key = "validation.values.{$attribute}.{$value}"; + + if (($line = $this->translator->trans($key)) !== $key) { + return $line; + } + + return $value; + } + + /** + * Replace all place-holders for the between rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceBetween($message, $attribute, $rule, $parameters) + { + return str_replace([':min', ':max'], $parameters, $message); + } + + /** + * Replace all place-holders for the digits rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceDigits($message, $attribute, $rule, $parameters) + { + return str_replace(':digits', $parameters[0], $message); + } + + /** + * Replace all place-holders for the digits (between) rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceDigitsBetween($message, $attribute, $rule, $parameters) + { + return $this->replaceBetween($message, $attribute, $rule, $parameters); + } + + /** + * Replace all place-holders for the size rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceSize($message, $attribute, $rule, $parameters) + { + return str_replace(':size', $parameters[0], $message); + } + + /** + * Replace all place-holders for the min rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceMin($message, $attribute, $rule, $parameters) + { + return str_replace(':min', $parameters[0], $message); + } + + /** + * Replace all place-holders for the max rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceMax($message, $attribute, $rule, $parameters) + { + return str_replace(':max', $parameters[0], $message); + } + + /** + * Replace all place-holders for the in rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceIn($message, $attribute, $rule, $parameters) + { + foreach ($parameters as &$parameter) { + $parameter = $this->getDisplayableValue($attribute, $parameter); + } + + return str_replace(':values', implode(', ', $parameters), $message); + } + + /** + * Replace all place-holders for the not_in rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceNotIn($message, $attribute, $rule, $parameters) + { + return $this->replaceIn($message, $attribute, $rule, $parameters); + } + + /** + * Replace all place-holders for the mimes rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceMimes($message, $attribute, $rule, $parameters) + { + return str_replace(':values', implode(', ', $parameters), $message); + } + + /** + * Replace all place-holders for the required_with rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceRequiredWith($message, $attribute, $rule, $parameters) + { + $parameters = $this->getAttributeList($parameters); + + return str_replace(':values', implode(' / ', $parameters), $message); + } + + /** + * Replace all place-holders for the required_with_all rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceRequiredWithAll($message, $attribute, $rule, $parameters) + { + return $this->replaceRequiredWith($message, $attribute, $rule, $parameters); + } + + /** + * Replace all place-holders for the required_without rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceRequiredWithout($message, $attribute, $rule, $parameters) + { + return $this->replaceRequiredWith($message, $attribute, $rule, $parameters); + } + + /** + * Replace all place-holders for the required_without_all rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceRequiredWithoutAll($message, $attribute, $rule, $parameters) + { + return $this->replaceRequiredWith($message, $attribute, $rule, $parameters); + } + + /** + * Replace all place-holders for the required_if rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceRequiredIf($message, $attribute, $rule, $parameters) + { + $parameters[1] = $this->getDisplayableValue($parameters[0], Arr::get($this->data, $parameters[0])); + + $parameters[0] = $this->getAttribute($parameters[0]); + + return str_replace([':other', ':value'], $parameters, $message); + } + + /** + * Replace all place-holders for the same rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceSame($message, $attribute, $rule, $parameters) + { + return str_replace(':other', $this->getAttribute($parameters[0]), $message); + } + + /** + * Replace all place-holders for the different rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceDifferent($message, $attribute, $rule, $parameters) + { + return $this->replaceSame($message, $attribute, $rule, $parameters); + } + + /** + * Replace all place-holders for the date_format rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceDateFormat($message, $attribute, $rule, $parameters) + { + return str_replace(':format', $parameters[0], $message); + } + + /** + * Replace all place-holders for the before rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceBefore($message, $attribute, $rule, $parameters) + { + if (! (strtotime($parameters[0]))) { + return str_replace(':date', $this->getAttribute($parameters[0]), $message); + } + + return str_replace(':date', $parameters[0], $message); + } + + /** + * Replace all place-holders for the after rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceAfter($message, $attribute, $rule, $parameters) + { + return $this->replaceBefore($message, $attribute, $rule, $parameters); + } + + /** + * Determine if the given attribute has a rule in the given set. + * + * @param string $attribute + * @param string|array $rules + * @return bool + */ + protected function hasRule($attribute, $rules) + { + return ! is_null($this->getRule($attribute, $rules)); + } + + /** + * Get a rule and its parameters for a given attribute. + * + * @param string $attribute + * @param string|array $rules + * @return array|null + */ + protected function getRule($attribute, $rules) + { + if (! array_key_exists($attribute, $this->rules)) { + return; + } + + $rules = (array) $rules; + + foreach ($this->rules[$attribute] as $rule) { + list($rule, $parameters) = $this->parseRule($rule); + + if (in_array($rule, $rules)) { + return [$rule, $parameters]; + } + } + } + + /** + * Extract the rule name and parameters from a rule. + * + * @param array|string $rules + * @return array + */ + protected function parseRule($rules) + { + if (is_array($rules)) { + $rules = $this->parseArrayRule($rules); + } else { + $rules = $this->parseStringRule($rules); + } + + $rules[0] = $this->normalizeRule($rules[0]); + + return $rules; + } + + /** + * Parse an array based rule. + * + * @param array $rules + * @return array + */ + protected function parseArrayRule(array $rules) + { + return [Str::studly(trim(Arr::get($rules, 0))), array_slice($rules, 1)]; + } + + /** + * Parse a string based rule. + * + * @param string $rules + * @return array + */ + protected function parseStringRule($rules) + { + $parameters = []; + + // The format for specifying validation rules and parameters follows an + // easy {rule}:{parameters} formatting convention. For instance the + // rule "Max:3" states that the value may only be three letters. + if (strpos($rules, ':') !== false) { + list($rules, $parameter) = explode(':', $rules, 2); + + $parameters = $this->parseParameters($rules, $parameter); + } + + return [Str::studly(trim($rules)), $parameters]; + } + + /** + * Parse a parameter list. + * + * @param string $rule + * @param string $parameter + * @return array + */ + protected function parseParameters($rule, $parameter) + { + if (strtolower($rule) == 'regex') { + return [$parameter]; + } + + return str_getcsv($parameter); + } + + /** + * Normalizes a rule so that we can accept short types. + * + * @param string $rule + * @return string + */ + protected function normalizeRule($rule) + { + switch ($rule) { + case 'Int': + return 'Integer'; + case 'Bool': + return 'Boolean'; + default: + return $rule; + } + } + + /** + * Get the array of custom validator extensions. + * + * @return array + */ + public function getExtensions() + { + return $this->extensions; + } + + /** + * Register an array of custom validator extensions. + * + * @param array $extensions + * @return void + */ + public function addExtensions(array $extensions) + { + if ($extensions) { + $keys = array_map('\Illuminate\Support\Str::snake', array_keys($extensions)); + + $extensions = array_combine($keys, array_values($extensions)); + } + + $this->extensions = array_merge($this->extensions, $extensions); + } + + /** + * Register an array of custom implicit validator extensions. + * + * @param array $extensions + * @return void + */ + public function addImplicitExtensions(array $extensions) + { + $this->addExtensions($extensions); + + foreach ($extensions as $rule => $extension) { + $this->implicitRules[] = Str::studly($rule); + } + } + + /** + * Register a custom validator extension. + * + * @param string $rule + * @param \Closure|string $extension + * @return void + */ + public function addExtension($rule, $extension) + { + $this->extensions[Str::snake($rule)] = $extension; + } + + /** + * Register a custom implicit validator extension. + * + * @param string $rule + * @param \Closure|string $extension + * @return void + */ + public function addImplicitExtension($rule, $extension) + { + $this->addExtension($rule, $extension); + + $this->implicitRules[] = Str::studly($rule); + } + + /** + * Get the array of custom validator message replacers. + * + * @return array + */ + public function getReplacers() + { + return $this->replacers; + } + + /** + * Register an array of custom validator message replacers. + * + * @param array $replacers + * @return void + */ + public function addReplacers(array $replacers) + { + if ($replacers) { + $keys = array_map('\Illuminate\Support\Str::snake', array_keys($replacers)); + + $replacers = array_combine($keys, array_values($replacers)); + } + + $this->replacers = array_merge($this->replacers, $replacers); + } + + /** + * Register a custom validator message replacer. + * + * @param string $rule + * @param \Closure|string $replacer + * @return void + */ + public function addReplacer($rule, $replacer) + { + $this->replacers[Str::snake($rule)] = $replacer; + } + + /** + * Get the data under validation. + * + * @return array + */ + public function getData() + { + return $this->data; + } + + /** + * Set the data under validation. + * + * @param array $data + * @return void + */ + public function setData(array $data) + { + $this->data = $this->parseData($data); + } + + /** + * Get the validation rules. + * + * @return array + */ + public function getRules() + { + return $this->rules; + } + + /** + * Set the validation rules. + * + * @param array $rules + * @return $this + */ + public function setRules(array $rules) + { + $this->rules = $this->explodeRules($rules); + + return $this; + } + + /** + * Set the custom attributes on the validator. + * + * @param array $attributes + * @return $this + */ + public function setAttributeNames(array $attributes) + { + $this->customAttributes = $attributes; + + return $this; + } + + /** + * Set the custom values on the validator. + * + * @param array $values + * @return $this + */ + public function setValueNames(array $values) + { + $this->customValues = $values; + + return $this; + } + + /** + * Get the files under validation. + * + * @return array + */ + public function getFiles() + { + return $this->files; + } + + /** + * Set the files under validation. + * + * @param array $files + * @return $this + */ + public function setFiles(array $files) + { + $this->files = $files; + + return $this; + } + + /** + * Get the Presence Verifier implementation. + * + * @return \Illuminate\Validation\PresenceVerifierInterface + * + * @throws \RuntimeException + */ + public function getPresenceVerifier() + { + if (! isset($this->presenceVerifier)) { + throw new RuntimeException('Presence verifier has not been set.'); + } + + return $this->presenceVerifier; + } + + /** + * Set the Presence Verifier implementation. + * + * @param \Illuminate\Validation\PresenceVerifierInterface $presenceVerifier + * @return void + */ + public function setPresenceVerifier(PresenceVerifierInterface $presenceVerifier) + { + $this->presenceVerifier = $presenceVerifier; + } + + /** + * Get the Translator implementation. + * + * @return \Symfony\Component\Translation\TranslatorInterface + */ + public function getTranslator() + { + return $this->translator; + } + + /** + * Set the Translator implementation. + * + * @param \Symfony\Component\Translation\TranslatorInterface $translator + * @return void + */ + public function setTranslator(TranslatorInterface $translator) + { + $this->translator = $translator; + } + + /** + * Get the custom messages for the validator. + * + * @return array + */ + public function getCustomMessages() + { + return $this->customMessages; + } + + /** + * Set the custom messages for the validator. + * + * @param array $messages + * @return void + */ + public function setCustomMessages(array $messages) + { + $this->customMessages = array_merge($this->customMessages, $messages); + } + + /** + * Get the custom attributes used by the validator. + * + * @return array + */ + public function getCustomAttributes() + { + return $this->customAttributes; + } + + /** + * Add custom attributes to the validator. + * + * @param array $customAttributes + * @return $this + */ + public function addCustomAttributes(array $customAttributes) + { + $this->customAttributes = array_merge($this->customAttributes, $customAttributes); + + return $this; + } + + /** + * Get the custom values for the validator. + * + * @return array + */ + public function getCustomValues() + { + return $this->customValues; + } + + /** + * Add the custom values for the validator. + * + * @param array $customValues + * @return $this + */ + public function addCustomValues(array $customValues) + { + $this->customValues = array_merge($this->customValues, $customValues); + + return $this; + } + + /** + * Get the fallback messages for the validator. + * + * @return array + */ + public function getFallbackMessages() + { + return $this->fallbackMessages; + } + + /** + * Set the fallback messages for the validator. + * + * @param array $messages + * @return void + */ + public function setFallbackMessages(array $messages) + { + $this->fallbackMessages = $messages; + } + + /** + * Get the failed validation rules. + * + * @return array + */ + public function failed() + { + return $this->failedRules; + } + + /** + * Get the message container for the validator. + * + * @return \Illuminate\Support\MessageBag + */ + public function messages() + { + if (! $this->messages) { + $this->passes(); + } + + return $this->messages; + } + + /** + * An alternative more semantic shortcut to the message container. + * + * @return \Illuminate\Support\MessageBag + */ + public function errors() + { + return $this->messages(); + } + + /** + * Get the messages for the instance. + * + * @return \Illuminate\Support\MessageBag + */ + public function getMessageBag() + { + return $this->messages(); + } + + /** + * Set the IoC container instance. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return void + */ + public function setContainer(Container $container) + { + $this->container = $container; + } + + /** + * Call a custom validator extension. + * + * @param string $rule + * @param array $parameters + * @return bool|null + */ + protected function callExtension($rule, $parameters) + { + $callback = $this->extensions[$rule]; + + if ($callback instanceof Closure) { + return call_user_func_array($callback, $parameters); + } elseif (is_string($callback)) { + return $this->callClassBasedExtension($callback, $parameters); + } + } + + /** + * Call a class based validator extension. + * + * @param string $callback + * @param array $parameters + * @return bool + */ + protected function callClassBasedExtension($callback, $parameters) + { + list($class, $method) = explode('@', $callback); + + return call_user_func_array([$this->container->make($class), $method], $parameters); + } + + /** + * Call a custom validator message replacer. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string|null + */ + protected function callReplacer($message, $attribute, $rule, $parameters) + { + $callback = $this->replacers[$rule]; + + if ($callback instanceof Closure) { + return call_user_func_array($callback, func_get_args()); + } elseif (is_string($callback)) { + return $this->callClassBasedReplacer($callback, $message, $attribute, $rule, $parameters); + } + } + + /** + * Call a class based validator message replacer. + * + * @param string $callback + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function callClassBasedReplacer($callback, $message, $attribute, $rule, $parameters) + { + list($class, $method) = explode('@', $callback); + + return call_user_func_array([$this->container->make($class), $method], array_slice(func_get_args(), 1)); + } + + /** + * Require a certain number of parameters to be present. + * + * @param int $count + * @param array $parameters + * @param string $rule + * @return void + * @throws \InvalidArgumentException + */ + protected function requireParameterCount($count, $parameters, $rule) + { + if (count($parameters) < $count) { + throw new InvalidArgumentException("Validation rule $rule requires at least $count parameters."); + } + } + + /** + * Handle dynamic calls to class methods. + * + * @param string $method + * @param array $parameters + * @return mixed + * + * @throws \BadMethodCallException + */ + public function __call($method, $parameters) + { + $rule = Str::snake(substr($method, 8)); + + if (isset($this->extensions[$rule])) { + return $this->callExtension($rule, $parameters); + } + + throw new BadMethodCallException("Method [$method] does not exist."); + } +} diff --git a/vendor/illuminate/validation/composer.json b/vendor/illuminate/validation/composer.json new file mode 100755 index 0000000..3733144 --- /dev/null +++ b/vendor/illuminate/validation/composer.json @@ -0,0 +1,38 @@ +{ + "name": "illuminate/validation", + "description": "The Illuminate Validation package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/support": "5.1.*", + "symfony/http-foundation": "2.7.*", + "symfony/translation": "2.7.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\Validation\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "suggest": { + "illuminate/database": "Required to use the database presence verifier (5.1.*)." + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/view/Compilers/BladeCompiler.php b/vendor/illuminate/view/Compilers/BladeCompiler.php new file mode 100644 index 0000000..bd8eca1 --- /dev/null +++ b/vendor/illuminate/view/Compilers/BladeCompiler.php @@ -0,0 +1,889 @@ +setPath($path); + } + + $contents = $this->compileString($this->files->get($this->getPath())); + + if (! is_null($this->cachePath)) { + $this->files->put($this->getCompiledPath($this->getPath()), $contents); + } + } + + /** + * Get the path currently being compiled. + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * Set the path currently being compiled. + * + * @param string $path + * @return void + */ + public function setPath($path) + { + $this->path = $path; + } + + /** + * Compile the given Blade template contents. + * + * @param string $value + * @return string + */ + public function compileString($value) + { + $result = ''; + + $this->footer = []; + + // Here we will loop through all of the tokens returned by the Zend lexer and + // parse each one into the corresponding valid PHP. We will then have this + // template as the correctly rendered PHP that can be rendered natively. + foreach (token_get_all($value) as $token) { + $result .= is_array($token) ? $this->parseToken($token) : $token; + } + + // If there are any footer lines that need to get added to a template we will + // add them here at the end of the template. This gets used mainly for the + // template inheritance via the extends keyword that should be appended. + if (count($this->footer) > 0) { + $result = ltrim($result, PHP_EOL) + .PHP_EOL.implode(PHP_EOL, array_reverse($this->footer)); + } + + return $result; + } + + /** + * Parse the tokens from the template. + * + * @param array $token + * @return string + */ + protected function parseToken($token) + { + list($id, $content) = $token; + + if ($id == T_INLINE_HTML) { + foreach ($this->compilers as $type) { + $content = $this->{"compile{$type}"}($content); + } + } + + return $content; + } + + /** + * Execute the user defined extensions. + * + * @param string $value + * @return string + */ + protected function compileExtensions($value) + { + foreach ($this->extensions as $compiler) { + $value = call_user_func($compiler, $value, $this); + } + + return $value; + } + + /** + * Compile Blade comments into valid PHP. + * + * @param string $value + * @return string + */ + protected function compileComments($value) + { + $pattern = sprintf('/%s--((.|\s)*?)--%s/', $this->contentTags[0], $this->contentTags[1]); + + return preg_replace($pattern, '', $value); + } + + /** + * Compile Blade echos into valid PHP. + * + * @param string $value + * @return string + */ + protected function compileEchos($value) + { + foreach ($this->getEchoMethods() as $method => $length) { + $value = $this->$method($value); + } + + return $value; + } + + /** + * Get the echo methods in the proper order for compilation. + * + * @return array + */ + protected function getEchoMethods() + { + $methods = [ + 'compileRawEchos' => strlen(stripcslashes($this->rawTags[0])), + 'compileEscapedEchos' => strlen(stripcslashes($this->escapedTags[0])), + 'compileRegularEchos' => strlen(stripcslashes($this->contentTags[0])), + ]; + + uksort($methods, function ($method1, $method2) use ($methods) { + // Ensure the longest tags are processed first + if ($methods[$method1] > $methods[$method2]) { + return -1; + } + if ($methods[$method1] < $methods[$method2]) { + return 1; + } + + // Otherwise give preference to raw tags (assuming they've overridden) + if ($method1 === 'compileRawEchos') { + return -1; + } + if ($method2 === 'compileRawEchos') { + return 1; + } + + if ($method1 === 'compileEscapedEchos') { + return -1; + } + if ($method2 === 'compileEscapedEchos') { + return 1; + } + }); + + return $methods; + } + + /** + * Compile Blade statements that start with "@". + * + * @param string $value + * @return mixed + */ + protected function compileStatements($value) + { + $callback = function ($match) { + if (method_exists($this, $method = 'compile'.ucfirst($match[1]))) { + $match[0] = $this->$method(Arr::get($match, 3)); + } elseif (isset($this->customDirectives[$match[1]])) { + $match[0] = call_user_func($this->customDirectives[$match[1]], Arr::get($match, 3)); + } + + return isset($match[3]) ? $match[0] : $match[0].$match[2]; + }; + + return preg_replace_callback('/\B@(\w+)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', $callback, $value); + } + + /** + * Compile the "raw" echo statements. + * + * @param string $value + * @return string + */ + protected function compileRawEchos($value) + { + $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]); + + $callback = function ($matches) { + $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3]; + + return $matches[1] ? substr($matches[0], 1) : 'compileEchoDefaults($matches[2]).'; ?>'.$whitespace; + }; + + return preg_replace_callback($pattern, $callback, $value); + } + + /** + * Compile the "regular" echo statements. + * + * @param string $value + * @return string + */ + protected function compileRegularEchos($value) + { + $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]); + + $callback = function ($matches) { + $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3]; + + $wrapped = sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2])); + + return $matches[1] ? substr($matches[0], 1) : ''.$whitespace; + }; + + return preg_replace_callback($pattern, $callback, $value); + } + + /** + * Compile the escaped echo statements. + * + * @param string $value + * @return string + */ + protected function compileEscapedEchos($value) + { + $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]); + + $callback = function ($matches) { + $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3]; + + return $matches[1] ? $matches[0] : 'compileEchoDefaults($matches[2]).'); ?>'.$whitespace; + }; + + return preg_replace_callback($pattern, $callback, $value); + } + + /** + * Compile the default values for the echo statement. + * + * @param string $value + * @return string + */ + public function compileEchoDefaults($value) + { + return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s', 'isset($1) ? $1 : $2', $value); + } + + /** + * Compile the each statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEach($expression) + { + return "renderEach{$expression}; ?>"; + } + + /** + * Compile the inject statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileInject($expression) + { + $segments = explode(',', preg_replace("/[\(\)\\\"\']/", '', $expression)); + + return '"; + } + + /** + * Compile the yield statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileYield($expression) + { + return "yieldContent{$expression}; ?>"; + } + + /** + * Compile the show statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileShow($expression) + { + return 'yieldSection(); ?>'; + } + + /** + * Compile the section statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileSection($expression) + { + return "startSection{$expression}; ?>"; + } + + /** + * Compile the append statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileAppend($expression) + { + return 'appendSection(); ?>'; + } + + /** + * Compile the end-section statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndsection($expression) + { + return 'stopSection(); ?>'; + } + + /** + * Compile the stop statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileStop($expression) + { + return 'stopSection(); ?>'; + } + + /** + * Compile the overwrite statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileOverwrite($expression) + { + return 'stopSection(true); ?>'; + } + + /** + * Compile the unless statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileUnless($expression) + { + return ""; + } + + /** + * Compile the end unless statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndunless($expression) + { + return ''; + } + + /** + * Compile the lang statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileLang($expression) + { + return "get$expression; ?>"; + } + + /** + * Compile the choice statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileChoice($expression) + { + return "choice$expression; ?>"; + } + + /** + * Compile the else statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileElse($expression) + { + return ''; + } + + /** + * Compile the for statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileFor($expression) + { + return ""; + } + + /** + * Compile the foreach statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileForeach($expression) + { + return ""; + } + + /** + * Compile the forelse statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileForelse($expression) + { + $empty = '$__empty_'.++$this->forelseCounter; + + return ""; + } + + /** + * Compile the can statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileCan($expression) + { + return ""; + } + + /** + * Compile the cannot statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileCannot($expression) + { + return ""; + } + + /** + * Compile the if statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileIf($expression) + { + return ""; + } + + /** + * Compile the else-if statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileElseif($expression) + { + return ""; + } + + /** + * Compile the forelse statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEmpty($expression) + { + $empty = '$__empty_'.$this->forelseCounter--; + + return ""; + } + + /** + * Compile the while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileWhile($expression) + { + return ""; + } + + /** + * Compile the end-while statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndwhile($expression) + { + return ''; + } + + /** + * Compile the end-for statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndfor($expression) + { + return ''; + } + + /** + * Compile the end-for-each statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndforeach($expression) + { + return ''; + } + + /** + * Compile the end-can statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndcan($expression) + { + return ''; + } + + /** + * Compile the end-cannot statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndcannot($expression) + { + return ''; + } + + /** + * Compile the end-if statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndif($expression) + { + return ''; + } + + /** + * Compile the end-for-else statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndforelse($expression) + { + return ''; + } + + /** + * Compile the extends statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileExtends($expression) + { + if (Str::startsWith($expression, '(')) { + $expression = substr($expression, 1, -1); + } + + $data = "make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>"; + + $this->footer[] = $data; + + return ''; + } + + /** + * Compile the include statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileInclude($expression) + { + if (Str::startsWith($expression, '(')) { + $expression = substr($expression, 1, -1); + } + + return "make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>"; + } + + /** + * Compile the stack statements into the content. + * + * @param string $expression + * @return string + */ + protected function compileStack($expression) + { + return "yieldContent{$expression}; ?>"; + } + + /** + * Compile the push statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compilePush($expression) + { + return "startSection{$expression}; ?>"; + } + + /** + * Compile the endpush statements into valid PHP. + * + * @param string $expression + * @return string + */ + protected function compileEndpush($expression) + { + return 'appendSection(); ?>'; + } + + /** + * Get the extensions used by the compiler. + * + * @return array + */ + public function getExtensions() + { + return $this->extensions; + } + + /** + * Register a custom Blade compiler. + * + * @param callable $compiler + * @return void + */ + public function extend(callable $compiler) + { + $this->extensions[] = $compiler; + } + + /** + * Register a handler for custom directives. + * + * @param string $name + * @param callable $handler + * @return void + */ + public function directive($name, callable $handler) + { + $this->customDirectives[$name] = $handler; + } + + /** + * Get the list of custom directives. + * + * @return array + */ + public function getCustomDirectives() + { + return $this->customDirectives; + } + + /** + * Gets the raw tags used by the compiler. + * + * @return array + */ + public function getRawTags() + { + return $this->rawTags; + } + + /** + * Sets the raw tags used for the compiler. + * + * @param string $openTag + * @param string $closeTag + * @return void + */ + public function setRawTags($openTag, $closeTag) + { + $this->rawTags = [preg_quote($openTag), preg_quote($closeTag)]; + } + + /** + * Sets the content tags used for the compiler. + * + * @param string $openTag + * @param string $closeTag + * @param bool $escaped + * @return void + */ + public function setContentTags($openTag, $closeTag, $escaped = false) + { + $property = ($escaped === true) ? 'escapedTags' : 'contentTags'; + + $this->{$property} = [preg_quote($openTag), preg_quote($closeTag)]; + } + + /** + * Sets the escaped content tags used for the compiler. + * + * @param string $openTag + * @param string $closeTag + * @return void + */ + public function setEscapedContentTags($openTag, $closeTag) + { + $this->setContentTags($openTag, $closeTag, true); + } + + /** + * Gets the content tags used for the compiler. + * + * @return string + */ + public function getContentTags() + { + return $this->getTags(); + } + + /** + * Gets the escaped content tags used for the compiler. + * + * @return string + */ + public function getEscapedContentTags() + { + return $this->getTags(true); + } + + /** + * Gets the tags used for the compiler. + * + * @param bool $escaped + * @return array + */ + protected function getTags($escaped = false) + { + $tags = $escaped ? $this->escapedTags : $this->contentTags; + + return array_map('stripcslashes', $tags); + } + + /** + * Set the echo format to be used by the compiler. + * + * @param string $format + * @return void + */ + public function setEchoFormat($format) + { + $this->echoFormat = $format; + } +} diff --git a/vendor/illuminate/view/Compilers/Compiler.php b/vendor/illuminate/view/Compilers/Compiler.php new file mode 100755 index 0000000..a11a6d5 --- /dev/null +++ b/vendor/illuminate/view/Compilers/Compiler.php @@ -0,0 +1,68 @@ +files = $files; + $this->cachePath = $cachePath; + } + + /** + * Get the path to the compiled version of a view. + * + * @param string $path + * @return string + */ + public function getCompiledPath($path) + { + return $this->cachePath.'/'.md5($path); + } + + /** + * Determine if the view at the given path is expired. + * + * @param string $path + * @return bool + */ + public function isExpired($path) + { + $compiled = $this->getCompiledPath($path); + + // If the compiled file doesn't exist we will indicate that the view is expired + // so that it can be re-compiled. Else, we will verify the last modification + // of the views is less than the modification times of the compiled views. + if (! $this->cachePath || ! $this->files->exists($compiled)) { + return true; + } + + $lastModified = $this->files->lastModified($path); + + return $lastModified >= $this->files->lastModified($compiled); + } +} diff --git a/vendor/illuminate/view/Compilers/CompilerInterface.php b/vendor/illuminate/view/Compilers/CompilerInterface.php new file mode 100755 index 0000000..dfcb023 --- /dev/null +++ b/vendor/illuminate/view/Compilers/CompilerInterface.php @@ -0,0 +1,30 @@ +compiler = $compiler; + } + + /** + * Get the evaluated contents of the view. + * + * @param string $path + * @param array $data + * @return string + */ + public function get($path, array $data = []) + { + $this->lastCompiled[] = $path; + + // If this given view has expired, which means it has simply been edited since + // it was last compiled, we will re-compile the views so we can evaluate a + // fresh copy of the view. We'll pass the compiler the path of the view. + if ($this->compiler->isExpired($path)) { + $this->compiler->compile($path); + } + + $compiled = $this->compiler->getCompiledPath($path); + + // Once we have the path to the compiled file, we will evaluate the paths with + // typical PHP just like any other templates. We also keep a stack of views + // which have been rendered for right exception messages to be generated. + $results = $this->evaluatePath($compiled, $data); + + array_pop($this->lastCompiled); + + return $results; + } + + /** + * Handle a view exception. + * + * @param \Exception $e + * @param int $obLevel + * @return void + * + * @throws $e + */ + protected function handleViewException($e, $obLevel) + { + $e = new ErrorException($this->getMessage($e), 0, 1, $e->getFile(), $e->getLine(), $e); + + parent::handleViewException($e, $obLevel); + } + + /** + * Get the exception message for an exception. + * + * @param \Exception $e + * @return string + */ + protected function getMessage($e) + { + return $e->getMessage().' (View: '.realpath(last($this->lastCompiled)).')'; + } + + /** + * Get the compiler implementation. + * + * @return \Illuminate\View\Compilers\CompilerInterface + */ + public function getCompiler() + { + return $this->compiler; + } +} diff --git a/vendor/illuminate/view/Engines/Engine.php b/vendor/illuminate/view/Engines/Engine.php new file mode 100755 index 0000000..bf5c748 --- /dev/null +++ b/vendor/illuminate/view/Engines/Engine.php @@ -0,0 +1,23 @@ +lastRendered; + } +} diff --git a/vendor/illuminate/view/Engines/EngineInterface.php b/vendor/illuminate/view/Engines/EngineInterface.php new file mode 100755 index 0000000..a6f71d2 --- /dev/null +++ b/vendor/illuminate/view/Engines/EngineInterface.php @@ -0,0 +1,15 @@ +resolved[$engine]); + + $this->resolvers[$engine] = $resolver; + } + + /** + * Resolver an engine instance by name. + * + * @param string $engine + * @return \Illuminate\View\Engines\EngineInterface + * @throws \InvalidArgumentException + */ + public function resolve($engine) + { + if (isset($this->resolved[$engine])) { + return $this->resolved[$engine]; + } + + if (isset($this->resolvers[$engine])) { + return $this->resolved[$engine] = call_user_func($this->resolvers[$engine]); + } + + throw new InvalidArgumentException("Engine $engine not found."); + } +} diff --git a/vendor/illuminate/view/Engines/PhpEngine.php b/vendor/illuminate/view/Engines/PhpEngine.php new file mode 100755 index 0000000..543de6e --- /dev/null +++ b/vendor/illuminate/view/Engines/PhpEngine.php @@ -0,0 +1,69 @@ +evaluatePath($path, $data); + } + + /** + * Get the evaluated contents of the view at the given path. + * + * @param string $__path + * @param array $__data + * @return string + */ + protected function evaluatePath($__path, $__data) + { + $obLevel = ob_get_level(); + + ob_start(); + + extract($__data); + + // We'll evaluate the contents of the view inside a try/catch block so we can + // flush out any stray output that might get out before an error occurs or + // an exception is thrown. This prevents any partial views from leaking. + try { + include $__path; + } catch (Exception $e) { + $this->handleViewException($e, $obLevel); + } catch (Throwable $e) { + $this->handleViewException(new FatalThrowableError($e), $obLevel); + } + + return ltrim(ob_get_clean()); + } + + /** + * Handle a view exception. + * + * @param \Exception $e + * @param int $obLevel + * @return void + * + * @throws $e + */ + protected function handleViewException($e, $obLevel) + { + while (ob_get_level() > $obLevel) { + ob_end_clean(); + } + + throw $e; + } +} diff --git a/vendor/illuminate/view/Expression.php b/vendor/illuminate/view/Expression.php new file mode 100644 index 0000000..4749b23 --- /dev/null +++ b/vendor/illuminate/view/Expression.php @@ -0,0 +1,46 @@ +html = $html; + } + + /** + * Get the the HTML string. + * + * @return string + */ + public function toHtml() + { + return $this->html; + } + + /** + * Get the the HTML string. + * + * @return string + */ + public function __toString() + { + return $this->toHtml(); + } +} diff --git a/vendor/illuminate/view/Factory.php b/vendor/illuminate/view/Factory.php new file mode 100755 index 0000000..c24d757 --- /dev/null +++ b/vendor/illuminate/view/Factory.php @@ -0,0 +1,870 @@ + 'blade', 'php' => 'php']; + + /** + * The view composer events. + * + * @var array + */ + protected $composers = []; + + /** + * All of the finished, captured sections. + * + * @var array + */ + protected $sections = []; + + /** + * The stack of in-progress sections. + * + * @var array + */ + protected $sectionStack = []; + + /** + * The number of active rendering operations. + * + * @var int + */ + protected $renderCount = 0; + + /** + * Create a new view factory instance. + * + * @param \Illuminate\View\Engines\EngineResolver $engines + * @param \Illuminate\View\ViewFinderInterface $finder + * @param \Illuminate\Contracts\Events\Dispatcher $events + * @return void + */ + public function __construct(EngineResolver $engines, ViewFinderInterface $finder, Dispatcher $events) + { + $this->finder = $finder; + $this->events = $events; + $this->engines = $engines; + + $this->share('__env', $this); + } + + /** + * Get the evaluated view contents for the given view. + * + * @param string $path + * @param array $data + * @param array $mergeData + * @return \Illuminate\View\View + */ + public function file($path, $data = [], $mergeData = []) + { + $data = array_merge($mergeData, $this->parseData($data)); + + $this->callCreator($view = new View($this, $this->getEngineFromPath($path), $path, $path, $data)); + + return $view; + } + + /** + * Get the evaluated view contents for the given view. + * + * @param string $view + * @param array $data + * @param array $mergeData + * @return \Illuminate\Contracts\View\View + */ + public function make($view, $data = [], $mergeData = []) + { + if (isset($this->aliases[$view])) { + $view = $this->aliases[$view]; + } + + $view = $this->normalizeName($view); + + $path = $this->finder->find($view); + + $data = array_merge($mergeData, $this->parseData($data)); + + $this->callCreator($view = new View($this, $this->getEngineFromPath($path), $view, $path, $data)); + + return $view; + } + + /** + * Normalize a view name. + * + * @param string $name + * @return string + */ + protected function normalizeName($name) + { + $delimiter = ViewFinderInterface::HINT_PATH_DELIMITER; + + if (strpos($name, $delimiter) === false) { + return str_replace('/', '.', $name); + } + + list($namespace, $name) = explode($delimiter, $name); + + return $namespace.$delimiter.str_replace('/', '.', $name); + } + + /** + * Parse the given data into a raw array. + * + * @param mixed $data + * @return array + */ + protected function parseData($data) + { + return $data instanceof Arrayable ? $data->toArray() : $data; + } + + /** + * Get the evaluated view contents for a named view. + * + * @param string $view + * @param mixed $data + * @return \Illuminate\View\View + */ + public function of($view, $data = []) + { + return $this->make($this->names[$view], $data); + } + + /** + * Register a named view. + * + * @param string $view + * @param string $name + * @return void + */ + public function name($view, $name) + { + $this->names[$name] = $view; + } + + /** + * Add an alias for a view. + * + * @param string $view + * @param string $alias + * @return void + */ + public function alias($view, $alias) + { + $this->aliases[$alias] = $view; + } + + /** + * Determine if a given view exists. + * + * @param string $view + * @return bool + */ + public function exists($view) + { + try { + $this->finder->find($view); + } catch (InvalidArgumentException $e) { + return false; + } + + return true; + } + + /** + * Get the rendered contents of a partial from a loop. + * + * @param string $view + * @param array $data + * @param string $iterator + * @param string $empty + * @return string + */ + public function renderEach($view, $data, $iterator, $empty = 'raw|') + { + $result = ''; + + // If is actually data in the array, we will loop through the data and append + // an instance of the partial view to the final result HTML passing in the + // iterated value of this data array, allowing the views to access them. + if (count($data) > 0) { + foreach ($data as $key => $value) { + $data = ['key' => $key, $iterator => $value]; + + $result .= $this->make($view, $data)->render(); + } + } + + // If there is no data in the array, we will render the contents of the empty + // view. Alternatively, the "empty view" could be a raw string that begins + // with "raw|" for convenience and to let this know that it is a string. + else { + if (Str::startsWith($empty, 'raw|')) { + $result = substr($empty, 4); + } else { + $result = $this->make($empty)->render(); + } + } + + return $result; + } + + /** + * Get the appropriate view engine for the given path. + * + * @param string $path + * @return \Illuminate\View\Engines\EngineInterface + * + * @throws \InvalidArgumentException + */ + public function getEngineFromPath($path) + { + if (! $extension = $this->getExtension($path)) { + throw new InvalidArgumentException("Unrecognized extension in file: $path"); + } + + $engine = $this->extensions[$extension]; + + return $this->engines->resolve($engine); + } + + /** + * Get the extension used by the view file. + * + * @param string $path + * @return string + */ + protected function getExtension($path) + { + $extensions = array_keys($this->extensions); + + return Arr::first($extensions, function ($key, $value) use ($path) { + return Str::endsWith($path, $value); + }); + } + + /** + * Add a piece of shared data to the environment. + * + * @param array|string $key + * @param mixed $value + * @return mixed + */ + public function share($key, $value = null) + { + if (! is_array($key)) { + return $this->shared[$key] = $value; + } + + foreach ($key as $innerKey => $innerValue) { + $this->share($innerKey, $innerValue); + } + } + + /** + * Register a view creator event. + * + * @param array|string $views + * @param \Closure|string $callback + * @return array + */ + public function creator($views, $callback) + { + $creators = []; + + foreach ((array) $views as $view) { + $creators[] = $this->addViewEvent($view, $callback, 'creating: '); + } + + return $creators; + } + + /** + * Register multiple view composers via an array. + * + * @param array $composers + * @return array + */ + public function composers(array $composers) + { + $registered = []; + + foreach ($composers as $callback => $views) { + $registered = array_merge($registered, $this->composer($views, $callback)); + } + + return $registered; + } + + /** + * Register a view composer event. + * + * @param array|string $views + * @param \Closure|string $callback + * @param int|null $priority + * @return array + */ + public function composer($views, $callback, $priority = null) + { + $composers = []; + + foreach ((array) $views as $view) { + $composers[] = $this->addViewEvent($view, $callback, 'composing: ', $priority); + } + + return $composers; + } + + /** + * Add an event for a given view. + * + * @param string $view + * @param \Closure|string $callback + * @param string $prefix + * @param int|null $priority + * @return \Closure|null + */ + protected function addViewEvent($view, $callback, $prefix = 'composing: ', $priority = null) + { + $view = $this->normalizeName($view); + + if ($callback instanceof Closure) { + $this->addEventListener($prefix.$view, $callback, $priority); + + return $callback; + } elseif (is_string($callback)) { + return $this->addClassEvent($view, $callback, $prefix, $priority); + } + } + + /** + * Register a class based view composer. + * + * @param string $view + * @param string $class + * @param string $prefix + * @param int|null $priority + * @return \Closure + */ + protected function addClassEvent($view, $class, $prefix, $priority = null) + { + $name = $prefix.$view; + + // When registering a class based view "composer", we will simply resolve the + // classes from the application IoC container then call the compose method + // on the instance. This allows for convenient, testable view composers. + $callback = $this->buildClassEventCallback($class, $prefix); + + $this->addEventListener($name, $callback, $priority); + + return $callback; + } + + /** + * Add a listener to the event dispatcher. + * + * @param string $name + * @param \Closure $callback + * @param int|null $priority + * @return void + */ + protected function addEventListener($name, $callback, $priority = null) + { + if (is_null($priority)) { + $this->events->listen($name, $callback); + } else { + $this->events->listen($name, $callback, $priority); + } + } + + /** + * Build a class based container callback Closure. + * + * @param string $class + * @param string $prefix + * @return \Closure + */ + protected function buildClassEventCallback($class, $prefix) + { + list($class, $method) = $this->parseClassEvent($class, $prefix); + + // Once we have the class and method name, we can build the Closure to resolve + // the instance out of the IoC container and call the method on it with the + // given arguments that are passed to the Closure as the composer's data. + return function () use ($class, $method) { + $callable = [$this->container->make($class), $method]; + + return call_user_func_array($callable, func_get_args()); + }; + } + + /** + * Parse a class based composer name. + * + * @param string $class + * @param string $prefix + * @return array + */ + protected function parseClassEvent($class, $prefix) + { + if (Str::contains($class, '@')) { + return explode('@', $class); + } + + $method = Str::contains($prefix, 'composing') ? 'compose' : 'create'; + + return [$class, $method]; + } + + /** + * Call the composer for a given view. + * + * @param \Illuminate\View\View $view + * @return void + */ + public function callComposer(View $view) + { + $this->events->fire('composing: '.$view->getName(), [$view]); + } + + /** + * Call the creator for a given view. + * + * @param \Illuminate\View\View $view + * @return void + */ + public function callCreator(View $view) + { + $this->events->fire('creating: '.$view->getName(), [$view]); + } + + /** + * Start injecting content into a section. + * + * @param string $section + * @param string $content + * @return void + */ + public function startSection($section, $content = '') + { + if ($content === '') { + if (ob_start()) { + $this->sectionStack[] = $section; + } + } else { + $this->extendSection($section, $content); + } + } + + /** + * Inject inline content into a section. + * + * @param string $section + * @param string $content + * @return void + */ + public function inject($section, $content) + { + return $this->startSection($section, $content); + } + + /** + * Stop injecting content into a section and return its contents. + * + * @return string + */ + public function yieldSection() + { + return $this->yieldContent($this->stopSection()); + } + + /** + * Stop injecting content into a section. + * + * @param bool $overwrite + * @return string + */ + public function stopSection($overwrite = false) + { + $last = array_pop($this->sectionStack); + + if ($overwrite) { + $this->sections[$last] = ob_get_clean(); + } else { + $this->extendSection($last, ob_get_clean()); + } + + return $last; + } + + /** + * Stop injecting content into a section and append it. + * + * @return string + */ + public function appendSection() + { + $last = array_pop($this->sectionStack); + + if (isset($this->sections[$last])) { + $this->sections[$last] .= ob_get_clean(); + } else { + $this->sections[$last] = ob_get_clean(); + } + + return $last; + } + + /** + * Append content to a given section. + * + * @param string $section + * @param string $content + * @return void + */ + protected function extendSection($section, $content) + { + if (isset($this->sections[$section])) { + $content = str_replace('@parent', $content, $this->sections[$section]); + } + + $this->sections[$section] = $content; + } + + /** + * Get the string contents of a section. + * + * @param string $section + * @param string $default + * @return string + */ + public function yieldContent($section, $default = '') + { + $sectionContent = $default; + + if (isset($this->sections[$section])) { + $sectionContent = $this->sections[$section]; + } + + $sectionContent = str_replace('@@parent', '--parent--holder--', $sectionContent); + + return str_replace( + '--parent--holder--', '@parent', str_replace('@parent', '', $sectionContent) + ); + } + + /** + * Flush all of the section contents. + * + * @return void + */ + public function flushSections() + { + $this->sections = []; + + $this->sectionStack = []; + } + + /** + * Flush all of the section contents if done rendering. + * + * @return void + */ + public function flushSectionsIfDoneRendering() + { + if ($this->doneRendering()) { + $this->flushSections(); + } + } + + /** + * Increment the rendering counter. + * + * @return void + */ + public function incrementRender() + { + $this->renderCount++; + } + + /** + * Decrement the rendering counter. + * + * @return void + */ + public function decrementRender() + { + $this->renderCount--; + } + + /** + * Check if there are no active render operations. + * + * @return bool + */ + public function doneRendering() + { + return $this->renderCount == 0; + } + + /** + * Add a location to the array of view locations. + * + * @param string $location + * @return void + */ + public function addLocation($location) + { + $this->finder->addLocation($location); + } + + /** + * Add a new namespace to the loader. + * + * @param string $namespace + * @param string|array $hints + * @return void + */ + public function addNamespace($namespace, $hints) + { + $this->finder->addNamespace($namespace, $hints); + } + + /** + * Prepend a new namespace to the loader. + * + * @param string $namespace + * @param string|array $hints + * @return void + */ + public function prependNamespace($namespace, $hints) + { + $this->finder->prependNamespace($namespace, $hints); + } + + /** + * Register a valid view extension and its engine. + * + * @param string $extension + * @param string $engine + * @param \Closure $resolver + * @return void + */ + public function addExtension($extension, $engine, $resolver = null) + { + $this->finder->addExtension($extension); + + if (isset($resolver)) { + $this->engines->register($engine, $resolver); + } + + unset($this->extensions[$extension]); + + $this->extensions = array_merge([$extension => $engine], $this->extensions); + } + + /** + * Get the extension to engine bindings. + * + * @return array + */ + public function getExtensions() + { + return $this->extensions; + } + + /** + * Get the engine resolver instance. + * + * @return \Illuminate\View\Engines\EngineResolver + */ + public function getEngineResolver() + { + return $this->engines; + } + + /** + * Get the view finder instance. + * + * @return \Illuminate\View\ViewFinderInterface + */ + public function getFinder() + { + return $this->finder; + } + + /** + * Set the view finder instance. + * + * @param \Illuminate\View\ViewFinderInterface $finder + * @return void + */ + public function setFinder(ViewFinderInterface $finder) + { + $this->finder = $finder; + } + + /** + * Get the event dispatcher instance. + * + * @return \Illuminate\Contracts\Events\Dispatcher + */ + public function getDispatcher() + { + return $this->events; + } + + /** + * Set the event dispatcher instance. + * + * @param \Illuminate\Contracts\Events\Dispatcher $events + * @return void + */ + public function setDispatcher(Dispatcher $events) + { + $this->events = $events; + } + + /** + * Get the IoC container instance. + * + * @return \Illuminate\Contracts\Container\Container + */ + public function getContainer() + { + return $this->container; + } + + /** + * Set the IoC container instance. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return void + */ + public function setContainer(Container $container) + { + $this->container = $container; + } + + /** + * Get an item from the shared data. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function shared($key, $default = null) + { + return Arr::get($this->shared, $key, $default); + } + + /** + * Get all of the shared data for the environment. + * + * @return array + */ + public function getShared() + { + return $this->shared; + } + + /** + * Check if section exists. + * + * @param string $name + * @return bool + */ + public function hasSection($name) + { + return array_key_exists($name, $this->sections); + } + + /** + * Get the entire array of sections. + * + * @return array + */ + public function getSections() + { + return $this->sections; + } + + /** + * Get all of the registered named views in environment. + * + * @return array + */ + public function getNames() + { + return $this->names; + } +} diff --git a/vendor/illuminate/view/FileViewFinder.php b/vendor/illuminate/view/FileViewFinder.php new file mode 100755 index 0000000..ba92bd8 --- /dev/null +++ b/vendor/illuminate/view/FileViewFinder.php @@ -0,0 +1,266 @@ +files = $files; + $this->paths = $paths; + + if (isset($extensions)) { + $this->extensions = $extensions; + } + } + + /** + * Get the fully qualified location of the view. + * + * @param string $name + * @return string + */ + public function find($name) + { + if (isset($this->views[$name])) { + return $this->views[$name]; + } + + if ($this->hasHintInformation($name = trim($name))) { + return $this->views[$name] = $this->findNamedPathView($name); + } + + return $this->views[$name] = $this->findInPaths($name, $this->paths); + } + + /** + * Get the path to a template with a named path. + * + * @param string $name + * @return string + */ + protected function findNamedPathView($name) + { + list($namespace, $view) = $this->getNamespaceSegments($name); + + return $this->findInPaths($view, $this->hints[$namespace]); + } + + /** + * Get the segments of a template with a named path. + * + * @param string $name + * @return array + * + * @throws \InvalidArgumentException + */ + protected function getNamespaceSegments($name) + { + $segments = explode(static::HINT_PATH_DELIMITER, $name); + + if (count($segments) != 2) { + throw new InvalidArgumentException("View [$name] has an invalid name."); + } + + if (! isset($this->hints[$segments[0]])) { + throw new InvalidArgumentException("No hint path defined for [{$segments[0]}]."); + } + + return $segments; + } + + /** + * Find the given view in the list of paths. + * + * @param string $name + * @param array $paths + * @return string + * + * @throws \InvalidArgumentException + */ + protected function findInPaths($name, $paths) + { + foreach ((array) $paths as $path) { + foreach ($this->getPossibleViewFiles($name) as $file) { + if ($this->files->exists($viewPath = $path.'/'.$file)) { + return $viewPath; + } + } + } + + throw new InvalidArgumentException("View [$name] not found."); + } + + /** + * Get an array of possible view files. + * + * @param string $name + * @return array + */ + protected function getPossibleViewFiles($name) + { + return array_map(function ($extension) use ($name) { + return str_replace('.', '/', $name).'.'.$extension; + + }, $this->extensions); + } + + /** + * Add a location to the finder. + * + * @param string $location + * @return void + */ + public function addLocation($location) + { + $this->paths[] = $location; + } + + /** + * Add a namespace hint to the finder. + * + * @param string $namespace + * @param string|array $hints + * @return void + */ + public function addNamespace($namespace, $hints) + { + $hints = (array) $hints; + + if (isset($this->hints[$namespace])) { + $hints = array_merge($this->hints[$namespace], $hints); + } + + $this->hints[$namespace] = $hints; + } + + /** + * Prepend a namespace hint to the finder. + * + * @param string $namespace + * @param string|array $hints + * @return void + */ + public function prependNamespace($namespace, $hints) + { + $hints = (array) $hints; + + if (isset($this->hints[$namespace])) { + $hints = array_merge($hints, $this->hints[$namespace]); + } + + $this->hints[$namespace] = $hints; + } + + /** + * Register an extension with the view finder. + * + * @param string $extension + * @return void + */ + public function addExtension($extension) + { + if (($index = array_search($extension, $this->extensions)) !== false) { + unset($this->extensions[$index]); + } + + array_unshift($this->extensions, $extension); + } + + /** + * Returns whether or not the view specify a hint information. + * + * @param string $name + * @return bool + */ + public function hasHintInformation($name) + { + return strpos($name, static::HINT_PATH_DELIMITER) > 0; + } + + /** + * Get the filesystem instance. + * + * @return \Illuminate\Filesystem\Filesystem + */ + public function getFilesystem() + { + return $this->files; + } + + /** + * Get the active view paths. + * + * @return array + */ + public function getPaths() + { + return $this->paths; + } + + /** + * Get the namespace to file path hints. + * + * @return array + */ + public function getHints() + { + return $this->hints; + } + + /** + * Get registered extensions. + * + * @return array + */ + public function getExtensions() + { + return $this->extensions; + } +} diff --git a/vendor/illuminate/view/Middleware/ShareErrorsFromSession.php b/vendor/illuminate/view/Middleware/ShareErrorsFromSession.php new file mode 100644 index 0000000..812cf61 --- /dev/null +++ b/vendor/illuminate/view/Middleware/ShareErrorsFromSession.php @@ -0,0 +1,51 @@ +view = $view; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next) + { + // If the current session has an "errors" variable bound to it, we will share + // its value with all view instances so the views can easily access errors + // without having to bind. An empty bag is set when there aren't errors. + $this->view->share( + 'errors', $request->session()->get('errors', new ViewErrorBag) + ); + + // Putting the errors in the view for every view allows the developer to just + // assume that some errors are always available, which is convenient since + // they don't have to continually run checks for the presence of errors. + + return $next($request); + } +} diff --git a/vendor/illuminate/view/View.php b/vendor/illuminate/view/View.php new file mode 100755 index 0000000..b0aa9a7 --- /dev/null +++ b/vendor/illuminate/view/View.php @@ -0,0 +1,392 @@ +view = $view; + $this->path = $path; + $this->engine = $engine; + $this->factory = $factory; + + $this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data; + } + + /** + * Get the string contents of the view. + * + * @param callable|null $callback + * @return string + */ + public function render(callable $callback = null) + { + $contents = $this->renderContents(); + + $response = isset($callback) ? call_user_func($callback, $this, $contents) : null; + + // Once we have the contents of the view, we will flush the sections if we are + // done rendering all views so that there is nothing left hanging over when + // another view gets rendered in the future by the application developer. + $this->factory->flushSectionsIfDoneRendering(); + + return ! is_null($response) ? $response : $contents; + } + + /** + * Get the contents of the view instance. + * + * @return string + */ + protected function renderContents() + { + // We will keep track of the amount of views being rendered so we can flush + // the section after the complete rendering operation is done. This will + // clear out the sections for any separate views that may be rendered. + $this->factory->incrementRender(); + + $this->factory->callComposer($this); + + $contents = $this->getContents(); + + // Once we've finished rendering the view, we'll decrement the render count + // so that each sections get flushed out next time a view is created and + // no old sections are staying around in the memory of an environment. + $this->factory->decrementRender(); + + return $contents; + } + + /** + * Get the sections of the rendered view. + * + * @return array + */ + public function renderSections() + { + return $this->render(function () { + return $this->factory->getSections(); + }); + } + + /** + * Get the evaluated contents of the view. + * + * @return string + */ + protected function getContents() + { + return $this->engine->get($this->path, $this->gatherData()); + } + + /** + * Get the data bound to the view instance. + * + * @return array + */ + protected function gatherData() + { + $data = array_merge($this->factory->getShared(), $this->data); + + foreach ($data as $key => $value) { + if ($value instanceof Renderable) { + $data[$key] = $value->render(); + } + } + + return $data; + } + + /** + * Add a piece of data to the view. + * + * @param string|array $key + * @param mixed $value + * @return $this + */ + public function with($key, $value = null) + { + if (is_array($key)) { + $this->data = array_merge($this->data, $key); + } else { + $this->data[$key] = $value; + } + + return $this; + } + + /** + * Add a view instance to the view data. + * + * @param string $key + * @param string $view + * @param array $data + * @return $this + */ + public function nest($key, $view, array $data = []) + { + return $this->with($key, $this->factory->make($view, $data)); + } + + /** + * Add validation errors to the view. + * + * @param \Illuminate\Contracts\Support\MessageProvider|array $provider + * @return $this + */ + public function withErrors($provider) + { + if ($provider instanceof MessageProvider) { + $this->with('errors', $provider->getMessageBag()); + } else { + $this->with('errors', new MessageBag((array) $provider)); + } + + return $this; + } + + /** + * Get the view factory instance. + * + * @return \Illuminate\View\Factory + */ + public function getFactory() + { + return $this->factory; + } + + /** + * Get the view's rendering engine. + * + * @return \Illuminate\View\Engines\EngineInterface + */ + public function getEngine() + { + return $this->engine; + } + + /** + * Get the name of the view. + * + * @return string + */ + public function name() + { + return $this->getName(); + } + + /** + * Get the name of the view. + * + * @return string + */ + public function getName() + { + return $this->view; + } + + /** + * Get the array of view data. + * + * @return array + */ + public function getData() + { + return $this->data; + } + + /** + * Get the path to the view file. + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * Set the path to the view. + * + * @param string $path + * @return void + */ + public function setPath($path) + { + $this->path = $path; + } + + /** + * Determine if a piece of data is bound. + * + * @param string $key + * @return bool + */ + public function offsetExists($key) + { + return array_key_exists($key, $this->data); + } + + /** + * Get a piece of bound data to the view. + * + * @param string $key + * @return mixed + */ + public function offsetGet($key) + { + return $this->data[$key]; + } + + /** + * Set a piece of data on the view. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + $this->with($key, $value); + } + + /** + * Unset a piece of data from the view. + * + * @param string $key + * @return void + */ + public function offsetUnset($key) + { + unset($this->data[$key]); + } + + /** + * Get a piece of data from the view. + * + * @param string $key + * @return mixed + */ + public function &__get($key) + { + return $this->data[$key]; + } + + /** + * Set a piece of data on the view. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function __set($key, $value) + { + $this->with($key, $value); + } + + /** + * Check if a piece of data is bound to the view. + * + * @param string $key + * @return bool + */ + public function __isset($key) + { + return isset($this->data[$key]); + } + + /** + * Remove a piece of bound data from the view. + * + * @param string $key + * @return bool + */ + public function __unset($key) + { + unset($this->data[$key]); + } + + /** + * Dynamically bind parameters to the view. + * + * @param string $method + * @param array $parameters + * @return \Illuminate\View\View + * + * @throws \BadMethodCallException + */ + public function __call($method, $parameters) + { + if (Str::startsWith($method, 'with')) { + return $this->with(Str::snake(substr($method, 4)), $parameters[0]); + } + + throw new BadMethodCallException("Method [$method] does not exist on view."); + } + + /** + * Get the string contents of the view. + * + * @return string + */ + public function __toString() + { + return $this->render(); + } +} diff --git a/vendor/illuminate/view/ViewFinderInterface.php b/vendor/illuminate/view/ViewFinderInterface.php new file mode 100755 index 0000000..4af1f9d --- /dev/null +++ b/vendor/illuminate/view/ViewFinderInterface.php @@ -0,0 +1,55 @@ +registerEngineResolver(); + + $this->registerViewFinder(); + + $this->registerFactory(); + } + + /** + * Register the engine resolver instance. + * + * @return void + */ + public function registerEngineResolver() + { + $this->app->singleton('view.engine.resolver', function () { + $resolver = new EngineResolver; + + // Next we will register the various engines with the resolver so that the + // environment can resolve the engines it needs for various views based + // on the extension of view files. We call a method for each engines. + foreach (['php', 'blade'] as $engine) { + $this->{'register'.ucfirst($engine).'Engine'}($resolver); + } + + return $resolver; + }); + } + + /** + * Register the PHP engine implementation. + * + * @param \Illuminate\View\Engines\EngineResolver $resolver + * @return void + */ + public function registerPhpEngine($resolver) + { + $resolver->register('php', function () { return new PhpEngine; }); + } + + /** + * Register the Blade engine implementation. + * + * @param \Illuminate\View\Engines\EngineResolver $resolver + * @return void + */ + public function registerBladeEngine($resolver) + { + $app = $this->app; + + // The Compiler engine requires an instance of the CompilerInterface, which in + // this case will be the Blade compiler, so we'll first create the compiler + // instance to pass into the engine so it can compile the views properly. + $app->singleton('blade.compiler', function ($app) { + $cache = $app['config']['view.compiled']; + + return new BladeCompiler($app['files'], $cache); + }); + + $resolver->register('blade', function () use ($app) { + return new CompilerEngine($app['blade.compiler']); + }); + } + + /** + * Register the view finder implementation. + * + * @return void + */ + public function registerViewFinder() + { + $this->app->bind('view.finder', function ($app) { + $paths = $app['config']['view.paths']; + + return new FileViewFinder($app['files'], $paths); + }); + } + + /** + * Register the view environment. + * + * @return void + */ + public function registerFactory() + { + $this->app->singleton('view', function ($app) { + // Next we need to grab the engine resolver instance that will be used by the + // environment. The resolver will be used by an environment to get each of + // the various engine implementations such as plain PHP or Blade engine. + $resolver = $app['view.engine.resolver']; + + $finder = $app['view.finder']; + + $env = new Factory($resolver, $finder, $app['events']); + + // We will also set the container instance on this view environment since the + // view composers may be classes registered in the container, which allows + // for great testable, flexible composers for the application developer. + $env->setContainer($app); + + $env->share('app', $app); + + return $env; + }); + } +} diff --git a/vendor/illuminate/view/composer.json b/vendor/illuminate/view/composer.json new file mode 100755 index 0000000..c9c8f1a --- /dev/null +++ b/vendor/illuminate/view/composer.json @@ -0,0 +1,35 @@ +{ + "name": "illuminate/view", + "description": "The Illuminate View package.", + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/events": "5.1.*", + "illuminate/filesystem": "5.1.*", + "illuminate/support": "5.1.*" + }, + "autoload": { + "psr-4": { + "Illuminate\\View\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "minimum-stability": "dev" +} diff --git a/vendor/laravel/lumen-framework/.gitignore b/vendor/laravel/lumen-framework/.gitignore new file mode 100644 index 0000000..f1223d1 --- /dev/null +++ b/vendor/laravel/lumen-framework/.gitignore @@ -0,0 +1,4 @@ +/lumen.log +/vendor +composer.lock +.env diff --git a/vendor/laravel/lumen-framework/.travis.yml b/vendor/laravel/lumen-framework/.travis.yml new file mode 100644 index 0000000..087594f --- /dev/null +++ b/vendor/laravel/lumen-framework/.travis.yml @@ -0,0 +1,14 @@ +language: php + +php: + - 5.5.9 + - 5.5 + - 5.6 + - 7.0 + - hhvm + +sudo: false + +install: travis_retry composer install --no-interaction --prefer-source + +script: vendor/bin/phpunit diff --git a/vendor/laravel/lumen-framework/LICENSE.txt b/vendor/laravel/lumen-framework/LICENSE.txt new file mode 100644 index 0000000..1ce5963 --- /dev/null +++ b/vendor/laravel/lumen-framework/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/laravel/lumen-framework/composer.json b/vendor/laravel/lumen-framework/composer.json new file mode 100644 index 0000000..6616ac1 --- /dev/null +++ b/vendor/laravel/lumen-framework/composer.json @@ -0,0 +1,70 @@ +{ + "name": "laravel/lumen-framework", + "description": "The Laravel Lumen Framework.", + "keywords": ["framework", "laravel", "lumen"], + "license": "MIT", + "homepage": "http://laravel.com", + "support": { + "issues": "https://github.com/laravel/lumen-framework/issues", + "source": "https://github.com/laravel/lumen-framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "require": { + "php": ">=5.5.9", + "illuminate/auth": "5.1.*", + "illuminate/bus": "5.1.*", + "illuminate/broadcasting": "5.1.*", + "illuminate/config": "5.1.*", + "illuminate/container": "5.1.*", + "illuminate/contracts": "5.1.*", + "illuminate/cache": "5.1.*", + "illuminate/console": "5.1.*", + "illuminate/cookie": "5.1.*", + "illuminate/database": "5.1.*", + "illuminate/encryption": "5.1.*", + "illuminate/events": "5.1.*", + "illuminate/filesystem": "5.1.*", + "illuminate/hashing": "5.1.*", + "illuminate/http": "5.1.*", + "illuminate/pagination": "5.1.*", + "illuminate/queue": "5.1.*", + "illuminate/session": "5.1.*", + "illuminate/support": "5.1.*", + "illuminate/translation": "5.1.*", + "illuminate/validation": "5.1.*", + "illuminate/view": "5.1.*", + "monolog/monolog": "~1.0", + "mtdowling/cron-expression": "~1.0", + "nikic/fast-route": "0.4.*", + "paragonie/random_compat": "^1.0.6", + "symfony/dom-crawler": "2.7.*", + "symfony/http-kernel": "2.7.*", + "symfony/http-foundation": "2.7.*", + "symfony/security-core": "2.7.*", + "symfony/var-dumper": "2.7.*" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "mockery/mockery": "~0.9" + }, + "suggest": { + "vlucas/phpdotenv": "Required to use .env files (~1.0)." + }, + "autoload": { + "psr-4": { + "Laravel\\Lumen\\": "src/" + }, + "classmap": [ + "src/Foundation" + ], + "files": [ + "src/helpers.php" + ] + }, + "minimum-stability": "dev" +} diff --git a/vendor/laravel/lumen-framework/config/app.php b/vendor/laravel/lumen-framework/config/app.php new file mode 100644 index 0000000..bed4dc2 --- /dev/null +++ b/vendor/laravel/lumen-framework/config/app.php @@ -0,0 +1,46 @@ + env('APP_KEY', 'SomeRandomString!!!'), + + 'cipher' => 'AES-256-CBC', + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by the translation service provider. You are free to set this value + | to any of the locales which will be supported by the application. + | + */ + + 'locale' => env('APP_LOCALE', 'en'), + + /* + |-------------------------------------------------------------------------- + | Application Fallback Locale + |-------------------------------------------------------------------------- + | + | The fallback locale determines the locale to use when the current one + | is not available. You may change the value to correspond to any of + | the language folders that are provided through your application. + | + */ + + 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), + +]; diff --git a/vendor/laravel/lumen-framework/config/auth.php b/vendor/laravel/lumen-framework/config/auth.php new file mode 100644 index 0000000..cc6f6be --- /dev/null +++ b/vendor/laravel/lumen-framework/config/auth.php @@ -0,0 +1,67 @@ + env('AUTH_DRIVER', 'eloquent'), + + /* + |-------------------------------------------------------------------------- + | Authentication Model + |-------------------------------------------------------------------------- + | + | When using the "Eloquent" authentication driver, we need to know which + | Eloquent model should be used to retrieve your users. Of course, it + | is often just the "User" model but you may use whatever you like. + | + */ + + 'model' => env('AUTH_MODEL', 'App\User'), + + /* + |-------------------------------------------------------------------------- + | Authentication Table + |-------------------------------------------------------------------------- + | + | When using the "Database" authentication driver, we need to know which + | table should be used to retrieve your users. We have chosen a basic + | default value but you may easily change it to any table you like. + | + */ + + 'table' => env('AUTH_TABLE', 'users'), + + /* + |-------------------------------------------------------------------------- + | Password Reset Settings + |-------------------------------------------------------------------------- + | + | Here you may set the options for resetting passwords including the view + | that is your password reset e-mail. You can also set the name of the + | table that maintains all of the reset tokens for your application. + | + | The expire time is the number of minutes that the reset token should be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + */ + + 'password' => [ + 'email' => 'emails.password', + 'table' => 'password_resets', + 'expire' => 60, + ], + +]; diff --git a/vendor/laravel/lumen-framework/config/broadcasting.php b/vendor/laravel/lumen-framework/config/broadcasting.php new file mode 100644 index 0000000..36f9b3c --- /dev/null +++ b/vendor/laravel/lumen-framework/config/broadcasting.php @@ -0,0 +1,49 @@ + env('BROADCAST_DRIVER', 'pusher'), + + /* + |-------------------------------------------------------------------------- + | Broadcast Connections + |-------------------------------------------------------------------------- + | + | Here you may define all of the broadcast connections that will be used + | to broadcast events to other systems or over websockets. Samples of + | each available type of connection are provided inside this array. + | + */ + + 'connections' => [ + + 'pusher' => [ + 'driver' => 'pusher', + 'key' => env('PUSHER_KEY'), + 'secret' => env('PUSHER_SECRET'), + 'app_id' => env('PUSHER_APP_ID'), + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + 'log' => [ + 'driver' => 'log', + ], + + ], + +]; diff --git a/vendor/laravel/lumen-framework/config/cache.php b/vendor/laravel/lumen-framework/config/cache.php new file mode 100644 index 0000000..9aa5651 --- /dev/null +++ b/vendor/laravel/lumen-framework/config/cache.php @@ -0,0 +1,75 @@ + env('CACHE_DRIVER', 'memcached'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + */ + + 'stores' => [ + + 'array' => [ + 'driver' => 'array', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => env('CACHE_DATABASE_TABLE', 'cache'), + 'connection' => null, + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 'port' => env('MEMCACHED_PORT', 11211), 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing a RAM based store such as APC or Memcached, there might + | be other applications utilizing the same cache. So, we'll specify a + | value to get prefixed to all our keys so we can avoid collisions. + | + */ + + 'prefix' => 'laravel', + +]; diff --git a/vendor/laravel/lumen-framework/config/database.php b/vendor/laravel/lumen-framework/config/database.php new file mode 100644 index 0000000..7bbccf3 --- /dev/null +++ b/vendor/laravel/lumen-framework/config/database.php @@ -0,0 +1,134 @@ + PDO::FETCH_CLASS, + + /* + |-------------------------------------------------------------------------- + | Default Database Connection Name + |-------------------------------------------------------------------------- + | + | Here you may specify which of the database connections below you wish + | to use as your default connection for all database work. Of course + | you may use many connections at once using the Database library. + | + */ + + 'default' => env('DB_CONNECTION', 'mysql'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Here are each of the database connections setup for your application. + | Of course, examples of configuring each database platform that is + | supported by Laravel is shown below to make development simple. + | + | + | All database work in Laravel is done through the PHP PDO facilities + | so make sure you have the driver for your particular database of + | choice installed on your machine before you begin development. + | + */ + + 'connections' => [ + + 'testing' => [ + 'driver' => 'sqlite', + 'database' => ':memory:', + ], + + 'sqlite' => [ + 'driver' => 'sqlite', + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => env('DB_PREFIX', ''), + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', 3306), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => env('DB_PREFIX', ''), + 'timezone' => env('DB_TIMEZONE', '+00:00'), + 'strict' => false, + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', 5432), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => env('DB_PREFIX', ''), + 'schema' => 'public', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'host' => env('DB_HOST', 'localhost'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'prefix' => env('DB_PREFIX', ''), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run in the database. + | + */ + + 'migrations' => 'migrations', + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer set of commands than a typical key-value systems + | such as APC or Memcached. Laravel makes it easy to dig right in. + | + */ + + 'redis' => [ + + 'cluster' => env('REDIS_CLUSTER', false), + + 'default' => [ + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'port' => env('REDIS_PORT', 6379), + 'database' => env('REDIS_DATABASE', 0), + 'password' => env('REDIS_PASSWORD', null), + ], + + ], + +]; diff --git a/vendor/laravel/lumen-framework/config/filesystems.php b/vendor/laravel/lumen-framework/config/filesystems.php new file mode 100644 index 0000000..688db06 --- /dev/null +++ b/vendor/laravel/lumen-framework/config/filesystems.php @@ -0,0 +1,72 @@ + env('FILESYSTEM_DRIVER', 'local'), + + /* + |-------------------------------------------------------------------------- + | Default Cloud Filesystem Disk + |-------------------------------------------------------------------------- + | + | Many applications store files both locally and in the cloud. For this + | reason, you may specify a default "cloud" driver here. This driver + | will be bound as the Cloud disk implementation in the container. + | + */ + + 'cloud' => env('FILESYSTEM_CLOUD', 's3'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been setup for each driver as an example of the required options. + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('S3_KEY'), + 'secret' => env('S3_SECRET'), + 'region' => env('S3_REGION'), + 'bucket' => env('S3_BUCKET'), + 'base_url' => env('S3_URL'), + ], + + 'rackspace' => [ + 'driver' => 'rackspace', + 'username' => env('RACKSPACE_USERNAME'), + 'key' => env('RACKSPACE_KEY'), + 'container' => env('RACKSPACE_CONTAINER'), + 'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/', + 'region' => env('RACKSPACE_REGION'), + 'url_type' => 'publicURL', + ], + + ], + +]; diff --git a/vendor/laravel/lumen-framework/config/mail.php b/vendor/laravel/lumen-framework/config/mail.php new file mode 100644 index 0000000..1dd5d9f --- /dev/null +++ b/vendor/laravel/lumen-framework/config/mail.php @@ -0,0 +1,124 @@ + env('MAIL_DRIVER', 'smtp'), + + /* + |-------------------------------------------------------------------------- + | SMTP Host Address + |-------------------------------------------------------------------------- + | + | Here you may provide the host address of the SMTP server used by your + | applications. A default option is provided that is compatible with + | the Mailgun mail service which will provide reliable deliveries. + | + */ + + 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), + + /* + |-------------------------------------------------------------------------- + | SMTP Host Port + |-------------------------------------------------------------------------- + | + | This is the SMTP port used by your application to deliver e-mails to + | users of the application. Like the host we have set this value to + | stay compatible with the Mailgun e-mail application by default. + | + */ + + 'port' => env('MAIL_PORT', 587), + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all e-mails sent by your application to be sent from + | the same address. Here, you may specify a name and address that is + | used globally for all e-mails that are sent by your application. + | + */ + + 'from' => ['address' => env('MAIL_FROM_ADDRESS'), 'name' => env('MAIL_FROM_NAME')], + + /* + |-------------------------------------------------------------------------- + | E-Mail Encryption Protocol + |-------------------------------------------------------------------------- + | + | Here you may specify the encryption protocol that should be used when + | the application send e-mail messages. A sensible default using the + | transport layer security protocol should provide great security. + | + */ + + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + + /* + |-------------------------------------------------------------------------- + | SMTP Server Username + |-------------------------------------------------------------------------- + | + | If your SMTP server requires a username for authentication, you should + | set it here. This will get used to authenticate with your server on + | connection. You may also set the "password" value below this one. + | + */ + + 'username' => env('MAIL_USERNAME'), + + /* + |-------------------------------------------------------------------------- + | SMTP Server Password + |-------------------------------------------------------------------------- + | + | Here you may set the password required by your SMTP server to send out + | messages from your application. This will be given to the server on + | connection so that the application will be able to send messages. + | + */ + + 'password' => env('MAIL_PASSWORD'), + + /* + |-------------------------------------------------------------------------- + | Sendmail System Path + |-------------------------------------------------------------------------- + | + | When using the "sendmail" driver to send e-mails, we will need to know + | the path to where Sendmail lives on this server. A default path has + | been provided here, which will work well on most of your systems. + | + */ + + 'sendmail' => '/usr/sbin/sendmail -bs', + + /* + |-------------------------------------------------------------------------- + | Mail "Pretend" + |-------------------------------------------------------------------------- + | + | When this option is enabled, e-mail will not actually be sent over the + | web and will instead be written to your application's logs files so + | you may inspect the message. This is great for local development. + | + */ + + 'pretend' => false, + +]; diff --git a/vendor/laravel/lumen-framework/config/queue.php b/vendor/laravel/lumen-framework/config/queue.php new file mode 100644 index 0000000..a74cd44 --- /dev/null +++ b/vendor/laravel/lumen-framework/config/queue.php @@ -0,0 +1,93 @@ + env('QUEUE_DRIVER', 'sync'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection information for each server that + | is used by your application. A default configuration has been added + | for each back-end shipped with Laravel. You are free to add more. + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'default', + 'expire' => 60, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => 'localhost', + 'queue' => 'default', + 'ttr' => 60, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => 'your-public-key', + 'secret' => 'your-secret-key', + 'queue' => 'your-queue-url', + 'region' => 'us-east-1', + ], + + 'iron' => [ + 'driver' => 'iron', + 'host' => 'mq-aws-us-east-1.iron.io', + 'token' => 'your-token', + 'project' => 'your-project-id', + 'queue' => 'your-queue-name', + 'encrypt' => true, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + 'queue' => 'default', + 'expire' => 60, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control which database and table are used to store the jobs that + | have failed. You may change them to any database / table you wish. + | + */ + + 'failed' => [ + 'database' => env('DB_CONNECTION', 'mysql'), 'table' => 'failed_jobs', + ], + +]; diff --git a/vendor/laravel/lumen-framework/config/session.php b/vendor/laravel/lumen-framework/config/session.php new file mode 100644 index 0000000..e714742 --- /dev/null +++ b/vendor/laravel/lumen-framework/config/session.php @@ -0,0 +1,153 @@ + env('SESSION_DRIVER', 'memcached'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_DATABASE_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => env('SESSION_DATABASE_TABLE', 'sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => 'laravel_session', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => null, + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => false, + +]; diff --git a/vendor/laravel/lumen-framework/config/view.php b/vendor/laravel/lumen-framework/config/view.php new file mode 100644 index 0000000..e193ab6 --- /dev/null +++ b/vendor/laravel/lumen-framework/config/view.php @@ -0,0 +1,33 @@ + [ + realpath(base_path('resources/views')), + ], + + /* + |-------------------------------------------------------------------------- + | Compiled View Path + |-------------------------------------------------------------------------- + | + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. + | + */ + + 'compiled' => realpath(storage_path('framework/views')), + +]; diff --git a/vendor/laravel/lumen-framework/lang/en/validation.php b/vendor/laravel/lumen-framework/lang/en/validation.php new file mode 100644 index 0000000..ff1c087 --- /dev/null +++ b/vendor/laravel/lumen-framework/lang/en/validation.php @@ -0,0 +1,107 @@ + 'The :attribute must be accepted.', + 'active_url' => 'The :attribute is not a valid URL.', + 'after' => 'The :attribute must be a date after :date.', + 'alpha' => 'The :attribute may only contain letters.', + 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', + 'alpha_num' => 'The :attribute may only contain letters and numbers.', + 'array' => 'The :attribute must be an array.', + 'before' => 'The :attribute must be a date before :date.', + 'between' => [ + 'numeric' => 'The :attribute must be between :min and :max.', + 'file' => 'The :attribute must be between :min and :max kilobytes.', + 'string' => 'The :attribute must be between :min and :max characters.', + 'array' => 'The :attribute must have between :min and :max items.', + ], + 'boolean' => 'The :attribute field must be true or false.', + 'confirmed' => 'The :attribute confirmation does not match.', + 'date' => 'The :attribute is not a valid date.', + 'date_format' => 'The :attribute does not match the format :format.', + 'different' => 'The :attribute and :other must be different.', + 'digits' => 'The :attribute must be :digits digits.', + 'digits_between' => 'The :attribute must be between :min and :max digits.', + 'email' => 'The :attribute must be a valid email address.', + 'filled' => 'The :attribute field is required.', + 'exists' => 'The selected :attribute is invalid.', + 'image' => 'The :attribute must be an image.', + 'in' => 'The selected :attribute is invalid.', + 'integer' => 'The :attribute must be an integer.', + 'ip' => 'The :attribute must be a valid IP address.', + 'max' => [ + 'numeric' => 'The :attribute may not be greater than :max.', + 'file' => 'The :attribute may not be greater than :max kilobytes.', + 'string' => 'The :attribute may not be greater than :max characters.', + 'array' => 'The :attribute may not have more than :max items.', + ], + 'mimes' => 'The :attribute must be a file of type: :values.', + 'min' => [ + 'numeric' => 'The :attribute must be at least :min.', + 'file' => 'The :attribute must be at least :min kilobytes.', + 'string' => 'The :attribute must be at least :min characters.', + 'array' => 'The :attribute must have at least :min items.', + ], + 'not_in' => 'The selected :attribute is invalid.', + 'numeric' => 'The :attribute must be a number.', + 'regex' => 'The :attribute format is invalid.', + 'required' => 'The :attribute field is required.', + 'required_if' => 'The :attribute field is required when :other is :value.', + 'required_with' => 'The :attribute field is required when :values is present.', + 'required_with_all' => 'The :attribute field is required when :values is present.', + 'required_without' => 'The :attribute field is required when :values is not present.', + 'required_without_all' => 'The :attribute field is required when none of :values are present.', + 'same' => 'The :attribute and :other must match.', + 'size' => [ + 'numeric' => 'The :attribute must be :size.', + 'file' => 'The :attribute must be :size kilobytes.', + 'string' => 'The :attribute must be :size characters.', + 'array' => 'The :attribute must contain :size items.', + ], + 'unique' => 'The :attribute has already been taken.', + 'url' => 'The :attribute format is invalid.', + 'timezone' => 'The :attribute must be a valid zone.', + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => [ + 'attribute-name' => [ + 'rule-name' => 'custom-message', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as E-Mail Address instead + | of "email". This simply helps us make messages a little cleaner. + | + */ + + 'attributes' => [], + +]; diff --git a/vendor/laravel/lumen-framework/phpunit.php b/vendor/laravel/lumen-framework/phpunit.php new file mode 100644 index 0000000..7e0cfdd --- /dev/null +++ b/vendor/laravel/lumen-framework/phpunit.php @@ -0,0 +1,30 @@ + + + + + ./tests + + + + + ./src + + + diff --git a/vendor/laravel/lumen-framework/readme.md b/vendor/laravel/lumen-framework/readme.md new file mode 100644 index 0000000..c2c286e --- /dev/null +++ b/vendor/laravel/lumen-framework/readme.md @@ -0,0 +1,25 @@ +## Lumen Framework (Kernel) + +[![Build Status](https://travis-ci.org/laravel/lumen-framework.svg)](https://travis-ci.org/laravel/lumen-framework) +[![Total Downloads](https://poser.pugx.org/laravel/lumen-framework/d/total.svg)](https://packagist.org/packages/laravel/lumen-framework) +[![Latest Stable Version](https://poser.pugx.org/laravel/lumen-framework/v/stable.svg)](https://packagist.org/packages/laravel/lumen-framework) +[![Latest Unstable Version](https://poser.pugx.org/laravel/lumen-framework/v/unstable.svg)](https://packagist.org/packages/laravel/lumen-framework) +[![License](https://poser.pugx.org/laravel/lumen-framework/license.svg)](https://packagist.org/packages/laravel/lumen-framework) + +> **Note:** This repository contains the core code of the Laravel Lumen framework. If you want to build an application using Laravel Lumen, visit the main [Lumen repository](https://github.com/laravel/lumen). + +## Lumen PHP Framework + +Laravel Lumen is a stunningly fast PHP micro-framework for building web applications with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Lumen attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as routing, database abstraction, queueing, and caching. + +## Official Documentation + +Documentation for the framework can be found on the [Lumen website](http://lumen.laravel.com/docs). + +## Security Vulnerabilities + +If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed. + +### License + +The Lumen framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT). diff --git a/vendor/laravel/lumen-framework/src/Application.php b/vendor/laravel/lumen-framework/src/Application.php new file mode 100644 index 0000000..1a33ade --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Application.php @@ -0,0 +1,1819 @@ +basePath = $basePath; + $this->bootstrapContainer(); + $this->registerErrorHandling(); + } + + /** + * Bootstrap the application container. + * + * @return void + */ + protected function bootstrapContainer() + { + static::setInstance($this); + + $this->instance('app', $this); + $this->instance('path', $this->path()); + + $this->registerContainerAliases(); + } + + /** + * Get the version number of the application. + * + * @return string + */ + public function version() + { + return 'Lumen (5.1.6) (Laravel Components 5.1.*)'; + } + + /** + * Get or check the current application environment. + * + * @param mixed + * @return string + */ + public function environment() + { + $env = env('APP_ENV', 'production'); + + if (func_num_args() > 0) { + $patterns = is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args(); + + foreach ($patterns as $pattern) { + if (Str::is($pattern, $env)) { + return true; + } + } + + return false; + } + + return $env; + } + + /** + * Determine if the application is currently down for maintenance. + * + * @return bool + */ + public function isDownForMaintenance() + { + return file_exists($this->storagePath().'/framework/down'); + } + + /** + * Register all of the configured providers. + * + * @return void + */ + public function registerConfiguredProviders() + { + // + } + + /** + * Get the path to the cached "compiled.php" file. + * + * @return string + */ + public function getCachedCompilePath() + { + throw new Exception(__FUNCTION__.' is not implemented by Lumen.'); + } + + /** + * Get the path to the cached services.json file. + * + * @return string + */ + public function getCachedServicesPath() + { + throw new Exception(__FUNCTION__.' is not implemented by Lumen.'); + } + + /** + * Register a service provider with the application. + * + * @param \Illuminate\Support\ServiceProvider|string $provider + * @param array $options + * @param bool $force + * @return \Illuminate\Support\ServiceProvider + */ + public function register($provider, $options = [], $force = false) + { + if (! $provider instanceof ServiceProvider) { + $provider = new $provider($this); + } + + if (array_key_exists($providerName = get_class($provider), $this->loadedProviders)) { + return; + } + + $this->loadedProviders[$providerName] = true; + + $provider->register(); + $provider->boot(); + } + + /** + * Register a deferred provider and service. + * + * @param string $provider + * @param string|null $service + * @return void + */ + public function registerDeferredProvider($provider, $service = null) + { + return $this->register($provider); + } + + /** + * Boot the application's service providers. + * + * @return void + */ + public function boot() + { + // + } + + /** + * Register a new boot listener. + * + * @param mixed $callback + * @return void + */ + public function booting($callback) + { + // + } + + /** + * Register a new "booted" listener. + * + * @param mixed $callback + * @return void + */ + public function booted($callback) + { + // + } + + /** + * Set the error handling for the application. + * + * @return void + */ + protected function registerErrorHandling() + { + error_reporting(-1); + + set_error_handler(function ($level, $message, $file = '', $line = 0) { + if (error_reporting() & $level) { + throw new ErrorException($message, 0, $level, $file, $line); + } + }); + + set_exception_handler(function ($e) { + $this->handleUncaughtException($e); + }); + + register_shutdown_function(function () { + if (! is_null($error = error_get_last()) && $this->isFatalError($error['type'])) { + $this->handleUncaughtException(new FatalErrorException( + $error['message'], $error['type'], 0, $error['file'], $error['line'] + )); + } + }); + } + + /** + * Determine if the error type is fatal. + * + * @param int $type + * @return bool + */ + protected function isFatalError($type) + { + $errorCodes = [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]; + + if (defined('FATAL_ERROR')) { + $errorCodes[] = FATAL_ERROR; + } + + return in_array($type, $errorCodes); + } + + /** + * Send the exception to the handler and return the response. + * + * @param \Throwable $e + * @return Response + */ + protected function sendExceptionToHandler($e) + { + $handler = $this->make('Illuminate\Contracts\Debug\ExceptionHandler'); + + if ($e instanceof Error) { + $e = new FatalThrowableError($e); + } + + $handler->report($e); + + return $handler->render($this->make('request'), $e); + } + + /** + * Handle an uncaught exception instance. + * + * @param \Throwable $e + * @return void + */ + protected function handleUncaughtException($e) + { + $handler = $this->make('Illuminate\Contracts\Debug\ExceptionHandler'); + + if ($e instanceof Error) { + $e = new FatalThrowableError($e); + } + + $handler->report($e); + + if ($this->runningInConsole()) { + $handler->renderForConsole(new ConsoleOutput, $e); + } else { + $handler->render($this->make('request'), $e)->send(); + } + } + + /** + * Throw an HttpException with the given data. + * + * @param int $code + * @param string $message + * @param array $headers + * @return void + * + * @throws \Symfony\Component\HttpKernel\Exception\HttpException + */ + public function abort($code, $message = '', array $headers = []) + { + if ($code == 404) { + throw new NotFoundHttpException($message); + } + + throw new HttpException($code, $message, null, $headers); + } + + /** + * Resolve the given type from the container. + * + * @param string $abstract + * @param array $parameters + * @return mixed + */ + public function make($abstract, array $parameters = []) + { + if (array_key_exists($abstract, $this->availableBindings) && + ! array_key_exists($this->availableBindings[$abstract], $this->ranServiceBinders)) { + $this->{$method = $this->availableBindings[$abstract]}(); + + $this->ranServiceBinders[$method] = true; + } + + return parent::make($abstract, $parameters); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerAuthBindings() + { + $this->singleton('auth', function () { + return $this->loadComponent('auth', 'Illuminate\Auth\AuthServiceProvider', 'auth'); + }); + + $this->singleton('auth.driver', function () { + return $this->loadComponent('auth', 'Illuminate\Auth\AuthServiceProvider', 'auth.driver'); + }); + + $this->singleton('auth.password', function () { + return $this->loadComponent('auth', 'Illuminate\Auth\Passwords\PasswordResetServiceProvider', 'auth.password'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerBroadcastingBindings() + { + $this->singleton('Illuminate\Contracts\Broadcasting\Broadcaster', function () { + $this->configure('broadcasting'); + + $this->register('Illuminate\Broadcasting\BroadcastServiceProvider'); + + return $this->make('Illuminate\Contracts\Broadcasting\Broadcaster'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerBusBindings() + { + $this->singleton('Illuminate\Contracts\Bus\Dispatcher', function () { + $this->register('Illuminate\Bus\BusServiceProvider'); + + return $this->make('Illuminate\Contracts\Bus\Dispatcher'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerCacheBindings() + { + $this->singleton('cache', function () { + return $this->loadComponent('cache', 'Illuminate\Cache\CacheServiceProvider'); + }); + + $this->singleton('cache.store', function () { + return $this->loadComponent('cache', 'Illuminate\Cache\CacheServiceProvider', 'cache.store'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerConfigBindings() + { + $this->singleton('config', function () { + return new ConfigRepository; + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerComposerBindings() + { + $this->singleton('composer', function ($app) { + return new Composer($app->make('files'), $this->basePath()); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerCookieBindings() + { + $this->singleton('cookie', function () { + return $this->loadComponent('session', 'Illuminate\Cookie\CookieServiceProvider', 'cookie'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerDatabaseBindings() + { + $this->singleton('db', function () { + return $this->loadComponent( + 'database', [ + 'Illuminate\Database\DatabaseServiceProvider', + 'Illuminate\Pagination\PaginationServiceProvider', ], + 'db' + ); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerEncrypterBindings() + { + $this->singleton('encrypter', function () { + return $this->loadComponent('app', 'Illuminate\Encryption\EncryptionServiceProvider', 'encrypter'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerEventBindings() + { + $this->singleton('events', function () { + $this->register('Illuminate\Events\EventServiceProvider'); + + return $this->make('events'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerErrorBindings() + { + if (! $this->bound('Illuminate\Contracts\Debug\ExceptionHandler')) { + $this->singleton( + 'Illuminate\Contracts\Debug\ExceptionHandler', 'Laravel\Lumen\Exceptions\Handler' + ); + } + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerFilesBindings() + { + $this->singleton('files', function () { + return new Filesystem; + }); + + $this->singleton('filesystem', function () { + return $this->loadComponent('filesystems', 'Illuminate\Filesystem\FilesystemServiceProvider', 'filesystem'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerHashBindings() + { + $this->singleton('hash', function () { + $this->register('Illuminate\Hashing\HashServiceProvider'); + + return $this->make('hash'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerLogBindings() + { + $this->singleton('Psr\Log\LoggerInterface', function () { + return new Logger('lumen', [$this->getMonologHandler()]); + }); + } + + /** + * Get the Monolog handler for the application. + * + * @return \Monolog\Handler\AbstractHandler + */ + protected function getMonologHandler() + { + return (new StreamHandler(storage_path('logs/lumen.log'), Logger::DEBUG)) + ->setFormatter(new LineFormatter(null, null, true, true)); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerMailBindings() + { + $this->singleton('mailer', function () { + $this->configure('services'); + + return $this->loadComponent('mail', 'Illuminate\Mail\MailServiceProvider', 'mailer'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerQueueBindings() + { + $this->singleton('queue', function () { + return $this->loadComponent('queue', 'Illuminate\Queue\QueueServiceProvider', 'queue'); + }); + + $this->singleton('queue.connection', function () { + return $this->loadComponent('queue', 'Illuminate\Queue\QueueServiceProvider', 'queue.connection'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerRedisBindings() + { + $this->singleton('redis', function () { + return $this->loadComponent('database', 'Illuminate\Redis\RedisServiceProvider', 'redis'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerRequestBindings() + { + $this->singleton('Illuminate\Http\Request', function () { + return Request::capture()->setUserResolver(function () { + return $this->make('auth')->user(); + })->setRouteResolver(function () { + return $this->currentRoute; + }); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerSessionBindings() + { + $this->singleton('session', function () { + return $this->loadComponent('session', 'Illuminate\Session\SessionServiceProvider'); + }); + + $this->singleton('session.store', function () { + return $this->loadComponent('session', 'Illuminate\Session\SessionServiceProvider', 'session.store'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerTranslationBindings() + { + $this->singleton('translator', function () { + $this->configure('app'); + + $this->instance('path.lang', $this->getLanguagePath()); + + $this->register('Illuminate\Translation\TranslationServiceProvider'); + + return $this->make('translator'); + }); + } + + /** + * Get the path to the application's language files. + * + * @return string + */ + protected function getLanguagePath() + { + if (is_dir($appPath = $this->resourcePath('lang'))) { + return $appPath; + } else { + return __DIR__.'/../lang'; + } + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerUrlGeneratorBindings() + { + $this->singleton('url', function () { + return new Routing\UrlGenerator($this); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerValidatorBindings() + { + $this->singleton('validator', function () { + $this->register('Illuminate\Validation\ValidationServiceProvider'); + + return $this->make('validator'); + }); + } + + /** + * Register container bindings for the application. + * + * @return void + */ + protected function registerViewBindings() + { + $this->singleton('view', function () { + return $this->loadComponent('view', 'Illuminate\View\ViewServiceProvider'); + }); + } + + /** + * Configure and load the given component and provider. + * + * @param string $config + * @param array|string $providers + * @param string|null $return + * @return mixed + */ + protected function loadComponent($config, $providers, $return = null) + { + $this->configure($config); + + foreach ((array) $providers as $provider) { + $this->register($provider); + } + + return $this->make($return ?: $config); + } + + /** + * Load a configuration file into the application. + * + * @param string $name + * @return void + */ + public function configure($name) + { + if (isset($this->loadedConfigurations[$name])) { + return; + } + + $this->loadedConfigurations[$name] = true; + + $path = $this->getConfigurationPath($name); + + if ($path) { + $this->make('config')->set($name, require $path); + } + } + + /** + * Get the path to the given configuration file. + * + * If no name is provided, then we'll return the path to the config folder. + * + * @param string|null $name + * @return string + */ + public function getConfigurationPath($name = null) + { + if (! $name) { + $appConfigDir = ($this->configPath ?: $this->basePath('config')).'/'; + + if (file_exists($appConfigDir)) { + return $appConfigDir; + } elseif (file_exists($path = __DIR__.'/../config/')) { + return $path; + } + } else { + $appConfigPath = ($this->configPath ?: $this->basePath('config')).'/'.$name.'.php'; + + if (file_exists($appConfigPath)) { + return $appConfigPath; + } elseif (file_exists($path = __DIR__.'/../config/'.$name.'.php')) { + return $path; + } + } + } + + /** + * Register the facades for the application. + * + * @return void + */ + public function withFacades() + { + Facade::setFacadeApplication($this); + + if (! static::$aliasesRegistered) { + static::$aliasesRegistered = true; + + class_alias('Illuminate\Support\Facades\App', 'App'); + class_alias('Illuminate\Support\Facades\Auth', 'Auth'); + class_alias('Illuminate\Support\Facades\Bus', 'Bus'); + class_alias('Illuminate\Support\Facades\DB', 'DB'); + class_alias('Illuminate\Support\Facades\Cache', 'Cache'); + class_alias('Illuminate\Support\Facades\Cookie', 'Cookie'); + class_alias('Illuminate\Support\Facades\Crypt', 'Crypt'); + class_alias('Illuminate\Support\Facades\Event', 'Event'); + class_alias('Illuminate\Support\Facades\Hash', 'Hash'); + class_alias('Illuminate\Support\Facades\Log', 'Log'); + class_alias('Illuminate\Support\Facades\Mail', 'Mail'); + class_alias('Illuminate\Support\Facades\Queue', 'Queue'); + class_alias('Illuminate\Support\Facades\Request', 'Request'); + class_alias('Illuminate\Support\Facades\Schema', 'Schema'); + class_alias('Illuminate\Support\Facades\Session', 'Session'); + class_alias('Illuminate\Support\Facades\Storage', 'Storage'); + class_alias('Illuminate\Support\Facades\Validator', 'Validator'); + } + } + + /** + * Load the Eloquent library for the application. + * + * @return void + */ + public function withEloquent() + { + $this->make('db'); + } + + /** + * Register a set of routes with a set of shared attributes. + * + * @param array $attributes + * @param \Closure $callback + * @return void + */ + public function group(array $attributes, Closure $callback) + { + $parentGroupAttributes = $this->groupAttributes; + + $this->groupAttributes = $attributes; + + call_user_func($callback, $this); + + $this->groupAttributes = $parentGroupAttributes; + } + + /** + * Register a route with the application. + * + * @param string $uri + * @param mixed $action + * @return $this + */ + public function get($uri, $action) + { + $this->addRoute('GET', $uri, $action); + + return $this; + } + + /** + * Register a route with the application. + * + * @param string $uri + * @param mixed $action + * @return $this + */ + public function post($uri, $action) + { + $this->addRoute('POST', $uri, $action); + + return $this; + } + + /** + * Register a route with the application. + * + * @param string $uri + * @param mixed $action + * @return $this + */ + public function put($uri, $action) + { + $this->addRoute('PUT', $uri, $action); + + return $this; + } + + /** + * Register a route with the application. + * + * @param string $uri + * @param mixed $action + * @return $this + */ + public function patch($uri, $action) + { + $this->addRoute('PATCH', $uri, $action); + + return $this; + } + + /** + * Register a route with the application. + * + * @param string $uri + * @param mixed $action + * @return $this + */ + public function delete($uri, $action) + { + $this->addRoute('DELETE', $uri, $action); + + return $this; + } + + /** + * Register a route with the application. + * + * @param string $uri + * @param mixed $action + * @return $this + */ + public function options($uri, $action) + { + $this->addRoute('OPTIONS', $uri, $action); + + return $this; + } + + /** + * Add a route to the collection. + * + * @param string $method + * @param string $uri + * @param mixed $action + */ + public function addRoute($method, $uri, $action) + { + $action = $this->parseAction($action); + + if (isset($this->groupAttributes)) { + if (isset($this->groupAttributes['prefix'])) { + $uri = trim($this->groupAttributes['prefix'], '/').'/'.trim($uri, '/'); + } + + $action = $this->mergeGroupAttributes($action); + } + + $uri = '/'.trim($uri, '/'); + + if (isset($action['as'])) { + $this->namedRoutes[$action['as']] = $uri; + } + + $this->routes[$method.$uri] = ['method' => $method, 'uri' => $uri, 'action' => $action]; + } + + /** + * Parse the action into an array format. + * + * @param mixed $action + * @return array + */ + protected function parseAction($action) + { + if (is_string($action)) { + return ['uses' => $action]; + } elseif (! is_array($action)) { + return [$action]; + } + + return $action; + } + + /** + * Merge the group attributes into the action. + * + * @param array $action + * @return array + */ + protected function mergeGroupAttributes(array $action) + { + return $this->mergeNamespaceGroup( + $this->mergeMiddlewareGroup($action) + ); + } + + /** + * Merge the namespace group into the action. + * + * @param array $action + * @return array + */ + protected function mergeNamespaceGroup(array $action) + { + if (isset($this->groupAttributes['namespace']) && isset($action['uses'])) { + $action['uses'] = $this->groupAttributes['namespace'].'\\'.$action['uses']; + } + + return $action; + } + + /** + * Merge the middleware group into the action. + * + * @param array $action + * @return array + */ + protected function mergeMiddlewareGroup($action) + { + if (isset($this->groupAttributes['middleware'])) { + if (isset($action['middleware'])) { + $action['middleware'] = $this->groupAttributes['middleware'].'|'.$action['middleware']; + } else { + $action['middleware'] = $this->groupAttributes['middleware']; + } + } + + return $action; + } + + /** + * Add new middleware to the application. + * + * @param array $middleware + * @return $this + */ + public function middleware(array $middleware) + { + $this->middleware = array_unique(array_merge($this->middleware, $middleware)); + + return $this; + } + + /** + * Define the route middleware for the application. + * + * @param array $middleware + * @return $this + */ + public function routeMiddleware(array $middleware) + { + $this->routeMiddleware = array_merge($this->routeMiddleware, $middleware); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + return $this->dispatch($request); + } + + /** + * Run the application and send the response. + * + * @param SymfonyRequest|null $request + * @return void + */ + public function run($request = null) + { + $response = $this->dispatch($request); + + if ($response instanceof SymfonyResponse) { + $response->send(); + } else { + echo (string) $response; + } + + if (count($this->middleware) > 0) { + $this->callTerminableMiddleware($response); + } + } + + /** + * Call the terminable middleware. + * + * @param mixed $response + * @return void + */ + protected function callTerminableMiddleware($response) + { + $response = $this->prepareResponse($response); + + foreach ($this->middleware as $middleware) { + $instance = $this->make($middleware); + + if (method_exists($instance, 'terminate')) { + $instance->terminate($this->make('request'), $response); + } + } + } + + /** + * Dispatch the incoming request. + * + * @param SymfonyRequest|null $request + * @return Response + */ + public function dispatch($request = null) + { + if ($request) { + $this->instance('Illuminate\Http\Request', $request); + $this->ranServiceBinders['registerRequestBindings'] = true; + + $method = $request->getMethod(); + $pathInfo = $request->getPathInfo(); + } else { + $method = $this->getMethod(); + $pathInfo = $this->getPathInfo(); + } + + try { + return $this->sendThroughPipeline($this->middleware, function () use ($method, $pathInfo) { + if (isset($this->routes[$method.$pathInfo])) { + return $this->handleFoundRoute([true, $this->routes[$method.$pathInfo]['action'], []]); + } + + return $this->handleDispatcherResponse( + $this->createDispatcher()->dispatch($method, $pathInfo) + ); + }); + } catch (Exception $e) { + return $this->sendExceptionToHandler($e); + } catch (Throwable $e) { + return $this->sendExceptionToHandler($e); + } + } + + /** + * Create a FastRoute dispatcher instance for the application. + * + * @return Dispatcher + */ + protected function createDispatcher() + { + return $this->dispatcher ?: \FastRoute\simpleDispatcher(function ($r) { + foreach ($this->routes as $route) { + $r->addRoute($route['method'], $route['uri'], $route['action']); + } + }); + } + + /** + * Set the FastRoute dispatcher instance. + * + * @param \FastRoute\Dispatcher $dispatcher + * @return void + */ + public function setDispatcher(Dispatcher $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + /** + * Handle the response from the FastRoute dispatcher. + * + * @param array $routeInfo + * @return mixed + */ + protected function handleDispatcherResponse($routeInfo) + { + switch ($routeInfo[0]) { + case Dispatcher::NOT_FOUND: + throw new NotFoundHttpException; + + case Dispatcher::METHOD_NOT_ALLOWED: + throw new MethodNotAllowedHttpException($routeInfo[1]); + + case Dispatcher::FOUND: + return $this->handleFoundRoute($routeInfo); + } + } + + /** + * Handle a route found by the dispatcher. + * + * @param array $routeInfo + * @return mixed + */ + protected function handleFoundRoute($routeInfo) + { + $this->currentRoute = $routeInfo; + + $action = $routeInfo[1]; + + // Pipe through route middleware... + if (isset($action['middleware'])) { + $middleware = $this->gatherMiddlewareClassNames($action['middleware']); + + return $this->prepareResponse($this->sendThroughPipeline($middleware, function () use ($routeInfo) { + return $this->callActionOnArrayBasedRoute($routeInfo); + })); + } + + return $this->prepareResponse( + $this->callActionOnArrayBasedRoute($routeInfo) + ); + } + + /** + * Call the Closure on the array based route. + * + * @param array $routeInfo + * @return mixed + */ + protected function callActionOnArrayBasedRoute($routeInfo) + { + $action = $routeInfo[1]; + + if (isset($action['uses'])) { + return $this->prepareResponse($this->callControllerAction($routeInfo)); + } + + foreach ($action as $value) { + if ($value instanceof Closure) { + $closure = $value->bindTo(new Routing\Closure); + break; + } + } + + try { + return $this->prepareResponse($this->call($closure, $routeInfo[2])); + } catch (HttpResponseException $e) { + return $e->getResponse(); + } + } + + /** + * Call a controller based route. + * + * @param array $routeInfo + * @return mixed + */ + protected function callControllerAction($routeInfo) + { + list($controller, $method) = explode('@', $routeInfo[1]['uses']); + + if (! method_exists($instance = $this->make($controller), $method)) { + throw new NotFoundHttpException; + } + + if ($instance instanceof Routing\Controller) { + return $this->callLumenController($instance, $method, $routeInfo); + } else { + return $this->callControllerCallable( + [$instance, $method], $routeInfo[2] + ); + } + } + + /** + * Send the request through a Lumen controller. + * + * @param mixed $instance + * @param string $method + * @param array $routeInfo + * @return mixed + */ + protected function callLumenController($instance, $method, $routeInfo) + { + $middleware = $instance->getMiddlewareForMethod( + $method + ); + + if (count($middleware) > 0) { + return $this->callLumenControllerWithMiddleware( + $instance, $method, $routeInfo, $middleware + ); + } else { + return $this->callControllerCallable( + [$instance, $method], $routeInfo[2] + ); + } + } + + /** + * Send the request through a set of controller middleware. + * + * @param mixed $instance + * @param string $method + * @param array $routeInfo + * @param array $middleware + * @return mixed + */ + protected function callLumenControllerWithMiddleware($instance, $method, $routeInfo, $middleware) + { + $middleware = $this->gatherMiddlewareClassNames($middleware); + + return $this->sendThroughPipeline($middleware, function () use ($instance, $method, $routeInfo) { + return $this->callControllerCallable( + [$instance, $method], $routeInfo[2] + ); + }); + } + + /** + * Call the callable for a controller action with the given parameters. + * + * @param array $callable + * @param array $parameters + * @return mixed + */ + protected function callControllerCallable(array $callable, array $parameters) + { + try { + return $this->prepareResponse( + $this->call($callable, $parameters) + ); + } catch (HttpResponseException $e) { + return $e->getResponse(); + } + } + + /** + * Gather the full class names for the middleware short-cut string. + * + * @param string $middleware + * @return array + */ + protected function gatherMiddlewareClassNames($middleware) + { + $middleware = is_string($middleware) ? explode('|', $middleware) : (array) $middleware; + + return array_map(function ($name) { + list($name, $parameters) = array_pad(explode(':', $name, 2), 2, null); + + return array_get($this->routeMiddleware, $name, $name).($parameters ? ':'.$parameters : ''); + }, $middleware); + } + + /** + * Send the request through the pipeline with the given callback. + * + * @param array $middleware + * @param \Closure $then + * @return mixed + */ + protected function sendThroughPipeline(array $middleware, Closure $then) + { + $shouldSkipMiddleware = $this->bound('middleware.disable') && + $this->make('middleware.disable') === true; + + if (count($middleware) > 0 && ! $shouldSkipMiddleware) { + return (new Pipeline($this)) + ->send($this->make('request')) + ->through($middleware) + ->then($then); + } + + return $then(); + } + + /** + * Prepare the response for sending. + * + * @param mixed $response + * @return Response + */ + public function prepareResponse($response) + { + if (! $response instanceof SymfonyResponse) { + $response = new Response($response); + } elseif ($response instanceof BinaryFileResponse) { + $response = $response->prepare(Request::capture()); + } + + return $response; + } + + /** + * Get the current HTTP request method. + * + * @return string + */ + protected function getMethod() + { + if (isset($_POST['_method'])) { + return strtoupper($_POST['_method']); + } else { + return $_SERVER['REQUEST_METHOD']; + } + } + + /** + * Get the current HTTP path info. + * + * @return string + */ + public function getPathInfo() + { + $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; + + return '/'.trim(str_replace('?'.$query, '', $_SERVER['REQUEST_URI']), '/'); + } + + /** + * Get the application namespace. + * + * @return string + * + * @throws \RuntimeException + */ + public function getNamespace() + { + if (! is_null($this->namespace)) { + return $this->namespace; + } + + $composer = json_decode(file_get_contents($this->basePath().'/composer.json'), true); + + foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path) { + foreach ((array) $path as $pathChoice) { + if (realpath($this->path()) == realpath($this->basePath().'/'.$pathChoice)) { + return $this->namespace = $namespace; + } + } + } + + throw new RuntimeException('Unable to detect application namespace.'); + } + + /** + * Get the path to the application "app" directory. + * + * @return string + */ + public function path() + { + return $this->basePath.DIRECTORY_SEPARATOR.'app'; + } + + /** + * Get the base path for the application. + * + * @param string|null $path + * @return string + */ + public function basePath($path = null) + { + if (isset($this->basePath)) { + return $this->basePath.($path ? '/'.$path : $path); + } + + if ($this->runningInConsole()) { + $this->basePath = getcwd(); + } else { + $this->basePath = realpath(getcwd().'/../'); + } + + return $this->basePath($path); + } + + /** + * Get the storage path for the application. + * + * @param string|null $path + * @return string + */ + public function storagePath($path = null) + { + if ($this->storagePath) { + return $this->storagePath.($path ? '/'.$path : $path); + } + + return $this->basePath().'/storage'.($path ? '/'.$path : $path); + } + + /** + * Set a custom storage path for the application. + * + * @param string $path + * @return $this + */ + public function useStoragePath($path) + { + $this->storagePath = $path; + + return $this; + } + + /** + * Get the database path for the application. + * + * @return string + */ + public function databasePath() + { + return $this->basePath().'/database'; + } + + /** + * Set a custom configuration path for the application. + * + * @param string $path + * @return $this + */ + public function useConfigPath($path) + { + $this->configPath = $path; + + return $this; + } + + /** + * Get the resource path for the application. + * + * @param string|null $path + * @return string + */ + public function resourcePath($path = null) + { + if ($this->resourcePath) { + return $this->resourcePath.($path ? '/'.$path : $path); + } + + return $this->basePath().'/resources'.($path ? '/'.$path : $path); + } + + /** + * Set a custom resource path for the application. + * + * @param string $path + * @return $this + */ + public function useResourcePath($path) + { + $this->resourcePath = $path; + + return $this; + } + + /** + * Determine if the application is running in the console. + * + * @return bool + */ + public function runningInConsole() + { + return php_sapi_name() == 'cli'; + } + + /** + * Prepare the application to execute a console command. + * + * @return void + */ + public function prepareForConsoleCommand() + { + $this->withFacades(); + + $this->make('cache'); + $this->make('queue'); + + $this->configure('database'); + + $this->register('Illuminate\Database\MigrationServiceProvider'); + $this->register('Illuminate\Database\SeedServiceProvider'); + $this->register('Illuminate\Queue\ConsoleServiceProvider'); + } + + /** + * Get the raw routes for the application. + * + * @return array + */ + public function getRoutes() + { + return $this->routes; + } + + /** + * Set the cached routes. + * + * @param array $routes + * @return void + */ + public function setRoutes(array $routes) + { + $this->routes = $routes; + } + + /** + * Register the core container aliases. + * + * @return void + */ + protected function registerContainerAliases() + { + $this->aliases = [ + 'Illuminate\Contracts\Foundation\Application' => 'app', + 'Illuminate\Contracts\Auth\Guard' => 'auth.driver', + 'Illuminate\Contracts\Auth\PasswordBroker' => 'auth.password', + 'Illuminate\Contracts\Cache\Factory' => 'cache', + 'Illuminate\Contracts\Cache\Repository' => 'cache.store', + 'Illuminate\Contracts\Config\Repository' => 'config', + 'Illuminate\Container\Container' => 'app', + 'Illuminate\Contracts\Container\Container' => 'app', + 'Illuminate\Contracts\Cookie\Factory' => 'cookie', + 'Illuminate\Contracts\Cookie\QueueingFactory' => 'cookie', + 'Illuminate\Contracts\Encryption\Encrypter' => 'encrypter', + 'Illuminate\Contracts\Events\Dispatcher' => 'events', + 'Illuminate\Contracts\Filesystem\Factory' => 'filesystem', + 'Illuminate\Contracts\Hashing\Hasher' => 'hash', + 'log' => 'Psr\Log\LoggerInterface', + 'Illuminate\Contracts\Mail\Mailer' => 'mailer', + 'Illuminate\Contracts\Queue\Factory' => 'queue', + 'Illuminate\Contracts\Queue\Queue' => 'queue.connection', + 'Illuminate\Redis\Database' => 'redis', + 'Illuminate\Contracts\Redis\Database' => 'redis', + 'request' => 'Illuminate\Http\Request', + 'Illuminate\Session\SessionManager' => 'session', + 'Illuminate\Contracts\View\Factory' => 'view', + ]; + } + + /** + * The available container bindings and their respective load methods. + * + * @var array + */ + public $availableBindings = [ + 'auth' => 'registerAuthBindings', + 'auth.driver' => 'registerAuthBindings', + 'Illuminate\Contracts\Auth\Guard' => 'registerAuthBindings', + 'auth.password' => 'registerAuthBindings', + 'Illuminate\Contracts\Auth\PasswordBroker' => 'registerAuthBindings', + 'Illuminate\Contracts\Broadcasting\Broadcaster' => 'registerBroadcastingBindings', + 'Illuminate\Contracts\Bus\Dispatcher' => 'registerBusBindings', + 'cache' => 'registerCacheBindings', + 'Illuminate\Contracts\Cache\Factory' => 'registerCacheBindings', + 'Illuminate\Contracts\Cache\Repository' => 'registerCacheBindings', + 'config' => 'registerConfigBindings', + 'composer' => 'registerComposerBindings', + 'cookie' => 'registerCookieBindings', + 'Illuminate\Contracts\Cookie\Factory' => 'registerCookieBindings', + 'Illuminate\Contracts\Cookie\QueueingFactory' => 'registerCookieBindings', + 'db' => 'registerDatabaseBindings', + 'Illuminate\Database\Eloquent\Factory' => 'registerDatabaseBindings', + 'encrypter' => 'registerEncrypterBindings', + 'Illuminate\Contracts\Encryption\Encrypter' => 'registerEncrypterBindings', + 'events' => 'registerEventBindings', + 'Illuminate\Contracts\Events\Dispatcher' => 'registerEventBindings', + 'Illuminate\Contracts\Debug\ExceptionHandler' => 'registerErrorBindings', + 'files' => 'registerFilesBindings', + 'filesystem' => 'registerFilesBindings', + 'Illuminate\Contracts\Filesystem\Factory' => 'registerFilesBindings', + 'hash' => 'registerHashBindings', + 'Illuminate\Contracts\Hashing\Hasher' => 'registerHashBindings', + 'log' => 'registerLogBindings', + 'Psr\Log\LoggerInterface' => 'registerLogBindings', + 'mailer' => 'registerMailBindings', + 'Illuminate\Contracts\Mail\Mailer' => 'registerMailBindings', + 'queue' => 'registerQueueBindings', + 'queue.connection' => 'registerQueueBindings', + 'Illuminate\Contracts\Queue\Factory' => 'registerQueueBindings', + 'Illuminate\Contracts\Queue\Queue' => 'registerQueueBindings', + 'redis' => 'registerRedisBindings', + 'request' => 'registerRequestBindings', + 'Illuminate\Http\Request' => 'registerRequestBindings', + 'session' => 'registerSessionBindings', + 'session.store' => 'registerSessionBindings', + 'Illuminate\Session\SessionManager' => 'registerSessionBindings', + 'translator' => 'registerTranslationBindings', + 'url' => 'registerUrlGeneratorBindings', + 'validator' => 'registerValidatorBindings', + 'view' => 'registerViewBindings', + 'Illuminate\Contracts\View\Factory' => 'registerViewBindings', + ]; + + /** + * Get the HTML from the Lumen welcome screen. + * + * @return string + */ + public function welcome() + { + return " + + + Lumen + + + + + + +
    +
    +
    Lumen.
    +
    +
    + + + "; + } +} diff --git a/vendor/laravel/lumen-framework/src/Console/Commands/ServeCommand.php b/vendor/laravel/lumen-framework/src/Console/Commands/ServeCommand.php new file mode 100644 index 0000000..4ad0af5 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Console/Commands/ServeCommand.php @@ -0,0 +1,57 @@ +input->getOption('host'); + + $port = $this->input->getOption('port'); + + $base = $this->laravel->basePath(); + + $this->info("Lumen development server started on http://{$host}:{$port}/"); + + passthru('"'.PHP_BINARY.'"'." -S {$host}:{$port} \"{$base}\"/server.php"); + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['host', null, InputOption::VALUE_OPTIONAL, 'The host address to serve the application on.', 'localhost'], + + ['port', null, InputOption::VALUE_OPTIONAL, 'The port to serve the application on.', 8000], + ]; + } +} diff --git a/vendor/laravel/lumen-framework/src/Console/Commands/stubs/DatabaseSeeder.stub b/vendor/laravel/lumen-framework/src/Console/Commands/stubs/DatabaseSeeder.stub new file mode 100644 index 0000000..74a5605 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Console/Commands/stubs/DatabaseSeeder.stub @@ -0,0 +1,20 @@ +call('UserTableSeeder'); + } + +} diff --git a/vendor/laravel/lumen-framework/src/Console/Commands/stubs/routes.stub b/vendor/laravel/lumen-framework/src/Console/Commands/stubs/routes.stub new file mode 100644 index 0000000..6852d40 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Console/Commands/stubs/routes.stub @@ -0,0 +1,16 @@ +setRoutes( + unserialize(base64_decode('{{routes}}')) +); diff --git a/vendor/laravel/lumen-framework/src/Console/Kernel.php b/vendor/laravel/lumen-framework/src/Console/Kernel.php new file mode 100644 index 0000000..7b9d1b3 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Console/Kernel.php @@ -0,0 +1,205 @@ +app = $app; + + if ($this->includeDefaultCommands) { + $this->app->prepareForConsoleCommand(); + } + + $this->defineConsoleSchedule(); + } + + /** + * Define the application's command schedule. + * + * @return void + */ + protected function defineConsoleSchedule() + { + $this->app->instance( + 'Illuminate\Console\Scheduling\Schedule', $schedule = new Schedule + ); + + $this->schedule($schedule); + } + + /** + * Run the console application. + * + * @param \Symfony\Component\Console\Input\InputInterface $input + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @return int + */ + public function handle($input, $output = null) + { + try { + return $this->getArtisan()->run($input, $output); + } catch (Exception $e) { + $this->reportException($e); + + $this->renderException($output, $e); + + return 1; + } catch (Throwable $e) { + $e = new FatalThrowableError($e); + + $this->reportException($e); + + $this->renderException($output, $e); + + return 1; + } + } + + /** + * Define the application's command schedule. + * + * @param \Illuminate\Console\Scheduling\Schedule $schedule + * @return void + */ + protected function schedule(Schedule $schedule) + { + // + } + + /** + * Run an Artisan console command by name. + * + * @param string $command + * @param array $parameters + * @return int + */ + public function call($command, array $parameters = []) + { + return $this->getArtisan()->call($command, $parameters); + } + + /** + * Queue the given console command. + * + * @param string $command + * @param array $parameters + * @return void + */ + public function queue($command, array $parameters = []) + { + throw new RuntimeException('Queueing Artisan commands is not supported by Lumen.'); + } + + /** + * Get all of the commands registered with the console. + * + * @return array + */ + public function all() + { + return $this->getArtisan()->all(); + } + + /** + * Get the output for the last run command. + * + * @return string + */ + public function output() + { + return $this->getArtisan()->output(); + } + + /** + * Get the Artisan application instance. + * + * @return \Illuminate\Console\Application + */ + protected function getArtisan() + { + if (is_null($this->artisan)) { + return $this->artisan = (new Artisan($this->app, $this->app->make('events'), $this->app->version())) + ->resolveCommands($this->getCommands()); + } + + return $this->artisan; + } + + /** + * Get the commands to add to the application. + * + * @return array + */ + protected function getCommands() + { + if ($this->includeDefaultCommands) { + return array_merge($this->commands, [ + 'Illuminate\Console\Scheduling\ScheduleRunCommand', + 'Laravel\Lumen\Console\Commands\ServeCommand', + ]); + } else { + return $this->commands; + } + } + + /** + * Report the exception to the exception handler. + * + * @param \Exception $e + * @return void + */ + protected function reportException(Exception $e) + { + $this->app['Illuminate\Contracts\Debug\ExceptionHandler']->report($e); + } + + /** + * Report the exception to the exception handler. + * + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @param \Exception $e + * @return void + */ + protected function renderException($output, Exception $e) + { + $this->app['Illuminate\Contracts\Debug\ExceptionHandler']->renderForConsole($output, $e); + } +} diff --git a/vendor/laravel/lumen-framework/src/Exceptions/Handler.php b/vendor/laravel/lumen-framework/src/Exceptions/Handler.php new file mode 100644 index 0000000..fc0d4e4 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Exceptions/Handler.php @@ -0,0 +1,102 @@ +shouldReport($e)) { + app('Psr\Log\LoggerInterface')->error($e); + } + } + + /** + * Determine if the exception should be reported. + * + * @param \Exception $e + * @return bool + */ + public function shouldReport(Exception $e) + { + return ! $this->shouldntReport($e); + } + + /** + * Determine if the exception is in the "do not report" list. + * + * @param \Exception $e + * @return bool + */ + protected function shouldntReport(Exception $e) + { + foreach ($this->dontReport as $type) { + if ($e instanceof $type) { + return true; + } + } + + return false; + } + + /** + * Render an exception into an HTTP response. + * + * @param \Illuminate\Http\Request $request + * @param \Exception $e + * @return \Symfony\Component\HttpFoundation\Response + */ + public function render($request, Exception $e) + { + $response = (new SymfonyExceptionHandler(env('APP_DEBUG', false)))->createResponse($e); + + return $this->toIlluminateResponse($response, $e); + } + + /** + * Map exception into an illuminate response. + * + * @param \Symfony\Component\HttpFoundation\Response $response + * @param \Exception $e + * @return \Illuminate\Http\Response + */ + protected function toIlluminateResponse($response, Exception $e) + { + $response = new Response($response->getContent(), $response->getStatusCode(), $response->headers->all()); + + $response->exception = $e; + + return $response; + } + + /** + * Render an exception to the console. + * + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @param \Exception $e + * @return void + */ + public function renderForConsole($output, Exception $e) + { + (new ConsoleApplication)->renderException($e, $output); + } +} diff --git a/vendor/laravel/lumen-framework/src/Foundation/Composer.php b/vendor/laravel/lumen-framework/src/Foundation/Composer.php new file mode 100644 index 0000000..5cd8733 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Foundation/Composer.php @@ -0,0 +1,98 @@ +files = $files; + $this->workingPath = $workingPath; + } + + /** + * Regenerate the Composer autoloader files. + * + * @param string $extra + * @return void + */ + public function dumpAutoloads($extra = '') + { + $process = $this->getProcess(); + + $process->setCommandLine(trim($this->findComposer().' dump-autoload '.$extra)); + + $process->run(); + } + + /** + * Regenerate the optimized Composer autoloader files. + * + * @return void + */ + public function dumpOptimized() + { + $this->dumpAutoloads('--optimize'); + } + + /** + * Get the composer command for the environment. + * + * @return string + */ + protected function findComposer() + { + if ($this->files->exists($this->workingPath.'/composer.phar')) { + return '"'.PHP_BINARY.'" composer.phar'; + } + + return 'composer'; + } + + /** + * Get a new Symfony process instance. + * + * @return \Symfony\Component\Process\Process + */ + protected function getProcess() + { + return (new Process('', $this->workingPath))->setTimeout(null); + } + + /** + * Set the working path used by the class. + * + * @param string $path + * @return $this + */ + public function setWorkingPath($path) + { + $this->workingPath = realpath($path); + + return $this; + } +} diff --git a/vendor/laravel/lumen-framework/src/Foundation/Support/Providers/EventServiceProvider.php b/vendor/laravel/lumen-framework/src/Foundation/Support/Providers/EventServiceProvider.php new file mode 100644 index 0000000..4fd83d2 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Foundation/Support/Providers/EventServiceProvider.php @@ -0,0 +1,60 @@ +listen as $event => $listeners) { + foreach ($listeners as $listener) { + $events->listen($event, $listener); + } + } + + foreach ($this->subscribe as $subscriber) { + $events->subscribe($subscriber); + } + } + + /** + * {@inheritdoc} + */ + public function register() + { + // + } + + /** + * Get the events and handlers. + * + * @return array + */ + public function listens() + { + return $this->listen; + } +} diff --git a/vendor/laravel/lumen-framework/src/Foundation/Testing/DatabaseMigrations.php b/vendor/laravel/lumen-framework/src/Foundation/Testing/DatabaseMigrations.php new file mode 100644 index 0000000..d53b34e --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Foundation/Testing/DatabaseMigrations.php @@ -0,0 +1,18 @@ +artisan('migrate'); + + $this->beforeApplicationDestroyed(function () { + $this->artisan('migrate:rollback'); + }); + } +} diff --git a/vendor/laravel/lumen-framework/src/Foundation/Testing/DatabaseTransactions.php b/vendor/laravel/lumen-framework/src/Foundation/Testing/DatabaseTransactions.php new file mode 100644 index 0000000..e580f5a --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Foundation/Testing/DatabaseTransactions.php @@ -0,0 +1,18 @@ +app->make('db')->beginTransaction(); + + $this->beforeApplicationDestroyed(function () { + $this->app->make('db')->rollBack(); + }); + } +} diff --git a/vendor/laravel/lumen-framework/src/Foundation/Testing/WithoutMiddleware.php b/vendor/laravel/lumen-framework/src/Foundation/Testing/WithoutMiddleware.php new file mode 100644 index 0000000..91d1bf5 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Foundation/Testing/WithoutMiddleware.php @@ -0,0 +1,20 @@ +withoutMiddleware(); + } else { + throw new Exception('Unable to disable middleware. CrawlerTrait not used.'); + } + } +} diff --git a/vendor/laravel/lumen-framework/src/Http/Middleware/VerifyCsrfToken.php b/vendor/laravel/lumen-framework/src/Http/Middleware/VerifyCsrfToken.php new file mode 100644 index 0000000..4d334d6 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Http/Middleware/VerifyCsrfToken.php @@ -0,0 +1,92 @@ +encrypter = $encrypter; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return \Illuminate\Http\Response + * + * @throws \Illuminate\Session\TokenMismatchException + */ + public function handle($request, Closure $next) + { + if ($this->isReading($request) || $this->tokensMatch($request)) { + return $this->addCookieToResponse($request, $next($request)); + } + + throw new TokenMismatchException; + } + + /** + * Determine if the session and input CSRF tokens match. + * + * @param \Illuminate\Http\Request $request + * @return bool + */ + protected function tokensMatch($request) + { + $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN'); + + if (! $token && $header = $request->header('X-XSRF-TOKEN')) { + $token = $this->encrypter->decrypt($header); + } + + return StringUtils::equals($request->session()->token(), $token); + } + + /** + * Add the CSRF token to the response cookies. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Response $response + * @return \Illuminate\Http\Response + */ + protected function addCookieToResponse($request, $response) + { + $response->headers->setCookie( + new Cookie('XSRF-TOKEN', $request->session()->token(), time() + 60 * 120, '/', null, false, false) + ); + + return $response; + } + + /** + * Determine if the HTTP request uses a ‘read’ verb. + * + * @param \Illuminate\Http\Request $request + * @return bool + */ + protected function isReading($request) + { + return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']); + } +} diff --git a/vendor/laravel/lumen-framework/src/Http/Redirector.php b/vendor/laravel/lumen-framework/src/Http/Redirector.php new file mode 100644 index 0000000..83be7f5 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Http/Redirector.php @@ -0,0 +1,96 @@ +app = $app; + } + + /** + * Create a new redirect response to the given path. + * + * @param string $path + * @param int $status + * @param array $headers + * @param bool $secure + * @return \Illuminate\Http\RedirectResponse + */ + public function to($path, $status = 302, $headers = [], $secure = null) + { + $path = $this->app->make('url')->to($path, [], $secure); + + return $this->createRedirect($path, $status, $headers); + } + + /** + * Create a new redirect response to a named route. + * + * @param string $route + * @param array $parameters + * @param int $status + * @param array $headers + * @return \Illuminate\Http\RedirectResponse + */ + public function route($route, $parameters = [], $status = 302, $headers = []) + { + $path = $this->app->make('url')->route($route, $parameters); + + return $this->to($path, $status, $headers); + } + + /** + * Create a new redirect response to the previous location. + * + * @param int $status + * @param array $headers + * @return \Illuminate\Http\RedirectResponse + */ + public function back($status = 302, $headers = []) + { + $referrer = $this->app->make('request') + ->headers->get('referer'); + + $url = $referrer ? $this->app->make('url')->to($referrer) + : $this->app->make('session')->previousUrl(); + + return $this->createRedirect($url, $status, $headers); + } + + /** + * Create a new redirect response. + * + * @param string $path + * @param int $status + * @param array $headers + * @return \Illuminate\Http\RedirectResponse + */ + protected function createRedirect($path, $status, $headers) + { + $redirect = new RedirectResponse($path, $status, $headers); + + $redirect->setRequest($this->app->make('request')); + + $redirect->setSession($this->app->make('session.store')); + + return $redirect; + } +} diff --git a/vendor/laravel/lumen-framework/src/Http/ResponseFactory.php b/vendor/laravel/lumen-framework/src/Http/ResponseFactory.php new file mode 100644 index 0000000..aad2ac8 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Http/ResponseFactory.php @@ -0,0 +1,63 @@ +toArray(); + } + + return new JsonResponse($data, $status, $headers, $options); + } + + /** + * Create a new file download response. + * + * @param \SplFileInfo|string $file + * @param string $name + * @param array $headers + * @param null|string $disposition + * @return \Symfony\Component\HttpFoundation\BinaryFileResponse + */ + public function download($file, $name = null, array $headers = [], $disposition = 'attachment') + { + $response = new BinaryFileResponse($file, 200, $headers, true, $disposition); + + if (! is_null($name)) { + return $response->setContentDisposition($disposition, $name, str_replace('%', '', Str::ascii($name))); + } + + return $response; + } +} diff --git a/vendor/laravel/lumen-framework/src/Providers/CacheServiceProvider.php b/vendor/laravel/lumen-framework/src/Providers/CacheServiceProvider.php new file mode 100644 index 0000000..9f79119 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Providers/CacheServiceProvider.php @@ -0,0 +1,23 @@ +app->singleton('command.cache.clear', function ($app) { + return new ClearCommand($app['cache']); + }); + + $this->commands('command.cache.clear'); + } +} diff --git a/vendor/laravel/lumen-framework/src/Routing/Closure.php b/vendor/laravel/lumen-framework/src/Routing/Closure.php new file mode 100644 index 0000000..26568c3 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Routing/Closure.php @@ -0,0 +1,75 @@ +baseBuildFailedValidationResponse($request, $errors); + } + + /** + * {@inheritdoc} + */ + protected function formatValidationErrors(Validator $validator) + { + if (isset(static::$errorFormatter)) { + return call_user_func(static::$errorFormatter, $validator); + } + + return $this->baseFormatValidationErrors($validator); + } +} diff --git a/vendor/laravel/lumen-framework/src/Routing/Controller.php b/vendor/laravel/lumen-framework/src/Routing/Controller.php new file mode 100644 index 0000000..42716e1 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Routing/Controller.php @@ -0,0 +1,52 @@ +middleware[$middleware] = $options; + } + + /** + * Get the middleware for a given method. + * + * @param string $method + * @return array + */ + public function getMiddlewareForMethod($method) + { + $middleware = []; + + foreach ($this->middleware as $name => $options) { + if (isset($options['only']) && ! in_array($method, (array) $options['only'])) { + continue; + } + + if (isset($options['except']) && in_array($method, (array) $options['except'])) { + continue; + } + + $middleware[] = $name; + } + + return $middleware; + } +} diff --git a/vendor/laravel/lumen-framework/src/Routing/DispatchesJobs.php b/vendor/laravel/lumen-framework/src/Routing/DispatchesJobs.php new file mode 100644 index 0000000..26fa772 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Routing/DispatchesJobs.php @@ -0,0 +1,44 @@ +dispatch($job); + } + + /** + * Marshal a job and dispatch it to its appropriate handler. + * + * @param mixed $job + * @param array $array + * @return mixed + */ + protected function dispatchFromArray($job, array $array) + { + return app('Illuminate\Contracts\Bus\Dispatcher')->dispatchFromArray($job, $array); + } + + /** + * Marshal a job and dispatch it to its appropriate handler. + * + * @param mixed $job + * @param \ArrayAccess $source + * @param array $extras + * @return mixed + */ + protected function dispatchFrom($job, ArrayAccess $source, $extras = []) + { + return app('Illuminate\Contracts\Bus\Dispatcher')->dispatchFrom($job, $source, $extras); + } +} diff --git a/vendor/laravel/lumen-framework/src/Routing/UrlGenerator.php b/vendor/laravel/lumen-framework/src/Routing/UrlGenerator.php new file mode 100644 index 0000000..c8ba0d2 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Routing/UrlGenerator.php @@ -0,0 +1,333 @@ +app = $app; + } + + /** + * Get the full URL for the current request. + * + * @return string + */ + public function full() + { + return $this->app->make('request')->fullUrl(); + } + + /** + * Get the current URL for the request. + * + * @return string + */ + public function current() + { + return $this->to($this->app->make('request')->getPathInfo()); + } + + /** + * Generate a url for the application. + * + * @param string $path + * @param array $extra + * @param bool $secure + * @return string + */ + public function to($path, $extra = [], $secure = null) + { + // First we will check if the URL is already a valid URL. If it is we will not + // try to generate a new one but will simply return the URL as is, which is + // convenient since developers do not always have to check if it's valid. + if ($this->isValidUrl($path)) { + return $path; + } + + $scheme = $this->getSchemeForUrl($secure); + + $extra = $this->formatParametersForUrl($extra); + + $tail = implode('/', array_map( + 'rawurlencode', (array) $extra) + ); + + // Once we have the scheme we will compile the "tail" by collapsing the values + // into a single string delimited by slashes. This just makes it convenient + // for passing the array of parameters to this URL as a list of segments. + $root = $this->getRootUrl($scheme); + + return $this->trimUrl($root, $path, $tail); + } + + /** + * Generate a secure, absolute URL to the given path. + * + * @param string $path + * @param array $parameters + * @return string + */ + public function secure($path, $parameters = []) + { + return $this->to($path, $parameters, true); + } + + /** + * Generate a URL to an application asset. + * + * @param string $path + * @param bool|null $secure + * @return string + */ + public function asset($path, $secure = null) + { + if ($this->isValidUrl($path)) { + return $path; + } + + // Once we get the root URL, we will check to see if it contains an index.php + // file in the paths. If it does, we will remove it since it is not needed + // for asset paths, but only for routes to endpoints in the application. + $root = $this->getRootUrl($this->getScheme($secure)); + + return $this->removeIndex($root).'/'.trim($path, '/'); + } + + /** + * Generate a URL to an application asset from a root domain such as CDN etc. + * + * @param string $root + * @param string $path + * @param bool|null $secure + * @return string + */ + public function assetFrom($root, $path, $secure = null) + { + // Once we get the root URL, we will check to see if it contains an index.php + // file in the paths. If it does, we will remove it since it is not needed + // for asset paths, but only for routes to endpoints in the application. + $root = $this->getRootUrl($this->getScheme($secure), $root); + + return $this->removeIndex($root).'/'.trim($path, '/'); + } + + /** + * Remove the index.php file from a path. + * + * @param string $root + * @return string + */ + protected function removeIndex($root) + { + $i = 'index.php'; + + return str_contains($root, $i) ? str_replace('/'.$i, '', $root) : $root; + } + + /** + * Generate a URL to a secure asset. + * + * @param string $path + * @return string + */ + public function secureAsset($path) + { + return $this->asset($path, true); + } + + /** + * Get the scheme for a raw URL. + * + * @param bool|null $secure + * @return string + */ + protected function getScheme($secure) + { + if (is_null($secure)) { + return $this->forceSchema ?: $this->app->make('request')->getScheme().'://'; + } + + return $secure ? 'https://' : 'http://'; + } + + /** + * Force the schema for URLs. + * + * @param string $schema + * @return void + */ + public function forceSchema($schema) + { + $this->forceSchema = $schema.'://'; + } + + /** + * Get the URL to a named route. + * + * @param string $name + * @param mixed $parameters + * @return string + * + * @throws \InvalidArgumentException + */ + public function route($name, $parameters = []) + { + if (! isset($this->app->namedRoutes[$name])) { + throw new \InvalidArgumentException("Route [{$name}] not defined."); + } + + $uri = $this->app->namedRoutes[$name]; + + $parameters = $this->formatParametersForUrl($parameters); + + $uri = preg_replace_callback('/\{(.*?)(:.*?)?(\{[0-9,]+\})?\}/', function ($m) use (&$parameters) { + return isset($parameters[$m[1]]) ? array_pull($parameters, $m[1]) : $m[0]; + }, $uri); + + $uri = $this->to($uri, []); + + if (! empty($parameters)) { + $uri .= '?'.http_build_query($parameters); + } + + return $uri; + } + + /** + * Determine if the given path is a valid URL. + * + * @param string $path + * @return bool + */ + protected function isValidUrl($path) + { + if (starts_with($path, ['#', '//', 'mailto:', 'tel:', 'http://', 'https://'])) { + return true; + } + + return filter_var($path, FILTER_VALIDATE_URL) !== false; + } + + /** + * Get the scheme for a raw URL. + * + * @param bool|null $secure + * @return string + */ + protected function getSchemeForUrl($secure) + { + if (is_null($secure)) { + if (is_null($this->cachedScheme)) { + $this->cachedScheme = $this->app->make('request')->getScheme().'://'; + } + + return $this->cachedScheme; + } + + return $secure ? 'https://' : 'http://'; + } + + /** + * Format the array of URL parameters. + * + * @param mixed|array $parameters + * @return array + */ + protected function formatParametersForUrl($parameters) + { + return $this->replaceRoutableParametersForUrl($parameters); + } + + /** + * Replace UrlRoutable parameters with their route parameter. + * + * @param array $parameters + * @return array + */ + protected function replaceRoutableParametersForUrl($parameters = []) + { + $parameters = is_array($parameters) ? $parameters : [$parameters]; + + foreach ($parameters as $key => $parameter) { + if ($parameter instanceof UrlRoutable) { + $parameters[$key] = $parameter->getRouteKey(); + } + } + + return $parameters; + } + + /** + * Get the base URL for the request. + * + * @param string $scheme + * @param string $root + * @return string + */ + protected function getRootUrl($scheme, $root = null) + { + if (is_null($root)) { + if (is_null($this->cachedRoot)) { + $this->cachedRoot = $this->app->make('request')->root(); + } + + $root = $this->cachedRoot; + } + + $start = starts_with($root, 'http://') ? 'http://' : 'https://'; + + return preg_replace('~'.$start.'~', $scheme, $root, 1); + } + + /** + * Format the given URL segments into a single URL. + * + * @param string $root + * @param string $path + * @param string $tail + * @return string + */ + protected function trimUrl($root, $path, $tail = '') + { + return trim($root.'/'.trim($path.'/'.$tail, '/'), '/'); + } +} diff --git a/vendor/laravel/lumen-framework/src/Routing/ValidatesRequests.php b/vendor/laravel/lumen-framework/src/Routing/ValidatesRequests.php new file mode 100644 index 0000000..72a336f --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Routing/ValidatesRequests.php @@ -0,0 +1,102 @@ +getValidationFactory()->make($request->all(), $rules, $messages, $customAttributes); + + if ($validator->fails()) { + $this->throwValidationException($request, $validator); + } + } + + /** + * Throw the failed validation exception. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Contracts\Validation\Validator $validator + * @return void + */ + protected function throwValidationException(Request $request, $validator) + { + throw new HttpResponseException($this->buildFailedValidationResponse( + $request, $this->formatValidationErrors($validator) + )); + } + + /** + * Create the response for when a request fails validation. + * + * @param \Illuminate\Http\Request $request + * @param array $errors + * @return \Illuminate\Http\Response + */ + protected function buildFailedValidationResponse(Request $request, array $errors) + { + if ($request->ajax() || $request->wantsJson()) { + return new JsonResponse($errors, 422); + } + + return redirect()->to($this->getRedirectUrl()) + ->withInput($request->input()) + ->withErrors($errors, $this->errorBag()); + } + + /** + * Format the validation errors to be returned. + * + * @param \Illuminate\Validation\Validator $validator + * @return array + */ + protected function formatValidationErrors(Validator $validator) + { + return $validator->errors()->getMessages(); + } + + /** + * Get the URL we should redirect to. + * + * @return string + */ + protected function getRedirectUrl() + { + return app('session')->previousUrl(); + } + + /** + * Get a validation factory instance. + * + * @return \Illuminate\Contracts\Validation\Factory + */ + protected function getValidationFactory() + { + return app('validator'); + } + + /** + * Get the key to be used for the view error bag. + * + * @return string + */ + protected function errorBag() + { + return 'default'; + } +} diff --git a/vendor/laravel/lumen-framework/src/Testing/ApplicationTrait.php b/vendor/laravel/lumen-framework/src/Testing/ApplicationTrait.php new file mode 100644 index 0000000..c29765f --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Testing/ApplicationTrait.php @@ -0,0 +1,267 @@ +app = $this->createApplication(); + + Facade::clearResolvedInstances(); + } + + /** + * Specify a list of events that should be fired for the given operation. + * + * These events will be mocked, so that handlers will not actually be executed. + * + * @param array|dynamic $events + * @return $this + */ + public function expectsEvents($events) + { + $events = is_array($events) ? $events : func_get_args(); + + $mock = Mockery::spy('Illuminate\Contracts\Events\Dispatcher'); + + $mock->shouldReceive('fire')->andReturnUsing(function ($called) use (&$events) { + foreach ($events as $key => $event) { + if ((is_string($called) && $called === $event) || + (is_string($called) && is_subclass_of($called, $event)) || + (is_object($called) && $called instanceof $event)) { + unset($events[$key]); + } + } + }); + + $this->beforeApplicationDestroyed(function () use (&$events) { + if ($events) { + throw new Exception( + 'The following events were not fired: ['.implode(', ', $events).']' + ); + } + }); + + $this->app->instance('events', $mock); + + return $this; + } + + /** + * Mock the event dispatcher so all events are silenced. + * + * @return $this + */ + protected function withoutEvents() + { + $mock = Mockery::mock('Illuminate\Contracts\Events\Dispatcher'); + + $mock->shouldReceive('fire'); + + $this->app->instance('events', $mock); + + return $this; + } + + /** + * Specify a list of jobs that should be dispatched for the given operation. + * + * These jobs will be mocked, so that handlers will not actually be executed. + * + * @param array|dynamic $jobs + * @return $this + */ + protected function expectsJobs($jobs) + { + $jobs = is_array($jobs) ? $jobs : func_get_args(); + + $mock = Mockery::mock('Illuminate\Bus\Dispatcher[dispatch]', [$this->app]); + + foreach ($jobs as $job) { + $mock->shouldReceive('dispatch')->atLeast()->once() + ->with(Mockery::type($job)); + } + + $this->app->instance( + 'Illuminate\Contracts\Bus\Dispatcher', $mock + ); + + return $this; + } + + /** + * Set the session to the given array. + * + * @param array $data + * @return $this + */ + public function withSession(array $data) + { + $this->session($data); + + return $this; + } + + /** + * Set the session to the given array. + * + * @param array $data + * @return void + */ + public function session(array $data) + { + $this->startSession(); + + foreach ($data as $key => $value) { + $this->app['session']->put($key, $value); + } + } + + /** + * Flush all of the current session data. + * + * @return void + */ + public function flushSession() + { + $this->startSession(); + + $this->app['session']->flush(); + } + + /** + * Start the session for the application. + * + * @return void + */ + protected function startSession() + { + if (! $this->app['session']->isStarted()) { + $this->app['session']->start(); + } + } + + /** + * Set the currently logged in user for the application. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string|null $driver + * @return $this + */ + public function actingAs(UserContract $user, $driver = null) + { + $this->be($user, $driver); + + return $this; + } + + /** + * Set the currently logged in user for the application. + * + * @param \Illuminate\Contracts\Auth\Authenticatable $user + * @param string $driver + * @return void + */ + public function be(UserContract $user, $driver = null) + { + $this->app['auth']->driver($driver)->setUser($user); + } + + /** + * Assert that a given where condition exists in the database. + * + * @param string $table + * @param array $data + * @return $this + */ + protected function seeInDatabase($table, array $data) + { + $count = $this->app->make('db')->table($table)->where($data)->count(); + + $this->assertGreaterThan(0, $count, sprintf( + 'Unable to find row in database table [%s] that matched attributes [%s].', $table, json_encode($data) + )); + + return $this; + } + + /** + * Assert that a given where condition does not exist in the database. + * + * @param string $table + * @param array $data + * @return $this + */ + protected function missingFromDatabase($table, array $data) + { + return $this->notSeeInDatabase($table, $data); + } + + /** + * Assert that a given where condition does not exist in the database. + * + * @param string $table + * @param array $data + * @return $this + */ + protected function notSeeInDatabase($table, array $data) + { + $count = $this->app->make('db')->table($table)->where($data)->count(); + + $this->assertEquals(0, $count, sprintf( + 'Found unexpected records in database table [%s] that matched attributes [%s].', $table, json_encode($data) + )); + + return $this; + } + + /** + * Seed a given database connection. + * + * @param string $class + * @return void + */ + public function seed($class = 'DatabaseSeeder') + { + $this->artisan('db:seed', ['--class' => $class]); + } + + /** + * Call artisan command and return code. + * + * @param string $command + * @param array $parameters + * @return int + */ + public function artisan($command, $parameters = []) + { + return $this->code = $this->app['Illuminate\Contracts\Console\Kernel']->call($command, $parameters); + } +} diff --git a/vendor/laravel/lumen-framework/src/Testing/AssertionsTrait.php b/vendor/laravel/lumen-framework/src/Testing/AssertionsTrait.php new file mode 100644 index 0000000..d8afcf7 --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Testing/AssertionsTrait.php @@ -0,0 +1,190 @@ +response->getStatusCode(); + + return PHPUnit::assertTrue($this->response->isOk(), "Expected status code 200, got {$actual}."); + } + + /** + * Assert that the client response has a given code. + * + * @param int $code + * @return void + */ + public function assertResponseStatus($code) + { + $actual = $this->response->getStatusCode(); + + return PHPUnit::assertEquals($code, $this->response->getStatusCode(), "Expected status code {$code}, got {$actual}."); + } + + /** + * Assert that the response view has a given piece of bound data. + * + * @param string|array $key + * @param mixed $value + * @return void + */ + public function assertViewHas($key, $value = null) + { + if (is_array($key)) { + return $this->assertViewHasAll($key); + } + + if (! isset($this->response->original) || ! $this->response->original instanceof View) { + return PHPUnit::assertTrue(false, 'The response was not a view.'); + } + + if (is_null($value)) { + PHPUnit::assertArrayHasKey($key, $this->response->original->getData()); + } else { + PHPUnit::assertEquals($value, $this->response->original->$key); + } + } + + /** + * Assert that the view has a given list of bound data. + * + * @param array $bindings + * @return void + */ + public function assertViewHasAll(array $bindings) + { + foreach ($bindings as $key => $value) { + if (is_int($key)) { + $this->assertViewHas($value); + } else { + $this->assertViewHas($key, $value); + } + } + } + + /** + * Assert that the response view is missing a piece of bound data. + * + * @param string $key + * @return void + */ + public function assertViewMissing($key) + { + if (! isset($this->response->original) || ! $this->response->original instanceof View) { + return PHPUnit::assertTrue(false, 'The response was not a view.'); + } + + PHPUnit::assertArrayNotHasKey($key, $this->response->original->getData()); + } + + /** + * Assert whether the client was redirected to a given URI. + * + * @param string $uri + * @param array $with + * @return void + */ + public function assertRedirectedTo($uri, $with = []) + { + PHPUnit::assertInstanceOf('Illuminate\Http\RedirectResponse', $this->response); + + PHPUnit::assertEquals($this->app['url']->to($uri), $this->response->headers->get('Location')); + + $this->assertSessionHasAll($with); + } + + /** + * Assert whether the client was redirected to a given route. + * + * @param string $name + * @param array $parameters + * @param array $with + * @return void + */ + public function assertRedirectedToRoute($name, $parameters = [], $with = []) + { + $this->assertRedirectedTo($this->app['url']->route($name, $parameters), $with); + } + + /** + * Assert that the session has a given list of values. + * + * @param string|array $key + * @param mixed $value + * @return void + */ + public function assertSessionHas($key, $value = null) + { + if (is_array($key)) { + return $this->assertSessionHasAll($key); + } + + if (is_null($value)) { + PHPUnit::assertTrue($this->app['session.store']->has($key), "Session missing key: $key"); + } else { + PHPUnit::assertEquals($value, $this->app['session.store']->get($key)); + } + } + + /** + * Assert that the session has a given list of values. + * + * @param array $bindings + * @return void + */ + public function assertSessionHasAll(array $bindings) + { + foreach ($bindings as $key => $value) { + if (is_int($key)) { + $this->assertSessionHas($value); + } else { + $this->assertSessionHas($key, $value); + } + } + } + + /** + * Assert that the session has errors bound. + * + * @param string|array $bindings + * @param mixed $format + * @return void + */ + public function assertSessionHasErrors($bindings = [], $format = null) + { + $this->assertSessionHas('errors'); + + $bindings = (array) $bindings; + + $errors = $this->app['session.store']->get('errors'); + + foreach ($bindings as $key => $value) { + if (is_int($key)) { + PHPUnit::assertTrue($errors->has($value), "Session missing error: $value"); + } else { + PHPUnit::assertContains($value, $errors->get($key, $format)); + } + } + } + + /** + * Assert that the session has old input. + * + * @return void + */ + public function assertHasOldInput() + { + $this->assertSessionHas('_old_input'); + } +} diff --git a/vendor/laravel/lumen-framework/src/Testing/CrawlerTrait.php b/vendor/laravel/lumen-framework/src/Testing/CrawlerTrait.php new file mode 100644 index 0000000..f42971b --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Testing/CrawlerTrait.php @@ -0,0 +1,772 @@ +makeRequest('GET', $uri); + } + + /** + * Visit the given URI with a GET request. + * + * @param string $uri + * @param array $headers + * @return $this + */ + public function get($uri, array $headers = []) + { + $server = $this->transformHeadersToServerVars($headers); + + $this->call('GET', $uri, [], [], [], $server); + + return $this; + } + + /** + * Visit the given URI with a POST request. + * + * @param string $uri + * @param array $data + * @param array $headers + * @return $this + */ + public function post($uri, array $data = [], array $headers = []) + { + $server = $this->transformHeadersToServerVars($headers); + + $this->call('POST', $uri, $data, [], [], $server); + + return $this; + } + + /** + * Visit the given URI with a PUT request. + * + * @param string $uri + * @param array $data + * @param array $headers + * @return $this + */ + public function put($uri, array $data = [], array $headers = []) + { + $server = $this->transformHeadersToServerVars($headers); + + $this->call('PUT', $uri, $data, [], [], $server); + + return $this; + } + + /** + * Visit the given URI with a PATCH request. + * + * @param string $uri + * @param array $data + * @param array $headers + * @return $this + */ + public function patch($uri, array $data = [], array $headers = []) + { + $server = $this->transformHeadersToServerVars($headers); + + $this->call('PATCH', $uri, $data, [], [], $server); + + return $this; + } + + /** + * Visit the given URI with a DELETE request. + * + * @param string $uri + * @param array $data + * @param array $headers + * @return $this + */ + public function delete($uri, array $data = [], array $headers = []) + { + $server = $this->transformHeadersToServerVars($headers); + + $this->call('DELETE', $uri, $data, [], [], $server); + + return $this; + } + + /** + * Send the given request through the application. + * + * @param \Illuminate\Http\Request $request + * @return $this + */ + public function handle(Request $request) + { + $this->currentUri = $request->fullUrl(); + + $this->response = $this->app->prepareResponse($this->app->handle($request)); + + return $this; + } + + /** + * Transform headers array to array of $_SERVER vars with HTTP_* format. + * + * @param array $headers + * + * @return array + */ + protected function transformHeadersToServerVars(array $headers) + { + $server = []; + $prefix = 'HTTP_'; + + foreach ($headers as $name => $value) { + $name = strtr(strtoupper($name), '-', '_'); + + if (! starts_with($name, $prefix) && $name != 'CONTENT_TYPE') { + $name = $prefix.$name; + } + + $server[$name] = $value; + } + + return $server; + } + + /** + * Make a request to the application and create a Crawler instance. + * + * @param string $method + * @param string $uri + * @param array $parameters + * @param array $cookies + * @param array $files + * @return $this + */ + protected function makeRequest($method, $uri, $parameters = [], $cookies = [], $files = []) + { + $uri = $this->prepareUrlForRequest($uri); + + $this->call($method, $uri, $parameters, $cookies, $files); + + $this->clearInputs()->followRedirects()->assertPageLoaded($uri); + + $this->currentUri = $this->app->make('request')->fullUrl(); + + $this->crawler = new Crawler($this->response->getContent(), $uri); + + return $this; + } + + /** + * Make a request to the application using the given form. + * + * @param \Symfony\Component\DomCrawler\Form $form + * @return $this + */ + protected function makeRequestUsingForm(Form $form) + { + return $this->makeRequest( + $form->getMethod(), $form->getUri(), $this->extractParametersFromForm($form), [], $form->getFiles() + ); + } + + /** + * Extract the parameters from the given form. + * + * @param \Symfony\Component\DomCrawler\Form $form + * @return array + */ + protected function extractParametersFromForm(Form $form) + { + parse_str(http_build_query($form->getValues()), $parameters); + + return $parameters; + } + + /** + * Follow redirects from the last response. + * + * @return $this + */ + protected function followRedirects() + { + while ($this->response->isRedirect()) { + $this->makeRequest('GET', $this->response->getTargetUrl()); + } + + return $this; + } + + /** + * Clear the inputs for the current page. + * + * @return $this + */ + protected function clearInputs() + { + $this->inputs = []; + + return $this; + } + + /** + * Assert that a given page successfully loaded. + * + * @param string $uri + * @param string|null $message + * @return void + */ + protected function assertPageLoaded($uri, $message = null) + { + $status = $this->response->getStatusCode(); + + try { + $this->assertEquals(200, $status); + } catch (PHPUnitException $e) { + $message = $message ?: "A request to [{$uri}] failed. Received status code [{$status}]."; + + throw new PHPUnitException($message, null, $this->response->exception); + } + } + + /** + * Assert that a given string is seen on the page. + * + * @param string $text + * @param bool $negate + * @return $this + */ + protected function see($text, $negate = false) + { + $method = $negate ? 'assertNotRegExp' : 'assertRegExp'; + + $this->$method('/'.preg_quote($text, '/').'/i', $this->response->getContent()); + + return $this; + } + + /** + * Assert that a given string is not seen on the page. + * + * @param string $text + * @return $this + */ + protected function dontSee($text) + { + return $this->see($text, true); + } + + /** + * Assert that the response contains JSON. + * + * @param array|null $data + * @return $this + */ + protected function shouldReturnJson(array $data = null) + { + return $this->receiveJson($data); + } + + /** + * Assert that the response contains JSON. + * + * @param array|null $data + * @return $this + */ + protected function receiveJson($data = null) + { + $this->seeJson(); + + if (! is_null($data)) { + return $this->seeJson($data); + } + } + + /** + * Assert that the response contains an exact JSON array. + * + * @param array $data + * @return $this + */ + public function seeJsonEquals(array $data) + { + $actual = json_encode(array_sort_recursive( + json_decode($this->response->getContent(), true) + )); + + $this->assertEquals(json_encode(array_sort_recursive($data)), $actual); + + return $this; + } + + /** + * Assert that the response contains JSON. + * + * @param array|null $data + * @return $this + */ + public function seeJson(array $data = null) + { + $this->assertJson( + $this->response->getContent(), "Failed asserting that JSON returned [{$this->currentUri}]." + ); + + return is_null($data) ? $this : $this->seeJsonContains($data); + } + + /** + * Assert that the response contains the given JSON. + * + * @param array $data + * @return $this + */ + protected function seeJsonContains(array $data) + { + $actual = json_encode(array_sort_recursive( + json_decode($this->response->getContent(), true) + )); + + foreach (array_sort_recursive(json_decode(json_encode($data), true)) as $key => $value) { + $expected = $this->formatToExpectedJson($key, $value); + + $this->assertTrue( + str_contains($actual, $this->formatToExpectedJson($key, $value)), + "Unable to find JSON fragment [{$expected}] within [{$actual}]." + ); + } + + return $this; + } + + /** + * Format the given key and value into a JSON string for expectation checks. + * + * @param string $key + * @param mixed $value + * @return string + */ + protected function formatToExpectedJson($key, $value) + { + $expected = json_encode([$key => $value]); + + if (starts_with($expected, '{')) { + $expected = substr($expected, 1); + } + + if (ends_with($expected, '}')) { + $expected = substr($expected, 0, -1); + } + + return $expected; + } + + /** + * Asserts that the status code of the response matches the given code. + * + * @param int $status + * @return $this + */ + protected function seeStatusCode($status) + { + $this->assertEquals($status, $this->response->getStatusCode()); + + return $this; + } + + /** + * Assert that the current page matches a given URI. + * + * @param string $uri + * @return $this + */ + protected function seePageIs($uri) + { + return $this->landOn($uri); + } + + /** + * Assert that the current page matches a given URI. + * + * @param string $uri + * @return $this + */ + protected function onPage($uri) + { + return $this->landOn($uri); + } + + /** + * Assert that the current page matches a given URI. + * + * @param string $uri + * @return $this + */ + protected function landOn($uri) + { + $this->assertPageLoaded($uri = $this->prepareUrlForRequest($uri)); + + $this->assertEquals( + $uri, $this->currentUri, "Did not land on expected page [{$uri}].\n" + ); + + return $this; + } + + /** + * Click a link with the given body, name, or ID attribute. + * + * @param string $name + * @return $this + */ + protected function click($name) + { + $link = $this->crawler->selectLink($name); + + if (! count($link)) { + $link = $this->filterByNameOrId($name, 'a'); + + if (! count($link)) { + throw new InvalidArgumentException( + "Could not find a link with a body, name, or ID attribute of [{$name}]." + ); + } + } + + $this->visit($link->link()->getUri()); + + return $this; + } + + /** + * Fill an input field with the given text. + * + * @param string $text + * @param string $element + * @return $this + */ + protected function type($text, $element) + { + return $this->storeInput($element, $text); + } + + /** + * Check a checkbox on the page. + * + * @param string $element + * @return $this + */ + protected function check($element) + { + return $this->storeInput($element, true); + } + + /** + * Select an option from a drop-down. + * + * @param string $option + * @param string $element + * @return $this + */ + protected function select($option, $element) + { + return $this->storeInput($element, $option); + } + + /** + * Attach a file to a form field on the page. + * + * @param string $absolutePath + * @param string $element + * @return $this + */ + protected function attach($absolutePath, $element) + { + return $this->storeInput($element, $absolutePath); + } + + /** + * Submit a form using the button with the given text value. + * + * @param string $buttonText + * @return $this + */ + protected function press($buttonText) + { + return $this->submitForm($buttonText, $this->inputs); + } + + /** + * Submit a form on the page with the given input. + * + * @param string $buttonText + * @param array $inputs + * @return $this + */ + protected function submitForm($buttonText, $inputs = []) + { + $this->makeRequestUsingForm($this->fillForm($buttonText, $inputs)); + + return $this; + } + + /** + * Fill the form with the given data. + * + * @param string $buttonText + * @param array $inputs + * @return \Symfony\Component\DomCrawler\Form + */ + protected function fillForm($buttonText, $inputs = []) + { + if (! is_string($buttonText)) { + $inputs = $buttonText; + + $buttonText = null; + } + + return $this->getForm($buttonText)->setValues($inputs); + } + + /** + * Get the form from the page with the given submit button text. + * + * @param string|null $buttonText + * @return \Symfony\Component\DomCrawler\Form + */ + protected function getForm($buttonText = null) + { + try { + if ($buttonText) { + return $this->crawler->selectButton($buttonText)->form(); + } + + return $this->crawler->filter('form')->form(); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException( + "Could not find a form that has submit button [{$buttonText}]." + ); + } + } + + /** + * Store a form input in the local array. + * + * @param string $element + * @param string $text + * @return $this + */ + protected function storeInput($element, $text) + { + $this->assertFilterProducesResults($element); + + $element = str_replace('#', '', $element); + + $this->inputs[$element] = $text; + + return $this; + } + + /** + * Assert that a filtered Crawler returns nodes. + * + * @param string $filter + * @return void + */ + protected function assertFilterProducesResults($filter) + { + $crawler = $this->filterByNameOrId($filter); + + if (! count($crawler)) { + throw new InvalidArgumentException( + "Nothing matched the filter [{$filter}] CSS query provided for [{$this->currentUri}]." + ); + } + } + + /** + * Filter elements according to the given name or ID attribute. + * + * @param string $name + * @param string $element + * @return \Symfony\Component\DomCrawler\Crawler + */ + protected function filterByNameOrId($name, $element = '*') + { + $name = str_replace('#', '', $name); + + return $this->crawler->filter("{$element}#{$name}, {$element}[name='{$name}']"); + } + + /** + * Call the given URI and return the Response. + * + * @param string $method + * @param string $uri + * @param array $parameters + * @param array $cookies + * @param array $files + * @param array $server + * @param string $content + * @return \Illuminate\Http\Response + */ + public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null) + { + $this->currentUri = $this->prepareUrlForRequest($uri); + + $request = Request::create( + $this->currentUri, $method, $parameters, + $cookies, $files, $server, $content + ); + + return $this->response = $this->app->prepareResponse($this->app->handle($request)); + } + + /** + * Call the given HTTPS URI and return the Response. + * + * @param string $method + * @param string $uri + * @param array $parameters + * @param array $cookies + * @param array $files + * @param array $server + * @param string $content + * @return \Illuminate\Http\Response + */ + public function callSecure($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null) + { + $uri = $this->app['url']->secure(ltrim($uri, '/')); + + return $this->response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content); + } + + /** + * Call a controller action and return the Response. + * + * @param string $method + * @param string $action + * @param array $wildcards + * @param array $parameters + * @param array $cookies + * @param array $files + * @param array $server + * @param string $content + * @return \Illuminate\Http\Response + */ + public function action($method, $action, $wildcards = [], $parameters = [], $cookies = [], $files = [], $server = [], $content = null) + { + $uri = $this->app['url']->action($action, $wildcards, true); + + return $this->response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content); + } + + /** + * Call a named route and return the Response. + * + * @param string $method + * @param string $name + * @param array $routeParameters + * @param array $parameters + * @param array $cookies + * @param array $files + * @param array $server + * @param string $content + * @return \Illuminate\Http\Response + */ + public function route($method, $name, $routeParameters = [], $parameters = [], $cookies = [], $files = [], $server = [], $content = null) + { + $uri = $this->app['url']->route($name, $routeParameters); + + return $this->response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content); + } + + /** + * Turn the given URI into a fully qualified URL. + * + * @param string $uri + * @return string + */ + protected function prepareUrlForRequest($uri) + { + if (starts_with($uri, '/')) { + $uri = substr($uri, 1); + } + + if (! starts_with($uri, 'http')) { + $uri = $this->baseUrl.'/'.$uri; + } + + return trim($uri, '/'); + } + + /** + * Disable middleware for the test. + * + * @return $this + */ + public function withoutMiddleware() + { + $this->app->instance('middleware.disable', true); + + return $this; + } + + /** + * Dump the content from the last response. + * + * @return void + */ + public function dump() + { + $content = $this->response->getContent(); + + $json = json_decode($content); + + if (json_last_error() === JSON_ERROR_NONE) { + $content = $json; + } + + dd($content); + } +} diff --git a/vendor/laravel/lumen-framework/src/Testing/TestCase.php b/vendor/laravel/lumen-framework/src/Testing/TestCase.php new file mode 100644 index 0000000..591b44d --- /dev/null +++ b/vendor/laravel/lumen-framework/src/Testing/TestCase.php @@ -0,0 +1,78 @@ +app) { + $this->refreshApplication(); + } + } + + /** + * Clean up the testing environment before the next test. + * + * @return void + */ + public function tearDown() + { + if (class_exists('Mockery')) { + Mockery::close(); + } + + if ($this->app) { + foreach ($this->beforeApplicationDestroyedCallbacks as $callback) { + call_user_func($callback); + } + + $this->app->flush(); + $this->app = null; + } + } + + /** + * Register a callback to be run before the application is destroyed. + * + * @param callable $callback + * @return void + */ + protected function beforeApplicationDestroyed(callable $callback) + { + $this->beforeApplicationDestroyedCallbacks[] = $callback; + } +} diff --git a/vendor/laravel/lumen-framework/src/helpers.php b/vendor/laravel/lumen-framework/src/helpers.php new file mode 100644 index 0000000..80f1cfb --- /dev/null +++ b/vendor/laravel/lumen-framework/src/helpers.php @@ -0,0 +1,427 @@ +abort($code, $message, $headers); + } +} + +if (! function_exists('app')) { + /** + * Get the available container instance. + * + * @param string $make + * @param array $parameters + * @return mixed|\Laravel\Lumen\Application + */ + function app($make = null, $parameters = []) + { + if (is_null($make)) { + return Container::getInstance(); + } + + return Container::getInstance()->make($make, $parameters); + } +} + +if (! function_exists('base_path')) { + /** + * Get the path to the base of the install. + * + * @param string $path + * @return string + */ + function base_path($path = '') + { + return app()->basePath().($path ? '/'.$path : $path); + } +} + +if (! function_exists('bcrypt')) { + /** + * Hash the given value. + * + * @param string $value + * @param array $options + * @return string + */ + function bcrypt($value, $options = []) + { + return app('hash')->make($value, $options); + } +} + +if (! function_exists('config')) { + /** + * Get / set the specified configuration value. + * + * If an array is passed as the key, we will assume you want to set an array of values. + * + * @param array|string $key + * @param mixed $default + * @return mixed + */ + function config($key = null, $default = null) + { + if (is_null($key)) { + return app('config'); + } + + if (is_array($key)) { + return app('config')->set($key); + } + + return app('config')->get($key, $default); + } +} + +if (! function_exists('cookie')) { + /** + * Create a new cookie instance. + * + * @param string $name + * @param string $value + * @param int $minutes + * @param string $path + * @param string $domain + * @param bool $secure + * @param bool $httpOnly + * @return \Symfony\Component\HttpFoundation\Cookie + */ + function cookie($name = null, $value = null, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true) + { + $cookie = app('cookie'); + + if (is_null($name)) { + return $cookie; + } + + return $cookie->make($name, $value, $minutes, $path, $domain, $secure, $httpOnly); + } +} + +if (! function_exists('csrf_token')) { + /** + * Get the CSRF token value. + * + * @return string + * + * @throws RuntimeException + */ + function csrf_token() + { + $session = app('session'); + if (isset($session)) { + return $session->getToken(); + } + throw new RuntimeException('Application session store not set.'); + } +} + +if (! function_exists('database_path')) { + /** + * Get the path to the database directory of the install. + * + * @param string $path + * @return string + */ + function database_path($path = '') + { + return app()->databasePath().($path ? '/'.$path : $path); + } +} + +if (! function_exists('env')) { + /** + * Gets the value of an environment variable. Supports boolean, empty and null. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + function env($key, $default = null) + { + $value = getenv($key); + + if ($value === false) { + return value($default); + } + + switch (strtolower($value)) { + case 'true': + case '(true)': + return true; + + case 'false': + case '(false)': + return false; + + case 'empty': + case '(empty)': + return ''; + + case 'null': + case '(null)': + return; + } + + if (Str::startsWith($value, '"') && Str::endsWith($value, '"')) { + return substr($value, 1, -1); + } + + return $value; + } +} + +if (! function_exists('event')) { + /** + * Fire an event and call the listeners. + * + * @param string $event + * @param mixed $payload + * @param bool $halt + * @return array|null + */ + function event($event, $payload = [], $halt = false) + { + return app('events')->fire($event, $payload, $halt); + } +} + +if (! function_exists('factory')) { + /** + * Create a model factory builder for a given class, name, and amount. + * + * @param dynamic class|class,name|class,amount|class,name,amount + * @return \Illuminate\Database\Eloquent\FactoryBuilder + */ + function factory() + { + app('db'); + + $factory = app('Illuminate\Database\Eloquent\Factory'); + + $arguments = func_get_args(); + + if (isset($arguments[1]) && is_string($arguments[1])) { + return $factory->of($arguments[0], $arguments[1])->times(isset($arguments[2]) ? $arguments[2] : 1); + } elseif (isset($arguments[1])) { + return $factory->of($arguments[0])->times($arguments[1]); + } else { + return $factory->of($arguments[0]); + } + } +} + +if (! function_exists('info')) { + /** + * Write some information to the log. + * + * @param string $message + * @param array $context + * @return void + */ + function info($message, $context = []) + { + return app('Psr\Log\LoggerInterface')->info($message, $context); + } +} + +if (! function_exists('old')) { + /** + * Retrieve an old input item. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + function old($key = null, $default = null) + { + return app('request')->old($key, $default); + } +} + +if (! function_exists('redirect')) { + /** + * Get an instance of the redirector. + * + * @param string|null $to + * @param int $status + * @param array $headers + * @param bool $secure + * @return \Laravel\Lumen\Http\Redirector|\Illuminate\Http\RedirectResponse + */ + function redirect($to = null, $status = 302, $headers = [], $secure = null) + { + $redirector = new Laravel\Lumen\Http\Redirector(app()); + + if (is_null($to)) { + return $redirector; + } + + return $redirector->to($to, $status, $headers, $secure); + } +} + +if (! function_exists('response')) { + /** + * Return a new response from the application. + * + * @param string $content + * @param int $status + * @param array $headers + * @return \Symfony\Component\HttpFoundation\Response|\Laravel\Lumen\Http\ResponseFactory + */ + function response($content = '', $status = 200, array $headers = []) + { + $factory = new Laravel\Lumen\Http\ResponseFactory; + + if (func_num_args() === 0) { + return $factory; + } + + return $factory->make($content, $status, $headers); + } +} + +if (! function_exists('route')) { + /** + * Generate a URL to a named route. + * + * @param string $name + * @param array $parameters + * @return string + */ + function route($name, $parameters = []) + { + return (new Laravel\Lumen\Routing\UrlGenerator(app())) + ->route($name, $parameters); + } +} + +if (! function_exists('session')) { + /** + * Get / set the specified session value. + * + * If an array is passed as the key, we will assume you want to set an array of values. + * + * @param array|string $key + * @param mixed $default + * @return mixed + */ + function session($key = null, $default = null) + { + $session = app('session'); + + if (is_null($key)) { + return $session; + } + if (is_array($key)) { + return $session->put($key); + } + + return $session->get($key, $default); + } +} + +if (! function_exists('storage_path')) { + /** + * Get the path to the storage folder. + * + * @param string $path + * @return string + */ + function storage_path($path = '') + { + return app()->storagePath($path); + } +} + +if (! function_exists('trans')) { + /** + * Translate the given message. + * + * @param string $id + * @param array $parameters + * @param string $domain + * @param string $locale + * @return string + */ + function trans($id = null, $parameters = [], $domain = 'messages', $locale = null) + { + if (is_null($id)) { + return app('translator'); + } + + return app('translator')->trans($id, $parameters, $domain, $locale); + } +} + +if (! function_exists('trans_choice')) { + /** + * Translates the given message based on a count. + * + * @param string $id + * @param int $number + * @param array $parameters + * @param string $domain + * @param string $locale + * @return string + */ + function trans_choice($id, $number, array $parameters = [], $domain = 'messages', $locale = null) + { + return app('translator')->transChoice($id, $number, $parameters, $domain, $locale); + } +} + +if (! function_exists('url')) { + /** + * Generate a url for the application. + * + * @param string $path + * @param mixed $parameters + * @param bool $secure + * @return string + */ + function url($path = null, $parameters = [], $secure = null) + { + return (new Laravel\Lumen\Routing\UrlGenerator(app())) + ->to($path, $parameters, $secure); + } +} + +if (! function_exists('view')) { + /** + * Get the evaluated view contents for the given view. + * + * @param string $view + * @param array $data + * @param array $mergeData + * @return \Illuminate\View\View + */ + function view($view = null, $data = [], $mergeData = []) + { + $factory = app('view'); + + if (func_num_args() === 0) { + return $factory; + } + + return $factory->make($view, $data, $mergeData); + } +} diff --git a/vendor/laravel/lumen-framework/storage/logs/.gitignore b/vendor/laravel/lumen-framework/storage/logs/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/vendor/laravel/lumen-framework/storage/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/vendor/laravel/lumen-framework/tests/FullApplicationTest.php b/vendor/laravel/lumen-framework/tests/FullApplicationTest.php new file mode 100644 index 0000000..0dd3a7c --- /dev/null +++ b/vendor/laravel/lumen-framework/tests/FullApplicationTest.php @@ -0,0 +1,496 @@ +get('/', function () { + return response('Hello World'); + }); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Hello World', $response->getContent()); + } + + public function testRequestWithoutSymfonyClass() + { + $app = new Application; + + $app->get('/', function () { + return response('Hello World'); + }); + + $_SERVER['REQUEST_METHOD'] = 'GET'; + $_SERVER['REQUEST_URI'] = '/'; + + $response = $app->dispatch(); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Hello World', $response->getContent()); + + unset($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); + } + + public function testRequestWithoutSymfonyClassTrailingSlash() + { + $app = new Application; + + $app->get('/foo', function () { + return response('Hello World'); + }); + + $_SERVER['REQUEST_METHOD'] = 'GET'; + $_SERVER['REQUEST_URI'] = '/foo/'; + + $response = $app->dispatch(); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Hello World', $response->getContent()); + + unset($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); + } + + public function testRequestWithParameters() + { + $app = new Application; + + $app->get('/foo/{bar}/{baz}', function ($bar, $baz) { + return response($bar.$baz); + }); + + $response = $app->handle(Request::create('/foo/1/2', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('12', $response->getContent()); + } + + public function testRequestToControllerWithParameters() + { + $app = new Application; + + $app->get('/foo/{bar}', 'LumenTestController@actionWithParameter'); + + $response = $app->handle(Request::create('/foo/1', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('1', $response->getContent()); + } + + public function testCallbackRouteWithDefaultParameter() + { + $app = new Application; + $app->get('/foo-bar/{baz}', function ($baz = 'default-value') { + return response($baz); + }); + + $response = $app->handle(Request::create('/foo-bar/something', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('something', $response->getContent()); + } + + public function testControllerRouteWithDefaultParameter() + { + $app = new Application; + $app->get('/foo-bar/{baz}', 'LumenTestController@actionWithDefaultParameter'); + + $response = $app->handle(Request::create('/foo-bar/something2', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('something2', $response->getContent()); + } + + public function testGlobalMiddleware() + { + $app = new Application; + + $app->middleware(['LumenTestMiddleware']); + + $app->get('/', function () { + return response('Hello World'); + }); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Middleware', $response->getContent()); + } + + public function testRouteMiddleware() + { + $app = new Application; + + $app->routeMiddleware(['foo' => 'LumenTestMiddleware']); + + $app->get('/', function () { + return response('Hello World'); + }); + + $app->get('/foo', ['middleware' => 'foo', function () { + return response('Hello World'); + }]); + + $response = $app->handle(Request::create('/', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Hello World', $response->getContent()); + + $response = $app->handle(Request::create('/foo', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Middleware', $response->getContent()); + } + + public function testGlobalMiddlewareParameters() + { + $app = new Application; + + $app->middleware(['LumenTestParameterizedMiddleware:foo,bar']); + + $app->get('/', function () { + return response('Hello World'); + }); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Middleware - foo - bar', $response->getContent()); + } + + public function testRouteMiddlewareParameters() + { + $app = new Application; + + $app->routeMiddleware(['foo' => 'LumenTestParameterizedMiddleware']); + + $app->get('/', ['middleware' => 'foo:bar,boom', function () { + return response('Hello World'); + }]); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Middleware - bar - boom', $response->getContent()); + } + + public function testGroupRouteMiddleware() + { + $app = new Application; + + $app->routeMiddleware(['foo' => 'LumenTestMiddleware']); + + $app->group(['middleware' => 'foo'], function ($app) { + $app->get('/', function () { + return 'Hello World'; + }); + $app->group([], function () {}); + $app->get('/fooBar', function () { + return 'Hello World'; + }); + }); + + $app->get('/foo', function () { + return 'Hello World'; + }); + + $response = $app->handle(Request::create('/', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Middleware', $response->getContent()); + + $response = $app->handle(Request::create('/foo', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Hello World', $response->getContent()); + + $response = $app->handle(Request::create('/fooBar', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Middleware', $response->getContent()); + } + + public function testWithMiddlewareDisabled() + { + $app = new Application; + + $app->middleware(['LumenTestMiddleware']); + $app->instance('middleware.disable', true); + + $app->get('/', function () { + return response('Hello World'); + }); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Hello World', $response->getContent()); + } + + public function testGroupPrefixRoutes() + { + $app = new Application; + + $app->group(['prefix' => 'user'], function ($app) { + $app->get('/', function () { + return response('User Index'); + }); + + $app->get('profile', function () { + return response('User Profile'); + }); + + $app->get('/show', function () { + return response('User Show'); + }); + }); + + $response = $app->handle(Request::create('/user', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('User Index', $response->getContent()); + + $response = $app->handle(Request::create('/user/profile', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('User Profile', $response->getContent()); + + $response = $app->handle(Request::create('/user/show', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('User Show', $response->getContent()); + } + + public function testNotFoundResponse() + { + $app = new Application; + $app->instance('Illuminate\Contracts\Debug\ExceptionHandler', $mock = m::mock('Laravel\Lumen\Exceptions\Handler[report]')); + $mock->shouldIgnoreMissing(); + + $app->get('/', function () { + return response('Hello World'); + }); + + $response = $app->handle(Request::create('/foo', 'GET')); + + $this->assertEquals(404, $response->getStatusCode()); + } + + public function testMethodNotAllowedResponse() + { + $app = new Application; + $app->instance('Illuminate\Contracts\Debug\ExceptionHandler', $mock = m::mock('Laravel\Lumen\Exceptions\Handler[report]')); + $mock->shouldIgnoreMissing(); + + $app->post('/', function () { + return response('Hello World'); + }); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(405, $response->getStatusCode()); + } + + public function testControllerResponse() + { + $app = new Application; + + $app->get('/', 'LumenTestController@action'); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('LumenTestController', $response->getContent()); + } + + public function testNamespacedControllerResponse() + { + $app = new Application; + + require_once __DIR__.'/fixtures/TestController.php'; + + $app->group(['namespace' => 'Lumen\Tests'], function ($app) { + $app->get('/', 'TestController@action'); + $app->group([], function () {}); + $app->get('/foo', 'TestController@action'); + }); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Lumen\Tests\TestController', $response->getContent()); + + $response = $app->handle(Request::create('/foo', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Lumen\Tests\TestController', $response->getContent()); + } + + public function testGeneratingUrls() + { + $app = new Application; + $app->instance('request', Request::create('http://lumen.laravel.com', 'GET')); + unset($app->availableBindings['request']); + + $app->get('/foo-bar', ['as' => 'foo', function () { + // + }]); + + $app->get('/foo-bar/{baz}/{boom}', ['as' => 'bar', function () { + // + }]); + + $this->assertEquals('http://lumen.laravel.com/something', url('something')); + $this->assertEquals('http://lumen.laravel.com/foo-bar', route('foo')); + $this->assertEquals('http://lumen.laravel.com/foo-bar/1/2', route('bar', ['baz' => 1, 'boom' => 2])); + $this->assertEquals('http://lumen.laravel.com/foo-bar?baz=1&boom=2', route('foo', ['baz' => 1, 'boom' => 2])); + } + + public function testGeneratingUrlsForRegexParameters() + { + $app = new Application; + $app->instance('request', Request::create('http://lumen.laravel.com', 'GET')); + unset($app->availableBindings['request']); + + $app->get('/foo-bar', ['as' => 'foo', function () { + // + }]); + + $app->get('/foo-bar/{baz:[0-9]+}/{boom}', ['as' => 'bar', function () { + // + }]); + + $app->get('/foo-bar/{baz:[0-9]+}/{boom:[0-9]+}', ['as' => 'baz', function () { + // + }]); + + $app->get('/foo-bar/{baz:[0-9]{2,5}}', ['as' => 'boom', function () { + // + }]); + + $this->assertEquals('http://lumen.laravel.com/something', url('something')); + $this->assertEquals('http://lumen.laravel.com/foo-bar', route('foo')); + $this->assertEquals('http://lumen.laravel.com/foo-bar/1/2', route('bar', ['baz' => 1, 'boom' => 2])); + $this->assertEquals('http://lumen.laravel.com/foo-bar/1/2', route('baz', ['baz' => 1, 'boom' => 2])); + $this->assertEquals('http://lumen.laravel.com/foo-bar/{baz:[0-9]+}/{boom:[0-9]+}?ba=1&bo=2', route('baz', ['ba' => 1, 'bo' => 2])); + $this->assertEquals('http://lumen.laravel.com/foo-bar/5', route('boom', ['baz' => 5])); + } + + public function testRegisterServiceProvider() + { + $app = new Application; + $provider = new LumenTestServiceProvider($app); + $app->register($provider); + } + + public function testUsingCustomDispatcher() + { + $routes = new FastRoute\RouteCollector(new FastRoute\RouteParser\Std, new FastRoute\DataGenerator\GroupCountBased); + + $routes->addRoute('GET', '/', [function () { + return response('Hello World'); + }]); + + $app = new Application; + + $app->setDispatcher(new FastRoute\Dispatcher\GroupCountBased($routes->getData())); + + $response = $app->handle(Request::create('/', 'GET')); + + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Hello World', $response->getContent()); + } + + public function testMiddlewareReceiveResponsesEvenWhenStringReturned() + { + unset($_SERVER['__middleware.response']); + + $app = new Application; + + $app->routeMiddleware(['foo' => 'LumenTestPlainMiddleware']); + + $app->get('/', ['middleware' => 'foo', function () { + return 'Hello World'; + }]); + + $response = $app->handle(Request::create('/', 'GET')); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('Hello World', $response->getContent()); + $this->assertEquals(true, $_SERVER['__middleware.response']); + } + + public function testEnvironmentDetection() + { + $app = new Application; + + $this->assertEquals('production', $app->environment()); + $this->assertTrue($app->environment('production')); + $this->assertTrue($app->environment(['production'])); + } +} + +class LumenTestService +{ +} + +class LumenTestServiceProvider extends Illuminate\Support\ServiceProvider +{ + public function register() + { + } +} + +class LumenTestMiddleware +{ + public function handle($request, $next) + { + return response('Middleware'); + } +} + +class LumenTestPlainMiddleware +{ + public function handle($request, $next) + { + $response = $next($request); + $_SERVER['__middleware.response'] = $response instanceof Illuminate\Http\Response; + + return $response; + } +} + +class LumenTestParameterizedMiddleware +{ + public function handle($request, $next, $parameter1, $parameter2) + { + return response("Middleware - $parameter1 - $parameter2"); + } +} + +class LumenTestController +{ + public $service; + + public function __construct(LumenTestService $service) + { + $this->service = $service; + } + + public function action() + { + return response(__CLASS__); + } + + public function actionWithParameter($baz) + { + return response($baz); + } + + public function actionWithDefaultParameter($baz = 'default-value') + { + return response($baz); + } +} diff --git a/vendor/laravel/lumen-framework/tests/fixtures/TestController.php b/vendor/laravel/lumen-framework/tests/fixtures/TestController.php new file mode 100644 index 0000000..e787992 --- /dev/null +++ b/vendor/laravel/lumen-framework/tests/fixtures/TestController.php @@ -0,0 +1,11 @@ +files() + ->name('*.php') + ->in(__DIR__.'/src') + ->in(__DIR__.'/tests') +; + +return Symfony\CS\Config\Config::create() + ->fixers(array( + 'psr0', 'encoding', 'short_tag', 'braces', 'elseif', 'eof_ending', 'function_declaration', 'indentation', 'line_after_namespace', 'linefeed', 'lowercase_constants', 'lowercase_keywords', 'multiple_use', 'php_closing_tag', 'trailing_spaces', 'visibility', 'duplicate_semicolon', 'extra_empty_lines', 'include', 'namespace_no_leading_whitespace', 'object_operator', 'operators_spaces', 'phpdoc_params', 'return', 'single_array_no_trailing_comma', 'spaces_cast', 'standardize_not_equal', 'ternary_spaces', 'unused_use', 'whitespacy_lines', + )) + ->finder($finder) +; diff --git a/vendor/monolog/monolog/CHANGELOG.mdown b/vendor/monolog/monolog/CHANGELOG.mdown new file mode 100644 index 0000000..2aaeec5 --- /dev/null +++ b/vendor/monolog/monolog/CHANGELOG.mdown @@ -0,0 +1,265 @@ +### 1.17.2 (2015-10-14) + + * Fixed ErrorHandler compatibility with non-Monolog PSR-3 loggers + * Fixed SlackHandler handling to use slack functionalities better + * Fixed SwiftMailerHandler bug when sending multiple emails they all had the same id + * Fixed 5.3 compatibility regression + +### 1.17.1 (2015-08-31) + + * Fixed RollbarHandler triggering PHP notices + +### 1.17.0 (2015-08-30) + + * Added support for `checksum` and `release` context/extra values in RavenHandler + * Added better support for exceptions in RollbarHandler + * Added UidProcessor::getUid + * Added support for showing the resource type in NormalizedFormatter + * Fixed IntrospectionProcessor triggering PHP notices + +### 1.16.0 (2015-08-09) + + * Added IFTTTHandler to notify ifttt.com triggers + * Added Logger::setHandlers() to allow setting/replacing all handlers + * Added $capSize in RedisHandler to cap the log size + * Fixed StreamHandler creation of directory to only trigger when the first log write happens + * Fixed bug in the handling of curl failures + * Fixed duplicate logging of fatal errors when both error and fatal error handlers are registered in monolog's ErrorHandler + * Fixed missing fatal errors records with handlers that need to be closed to flush log records + * Fixed TagProcessor::addTags support for associative arrays + +### 1.15.0 (2015-07-12) + + * Added addTags and setTags methods to change a TagProcessor + * Added automatic creation of directories if they are missing for a StreamHandler to open a log file + * Added retry functionality to Loggly, Cube and Mandrill handlers so they retry up to 5 times in case of network failure + * Fixed process exit code being incorrectly reset to 0 if ErrorHandler::registerExceptionHandler was used + * Fixed HTML/JS escaping in BrowserConsoleHandler + * Fixed JSON encoding errors being silently suppressed (PHP 5.5+ only) + +### 1.14.0 (2015-06-19) + + * Added PHPConsoleHandler to send record to Chrome's PHP Console extension and library + * Added support for objects implementing __toString in the NormalizerFormatter + * Added support for HipChat's v2 API in HipChatHandler + * Added Logger::setTimezone() to initialize the timezone monolog should use in case date.timezone isn't correct for your app + * Added an option to send formatted message instead of the raw record on PushoverHandler via ->useFormattedMessage(true) + * Fixed curl errors being silently suppressed + +### 1.13.1 (2015-03-09) + + * Fixed regression in HipChat requiring a new token to be created + +### 1.13.0 (2015-03-05) + + * Added Registry::hasLogger to check for the presence of a logger instance + * Added context.user support to RavenHandler + * Added HipChat API v2 support in the HipChatHandler + * Added NativeMailerHandler::addParameter to pass params to the mail() process + * Added context data to SlackHandler when $includeContextAndExtra is true + * Added ability to customize the Swift_Message per-email in SwiftMailerHandler + * Fixed SwiftMailerHandler to lazily create message instances if a callback is provided + * Fixed serialization of INF and NaN values in Normalizer and LineFormatter + +### 1.12.0 (2014-12-29) + + * Break: HandlerInterface::isHandling now receives a partial record containing only a level key. This was always the intent and does not break any Monolog handler but is strictly speaking a BC break and you should check if you relied on any other field in your own handlers. + * Added PsrHandler to forward records to another PSR-3 logger + * Added SamplingHandler to wrap around a handler and include only every Nth record + * Added MongoDBFormatter to support better storage with MongoDBHandler (it must be enabled manually for now) + * Added exception codes in the output of most formatters + * Added LineFormatter::includeStacktraces to enable exception stack traces in logs (uses more than one line) + * Added $useShortAttachment to SlackHandler to minify attachment size and $includeExtra to append extra data + * Added $host to HipChatHandler for users of private instances + * Added $transactionName to NewRelicHandler and support for a transaction_name context value + * Fixed MandrillHandler to avoid outputing API call responses + * Fixed some non-standard behaviors in SyslogUdpHandler + +### 1.11.0 (2014-09-30) + + * Break: The NewRelicHandler extra and context data are now prefixed with extra_ and context_ to avoid clashes. Watch out if you have scripts reading those from the API and rely on names + * Added WhatFailureGroupHandler to suppress any exception coming from the wrapped handlers and avoid chain failures if a logging service fails + * Added MandrillHandler to send emails via the Mandrillapp.com API + * Added SlackHandler to log records to a Slack.com account + * Added FleepHookHandler to log records to a Fleep.io account + * Added LogglyHandler::addTag to allow adding tags to an existing handler + * Added $ignoreEmptyContextAndExtra to LineFormatter to avoid empty [] at the end + * Added $useLocking to StreamHandler and RotatingFileHandler to enable flock() while writing + * Added support for PhpAmqpLib in the AmqpHandler + * Added FingersCrossedHandler::clear and BufferHandler::clear to reset them between batches in long running jobs + * Added support for adding extra fields from $_SERVER in the WebProcessor + * Fixed support for non-string values in PrsLogMessageProcessor + * Fixed SwiftMailer messages being sent with the wrong date in long running scripts + * Fixed minor PHP 5.6 compatibility issues + * Fixed BufferHandler::close being called twice + +### 1.10.0 (2014-06-04) + + * Added Logger::getHandlers() and Logger::getProcessors() methods + * Added $passthruLevel argument to FingersCrossedHandler to let it always pass some records through even if the trigger level is not reached + * Added support for extra data in NewRelicHandler + * Added $expandNewlines flag to the ErrorLogHandler to create multiple log entries when a message has multiple lines + +### 1.9.1 (2014-04-24) + + * Fixed regression in RotatingFileHandler file permissions + * Fixed initialization of the BufferHandler to make sure it gets flushed after receiving records + * Fixed ChromePHPHandler and FirePHPHandler's activation strategies to be more conservative + +### 1.9.0 (2014-04-20) + + * Added LogEntriesHandler to send logs to a LogEntries account + * Added $filePermissions to tweak file mode on StreamHandler and RotatingFileHandler + * Added $useFormatting flag to MemoryProcessor to make it send raw data in bytes + * Added support for table formatting in FirePHPHandler via the table context key + * Added a TagProcessor to add tags to records, and support for tags in RavenHandler + * Added $appendNewline flag to the JsonFormatter to enable using it when logging to files + * Added sound support to the PushoverHandler + * Fixed multi-threading support in StreamHandler + * Fixed empty headers issue when ChromePHPHandler received no records + * Fixed default format of the ErrorLogHandler + +### 1.8.0 (2014-03-23) + + * Break: the LineFormatter now strips newlines by default because this was a bug, set $allowInlineLineBreaks to true if you need them + * Added BrowserConsoleHandler to send logs to any browser's console via console.log() injection in the output + * Added FilterHandler to filter records and only allow those of a given list of levels through to the wrapped handler + * Added FlowdockHandler to send logs to a Flowdock account + * Added RollbarHandler to send logs to a Rollbar account + * Added HtmlFormatter to send prettier log emails with colors for each log level + * Added GitProcessor to add the current branch/commit to extra record data + * Added a Monolog\Registry class to allow easier global access to pre-configured loggers + * Added support for the new official graylog2/gelf-php lib for GelfHandler, upgrade if you can by replacing the mlehner/gelf-php requirement + * Added support for HHVM + * Added support for Loggly batch uploads + * Added support for tweaking the content type and encoding in NativeMailerHandler + * Added $skipClassesPartials to tweak the ignored classes in the IntrospectionProcessor + * Fixed batch request support in GelfHandler + +### 1.7.0 (2013-11-14) + + * Added ElasticSearchHandler to send logs to an Elastic Search server + * Added DynamoDbHandler and ScalarFormatter to send logs to Amazon's Dynamo DB + * Added SyslogUdpHandler to send logs to a remote syslogd server + * Added LogglyHandler to send logs to a Loggly account + * Added $level to IntrospectionProcessor so it only adds backtraces when needed + * Added $version to LogstashFormatter to allow using the new v1 Logstash format + * Added $appName to NewRelicHandler + * Added configuration of Pushover notification retries/expiry + * Added $maxColumnWidth to NativeMailerHandler to change the 70 chars default + * Added chainability to most setters for all handlers + * Fixed RavenHandler batch processing so it takes the message from the record with highest priority + * Fixed HipChatHandler batch processing so it sends all messages at once + * Fixed issues with eAccelerator + * Fixed and improved many small things + +### 1.6.0 (2013-07-29) + + * Added HipChatHandler to send logs to a HipChat chat room + * Added ErrorLogHandler to send logs to PHP's error_log function + * Added NewRelicHandler to send logs to NewRelic's service + * Added Monolog\ErrorHandler helper class to register a Logger as exception/error/fatal handler + * Added ChannelLevelActivationStrategy for the FingersCrossedHandler to customize levels by channel + * Added stack traces output when normalizing exceptions (json output & co) + * Added Monolog\Logger::API constant (currently 1) + * Added support for ChromePHP's v4.0 extension + * Added support for message priorities in PushoverHandler, see $highPriorityLevel and $emergencyLevel + * Added support for sending messages to multiple users at once with the PushoverHandler + * Fixed RavenHandler's support for batch sending of messages (when behind a Buffer or FingersCrossedHandler) + * Fixed normalization of Traversables with very large data sets, only the first 1000 items are shown now + * Fixed issue in RotatingFileHandler when an open_basedir restriction is active + * Fixed minor issues in RavenHandler and bumped the API to Raven 0.5.0 + * Fixed SyslogHandler issue when many were used concurrently with different facilities + +### 1.5.0 (2013-04-23) + + * Added ProcessIdProcessor to inject the PID in log records + * Added UidProcessor to inject a unique identifier to all log records of one request/run + * Added support for previous exceptions in the LineFormatter exception serialization + * Added Monolog\Logger::getLevels() to get all available levels + * Fixed ChromePHPHandler so it avoids sending headers larger than Chrome can handle + +### 1.4.1 (2013-04-01) + + * Fixed exception formatting in the LineFormatter to be more minimalistic + * Fixed RavenHandler's handling of context/extra data, requires Raven client >0.1.0 + * Fixed log rotation in RotatingFileHandler to work with long running scripts spanning multiple days + * Fixed WebProcessor array access so it checks for data presence + * Fixed Buffer, Group and FingersCrossed handlers to make use of their processors + +### 1.4.0 (2013-02-13) + + * Added RedisHandler to log to Redis via the Predis library or the phpredis extension + * Added ZendMonitorHandler to log to the Zend Server monitor + * Added the possibility to pass arrays of handlers and processors directly in the Logger constructor + * Added `$useSSL` option to the PushoverHandler which is enabled by default + * Fixed ChromePHPHandler and FirePHPHandler issue when multiple instances are used simultaneously + * Fixed header injection capability in the NativeMailHandler + +### 1.3.1 (2013-01-11) + + * Fixed LogstashFormatter to be usable with stream handlers + * Fixed GelfMessageFormatter levels on Windows + +### 1.3.0 (2013-01-08) + + * Added PSR-3 compliance, the `Monolog\Logger` class is now an instance of `Psr\Log\LoggerInterface` + * Added PsrLogMessageProcessor that you can selectively enable for full PSR-3 compliance + * Added LogstashFormatter (combine with SocketHandler or StreamHandler to send logs to Logstash) + * Added PushoverHandler to send mobile notifications + * Added CouchDBHandler and DoctrineCouchDBHandler + * Added RavenHandler to send data to Sentry servers + * Added support for the new MongoClient class in MongoDBHandler + * Added microsecond precision to log records' timestamps + * Added `$flushOnOverflow` param to BufferHandler to flush by batches instead of losing + the oldest entries + * Fixed normalization of objects with cyclic references + +### 1.2.1 (2012-08-29) + + * Added new $logopts arg to SyslogHandler to provide custom openlog options + * Fixed fatal error in SyslogHandler + +### 1.2.0 (2012-08-18) + + * Added AmqpHandler (for use with AMQP servers) + * Added CubeHandler + * Added NativeMailerHandler::addHeader() to send custom headers in mails + * Added the possibility to specify more than one recipient in NativeMailerHandler + * Added the possibility to specify float timeouts in SocketHandler + * Added NOTICE and EMERGENCY levels to conform with RFC 5424 + * Fixed the log records to use the php default timezone instead of UTC + * Fixed BufferHandler not being flushed properly on PHP fatal errors + * Fixed normalization of exotic resource types + * Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog + +### 1.1.0 (2012-04-23) + + * Added Monolog\Logger::isHandling() to check if a handler will + handle the given log level + * Added ChromePHPHandler + * Added MongoDBHandler + * Added GelfHandler (for use with Graylog2 servers) + * Added SocketHandler (for use with syslog-ng for example) + * Added NormalizerFormatter + * Added the possibility to change the activation strategy of the FingersCrossedHandler + * Added possibility to show microseconds in logs + * Added `server` and `referer` to WebProcessor output + +### 1.0.2 (2011-10-24) + + * Fixed bug in IE with large response headers and FirePHPHandler + +### 1.0.1 (2011-08-25) + + * Added MemoryPeakUsageProcessor and MemoryUsageProcessor + * Added Monolog\Logger::getName() to get a logger's channel name + +### 1.0.0 (2011-07-06) + + * Added IntrospectionProcessor to get info from where the logger was called + * Fixed WebProcessor in CLI + +### 1.0.0-RC1 (2011-07-01) + + * Initial release diff --git a/vendor/monolog/monolog/LICENSE b/vendor/monolog/monolog/LICENSE new file mode 100644 index 0000000..56e08d5 --- /dev/null +++ b/vendor/monolog/monolog/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011-2015 Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/monolog/monolog/README.mdown b/vendor/monolog/monolog/README.mdown new file mode 100644 index 0000000..7d8ade5 --- /dev/null +++ b/vendor/monolog/monolog/README.mdown @@ -0,0 +1,95 @@ +# Monolog - Logging for PHP [![Build Status](https://img.shields.io/travis/Seldaek/monolog.svg)](https://travis-ci.org/Seldaek/monolog) + +[![Total Downloads](https://img.shields.io/packagist/dt/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog) +[![Latest Stable Version](https://img.shields.io/packagist/v/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog) +[![Reference Status](https://www.versioneye.com/php/monolog:monolog/reference_badge.svg)](https://www.versioneye.com/php/monolog:monolog/references) + + +Monolog sends your logs to files, sockets, inboxes, databases and various +web services. See the complete list of handlers below. Special handlers +allow you to build advanced logging strategies. + +This library implements the [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +interface that you can type-hint against in your own libraries to keep +a maximum of interoperability. You can also use it in your applications to +make sure you can always use another compatible logger at a later time. +As of 1.11.0 Monolog public APIs will also accept PSR-3 log levels. +Internally Monolog still uses its own level scheme since it predates PSR-3. + +## Installation + +Install the latest version with + +```bash +$ composer require monolog/monolog +``` + +## Basic Usage + +```php +pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); + +// add records to the log +$log->addWarning('Foo'); +$log->addError('Bar'); +``` + +## Documentation + +- [Usage Instructions](doc/01-usage.md) +- [Handlers, Formatters and Processors](doc/02-handlers-formatters-processors.md) +- [Utility classes](doc/03-utilities.md) +- [Extending Monolog](doc/04-extending.md) + +## Third Party Packages + +Third party handlers, formatters and processors are +[listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You +can also add your own there if you publish one. + +## About + +### Requirements + +- Monolog works with PHP 5.3 or above, and is also tested to work with HHVM. + +### Submitting bugs and feature requests + +Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues) + +### Framework Integrations + +- Frameworks and libraries using [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) + can be used very easily with Monolog since it implements the interface. +- [Symfony2](http://symfony.com) comes out of the box with Monolog. +- [Silex](http://silex.sensiolabs.org/) comes out of the box with Monolog. +- [Laravel 4 & 5](http://laravel.com/) come out of the box with Monolog. +- [Lumen](http://lumen.laravel.com/) comes out of the box with Monolog. +- [PPI](http://www.ppi.io/) comes out of the box with Monolog. +- [CakePHP](http://cakephp.org/) is usable with Monolog via the [cakephp-monolog](https://github.com/jadb/cakephp-monolog) plugin. +- [Slim](http://www.slimframework.com/) is usable with Monolog via the [Slim-Monolog](https://github.com/Flynsarmy/Slim-Monolog) log writer. +- [XOOPS 2.6](http://xoops.org/) comes out of the box with Monolog. +- [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog. +- [Nette Framework](http://nette.org/en/) can be used with Monolog via [Kdyby/Monolog](https://github.com/Kdyby/Monolog) extension. +- [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog. + +### Author + +Jordi Boggiano - -
    +See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) which participated in this project. + +### License + +Monolog is licensed under the MIT License - see the `LICENSE` file for details + +### Acknowledgements + +This library is heavily inspired by Python's [Logbook](http://packages.python.org/Logbook/) +library, although most concepts have been adjusted to fit to the PHP world. diff --git a/vendor/monolog/monolog/composer.json b/vendor/monolog/monolog/composer.json new file mode 100644 index 0000000..2bb9053 --- /dev/null +++ b/vendor/monolog/monolog/composer.json @@ -0,0 +1,65 @@ +{ + "name": "monolog/monolog", + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "keywords": ["log", "logging", "psr-3"], + "homepage": "http://github.com/Seldaek/monolog", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "graylog2/gelf-php": "~1.0", + "raven/raven": "^0.13", + "ruflin/elastica": ">=0.90 <3.0", + "doctrine/couchdb": "~1.0@dev", + "aws/aws-sdk-php": "^2.4.9", + "videlalvaro/php-amqplib": "~2.4", + "swiftmailer/swiftmailer": "~5.3", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit-mock-objects": "2.3.0", + "jakub-onderka/php-parallel-lint": "0.9" + }, + "_": "phpunit/phpunit-mock-objects required in 2.3.0 due to https://github.com/sebastianbergmann/phpunit-mock-objects/issues/223 - needs hhvm 3.8+ on travis", + "suggest": { + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "raven/raven": "Allow sending log messages to a Sentry server", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "php-console/php-console": "Allow sending log messages to Google Chrome" + }, + "autoload": { + "psr-4": {"Monolog\\": "src/Monolog"} + }, + "autoload-dev": { + "psr-4": {"Monolog\\": "tests/Monolog"} + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "extra": { + "branch-alias": { + "dev-master": "1.16.x-dev" + } + }, + "scripts": { + "test": [ + "parallel-lint . --exclude vendor", + "phpunit" + ] + } +} diff --git a/vendor/monolog/monolog/doc/01-usage.md b/vendor/monolog/monolog/doc/01-usage.md new file mode 100644 index 0000000..75bc402 --- /dev/null +++ b/vendor/monolog/monolog/doc/01-usage.md @@ -0,0 +1,228 @@ +# Using Monolog + +- [Installation](#installation) +- [Core Concepts](#core-concepts) +- [Log Levels](#log-levels) +- [Configuring a logger](#configuring-a-logger) +- [Adding extra data in the records](#adding-extra-data-in-the-records) +- [Leveraging channels](#leveraging-channels) +- [Customizing the log format](#customizing-the-log-format) + +## Installation + +Monolog is available on Packagist ([monolog/monolog](http://packagist.org/packages/monolog/monolog)) +and as such installable via [Composer](http://getcomposer.org/). + +```bash +composer require monolog/monolog +``` + +If you do not use Composer, you can grab the code from GitHub, and use any +PSR-0 compatible autoloader (e.g. the [Symfony2 ClassLoader component](https://github.com/symfony/ClassLoader)) +to load Monolog classes. + +## Core Concepts + +Every `Logger` instance has a channel (name) and a stack of handlers. Whenever +you add a record to the logger, it traverses the handler stack. Each handler +decides whether it fully handled the record, and if so, the propagation of the +record ends there. + +This allows for flexible logging setups, for example having a `StreamHandler` at +the bottom of the stack that will log anything to disk, and on top of that add +a `MailHandler` that will send emails only when an error message is logged. +Handlers also have a `$bubble` property which defines whether they block the +record or not if they handled it. In this example, setting the `MailHandler`'s +`$bubble` argument to false means that records handled by the `MailHandler` will +not propagate to the `StreamHandler` anymore. + +You can create many `Logger`s, each defining a channel (e.g.: db, request, +router, ..) and each of them combining various handlers, which can be shared +or not. The channel is reflected in the logs and allows you to easily see or +filter records. + +Each Handler also has a Formatter, a default one with settings that make sense +will be created if you don't set one. The formatters normalize and format +incoming records so that they can be used by the handlers to output useful +information. + +Custom severity levels are not available. Only the eight +[RFC 5424](http://tools.ietf.org/html/rfc5424) levels (debug, info, notice, +warning, error, critical, alert, emergency) are present for basic filtering +purposes, but for sorting and other use cases that would require +flexibility, you should add Processors to the Logger that can add extra +information (tags, user ip, ..) to the records before they are handled. + +## Log Levels + +Monolog supports the logging levels described by [RFC 5424](http://tools.ietf.org/html/rfc5424). + +- **DEBUG** (100): Detailed debug information. + +- **INFO** (200): Interesting events. Examples: User logs in, SQL logs. + +- **NOTICE** (250): Normal but significant events. + +- **WARNING** (300): Exceptional occurrences that are not errors. Examples: + Use of deprecated APIs, poor use of an API, undesirable things that are not + necessarily wrong. + +- **ERROR** (400): Runtime errors that do not require immediate action but + should typically be logged and monitored. + +- **CRITICAL** (500): Critical conditions. Example: Application component + unavailable, unexpected exception. + +- **ALERT** (550): Action must be taken immediately. Example: Entire website + down, database unavailable, etc. This should trigger the SMS alerts and wake + you up. + +- **EMERGENCY** (600): Emergency: system is unusable. + +## Configuring a logger + +Here is a basic setup to log to a file and to firephp on the DEBUG level: + +```php +pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG)); +$logger->pushHandler(new FirePHPHandler()); + +// You can now use your logger +$logger->addInfo('My logger is now ready'); +``` + +Let's explain it. The first step is to create the logger instance which will +be used in your code. The argument is a channel name, which is useful when +you use several loggers (see below for more details about it). + +The logger itself does not know how to handle a record. It delegates it to +some handlers. The code above registers two handlers in the stack to allow +handling records in two different ways. + +Note that the FirePHPHandler is called first as it is added on top of the +stack. This allows you to temporarily add a logger with bubbling disabled if +you want to override other configured loggers. + +> If you use Monolog standalone and are looking for an easy way to +> configure many handlers, the [theorchard/monolog-cascade](https://github.com/theorchard/monolog-cascade) +> can help you build complex logging configs via PHP arrays, yaml or json configs. + +## Adding extra data in the records + +Monolog provides two different ways to add extra informations along the simple +textual message. + +### Using the logging context + +The first way is the context, allowing to pass an array of data along the +record: + +```php +addInfo('Adding a new user', array('username' => 'Seldaek')); +``` + +Simple handlers (like the StreamHandler for instance) will simply format +the array to a string but richer handlers can take advantage of the context +(FirePHP is able to display arrays in pretty way for instance). + +### Using processors + +The second way is to add extra data for all records by using a processor. +Processors can be any callable. They will get the record as parameter and +must return it after having eventually changed the `extra` part of it. Let's +write a processor adding some dummy data in the record: + +```php +pushProcessor(function ($record) { + $record['extra']['dummy'] = 'Hello world!'; + + return $record; +}); +``` + +Monolog provides some built-in processors that can be used in your project. +Look at the [dedicated chapter](https://github.com/Seldaek/monolog/blob/master/doc/02-handlers-formatters-processors.md#processors) for the list. + +> Tip: processors can also be registered on a specific handler instead of + the logger to apply only for this handler. + +## Leveraging channels + +Channels are a great way to identify to which part of the application a record +is related. This is useful in big applications (and is leveraged by +MonologBundle in Symfony2). + +Picture two loggers sharing a handler that writes to a single log file. +Channels would allow you to identify the logger that issued every record. +You can easily grep through the log files filtering this or that channel. + +```php +pushHandler($stream); +$logger->pushHandler($firephp); + +// Create a logger for the security-related stuff with a different channel +$securityLogger = new Logger('security'); +$securityLogger->pushHandler($stream); +$securityLogger->pushHandler($firephp); +``` + +## Customizing the log format + +In Monolog it's easy to customize the format of the logs written into files, +sockets, mails, databases and other handlers. Most of the handlers use the + +```php +$record['formatted'] +``` + +value to be automatically put into the log device. This value depends on the +formatter settings. You can choose between predefined formatter classes or +write your own (e.g. a multiline text file for human-readable output). + +To configure a predefined formatter class, just set it as the handler's field: + +```php +// the default date format is "Y-m-d H:i:s" +$dateFormat = "Y n j, g:i a"; +// the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n" +$output = "%datetime% > %level_name% > %message% %context% %extra%\n"; +// finally, create a formatter +$formatter = new LineFormatter($output, $dateFormat); + +// Create a handler +$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG); +$stream->setFormatter($formatter); +// bind it to a logger object +$securityLogger = new Logger('security'); +$securityLogger->pushHandler($stream); +``` + +You may also reuse the same formatter between multiple handlers and share those +handlers between multiple loggers. + +[Handlers, Formatters and Processors](02-handlers-formatters-processors.md) → diff --git a/vendor/monolog/monolog/doc/02-handlers-formatters-processors.md b/vendor/monolog/monolog/doc/02-handlers-formatters-processors.md new file mode 100644 index 0000000..90f8fce --- /dev/null +++ b/vendor/monolog/monolog/doc/02-handlers-formatters-processors.md @@ -0,0 +1,142 @@ +# Handlers, Formatters and Processors + +- [Handlers](#handlers) + - [Log to files and syslog](#log-to-files-and-syslog) + - [Send alerts and emails](#send-alerts-and-emails) + - [Log specific servers and networked logging](#log-specific-servers-and-networked-logging) + - [Logging in development](#logging-in-development) + - [Log to databases](#log-to-databases) + - [Wrappers / Special Handlers](#wrappers--special-handlers) +- [Formatters](#formatters) +- [Processors](#processors) +- [Third Party Packages](#third-party-packages) + +## Handlers + +### Log to files and syslog + +- _StreamHandler_: Logs records into any PHP stream, use this for log files. +- _RotatingFileHandler_: Logs records to a file and creates one logfile per day. + It will also delete files older than `$maxFiles`. You should use + [logrotate](http://linuxcommand.org/man_pages/logrotate8.html) for high profile + setups though, this is just meant as a quick and dirty solution. +- _SyslogHandler_: Logs records to the syslog. +- _ErrorLogHandler_: Logs records to PHP's + [`error_log()`](http://docs.php.net/manual/en/function.error-log.php) function. + +### Send alerts and emails + +- _NativeMailerHandler_: Sends emails using PHP's + [`mail()`](http://php.net/manual/en/function.mail.php) function. +- _SwiftMailerHandler_: Sends emails using a [`Swift_Mailer`](http://swiftmailer.org/) instance. +- _PushoverHandler_: Sends mobile notifications via the [Pushover](https://www.pushover.net/) API. +- _HipChatHandler_: Logs records to a [HipChat](http://hipchat.com) chat room using its API. +- _FlowdockHandler_: Logs records to a [Flowdock](https://www.flowdock.com/) account. +- _SlackHandler_: Logs records to a [Slack](https://www.slack.com/) account. +- _MandrillHandler_: Sends emails via the Mandrill API using a [`Swift_Message`](http://swiftmailer.org/) instance. +- _FleepHookHandler_: Logs records to a [Fleep](https://fleep.io/) conversation using Webhooks. +- _IFTTTHandler_: Notifies an [IFTTT](https://ifttt.com/maker) trigger with the log channel, level name and message. + +### Log specific servers and networked logging + +- _SocketHandler_: Logs records to [sockets](http://php.net/fsockopen), use this + for UNIX and TCP sockets. See an [example](sockets.md). +- _AmqpHandler_: Logs records to an [amqp](http://www.amqp.org/) compatible + server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+). +- _GelfHandler_: Logs records to a [Graylog2](http://www.graylog2.org) server. +- _CubeHandler_: Logs records to a [Cube](http://square.github.com/cube/) server. +- _RavenHandler_: Logs records to a [Sentry](http://getsentry.com/) server using + [raven](https://packagist.org/packages/raven/raven). +- _ZendMonitorHandler_: Logs records to the Zend Monitor present in Zend Server. +- _NewRelicHandler_: Logs records to a [NewRelic](http://newrelic.com/) application. +- _LogglyHandler_: Logs records to a [Loggly](http://www.loggly.com/) account. +- _RollbarHandler_: Logs records to a [Rollbar](https://rollbar.com/) account. +- _SyslogUdpHandler_: Logs records to a remote [Syslogd](http://www.rsyslog.com/) server. +- _LogEntriesHandler_: Logs records to a [LogEntries](http://logentries.com/) account. + +### Logging in development + +- _FirePHPHandler_: Handler for [FirePHP](http://www.firephp.org/), providing + inline `console` messages within [FireBug](http://getfirebug.com/). +- _ChromePHPHandler_: Handler for [ChromePHP](http://www.chromephp.com/), providing + inline `console` messages within Chrome. +- _BrowserConsoleHandler_: Handler to send logs to browser's Javascript `console` with + no browser extension required. Most browsers supporting `console` API are supported. +- _PHPConsoleHandler_: Handler for [PHP Console](https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef), providing + inline `console` and notification popup messages within Chrome. + +### Log to databases + +- _RedisHandler_: Logs records to a [redis](http://redis.io) server. +- _MongoDBHandler_: Handler to write records in MongoDB via a + [Mongo](http://pecl.php.net/package/mongo) extension connection. +- _CouchDBHandler_: Logs records to a CouchDB server. +- _DoctrineCouchDBHandler_: Logs records to a CouchDB server via the Doctrine CouchDB ODM. +- _ElasticSearchHandler_: Logs records to an Elastic Search server. +- _DynamoDbHandler_: Logs records to a DynamoDB table with the [AWS SDK](https://github.com/aws/aws-sdk-php). + +### Wrappers / Special Handlers + +- _FingersCrossedHandler_: A very interesting wrapper. It takes a logger as + parameter and will accumulate log records of all levels until a record + exceeds the defined severity level. At which point it delivers all records, + including those of lower severity, to the handler it wraps. This means that + until an error actually happens you will not see anything in your logs, but + when it happens you will have the full information, including debug and info + records. This provides you with all the information you need, but only when + you need it. +- _WhatFailureGroupHandler_: This handler extends the _GroupHandler_ ignoring + exceptions raised by each child handler. This allows you to ignore issues + where a remote tcp connection may have died but you do not want your entire + application to crash and may wish to continue to log to other handlers. +- _BufferHandler_: This handler will buffer all the log records it receives + until `close()` is called at which point it will call `handleBatch()` on the + handler it wraps with all the log messages at once. This is very useful to + send an email with all records at once for example instead of having one mail + for every log record. +- _GroupHandler_: This handler groups other handlers. Every record received is + sent to all the handlers it is configured with. +- _FilterHandler_: This handler only lets records of the given levels through + to the wrapped handler. +- _SamplingHandler_: Wraps around another handler and lets you sample records + if you only want to store some of them. +- _NullHandler_: Any record it can handle will be thrown away. This can be used + to put on top of an existing handler stack to disable it temporarily. +- _PsrHandler_: Can be used to forward log records to an existing PSR-3 logger +- _TestHandler_: Used for testing, it records everything that is sent to it and + has accessors to read out the information. + +## Formatters + +- _LineFormatter_: Formats a log record into a one-line string. +- _HtmlFormatter_: Used to format log records into a human readable html table, mainly suitable for emails. +- _NormalizerFormatter_: Normalizes objects/resources down to strings so a record can easily be serialized/encoded. +- _ScalarFormatter_: Used to format log records into an associative array of scalar values. +- _JsonFormatter_: Encodes a log record into json. +- _WildfireFormatter_: Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler. +- _ChromePHPFormatter_: Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler. +- _GelfMessageFormatter_: Used to format log records into Gelf message instances, only useful for the GelfHandler. +- _LogstashFormatter_: Used to format log records into [logstash](http://logstash.net/) event json, useful for any handler listed under inputs [here](http://logstash.net/docs/latest). +- _ElasticaFormatter_: Used to format log records into an Elastica\Document object, only useful for the ElasticSearchHandler. +- _LogglyFormatter_: Used to format log records into Loggly messages, only useful for the LogglyHandler. +- _FlowdockFormatter_: Used to format log records into Flowdock messages, only useful for the FlowdockHandler. +- _MongoDBFormatter_: Converts \DateTime instances to \MongoDate and objects recursively to arrays, only useful with the MongoDBHandler. + +## Processors + +- _IntrospectionProcessor_: Adds the line/file/class/method from which the log call originated. +- _WebProcessor_: Adds the current request URI, request method and client IP to a log record. +- _MemoryUsageProcessor_: Adds the current memory usage to a log record. +- _MemoryPeakUsageProcessor_: Adds the peak memory usage to a log record. +- _ProcessIdProcessor_: Adds the process id to a log record. +- _UidProcessor_: Adds a unique identifier to a log record. +- _GitProcessor_: Adds the current git branch and commit to a log record. +- _TagProcessor_: Adds an array of predefined tags to a log record. + +## Third Party Packages + +Third party handlers, formatters and processors are +[listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You +can also add your own there if you publish one. + +← [Usage](01-usage.md) | [Utility classes](03-utilities.md) → diff --git a/vendor/monolog/monolog/doc/03-utilities.md b/vendor/monolog/monolog/doc/03-utilities.md new file mode 100644 index 0000000..c62aa41 --- /dev/null +++ b/vendor/monolog/monolog/doc/03-utilities.md @@ -0,0 +1,13 @@ +# Utilities + +- _Registry_: The `Monolog\Registry` class lets you configure global loggers that you + can then statically access from anywhere. It is not really a best practice but can + help in some older codebases or for ease of use. +- _ErrorHandler_: The `Monolog\ErrorHandler` class allows you to easily register + a Logger instance as an exception handler, error handler or fatal error handler. +- _ErrorLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain log + level is reached. +- _ChannelLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain + log level is reached, depending on which channel received the log record. + +← [Handlers, Formatters and Processors](02-handlers-formatters-processors.md) | [Extending Monolog](04-extending.md) → diff --git a/vendor/monolog/monolog/doc/04-extending.md b/vendor/monolog/monolog/doc/04-extending.md new file mode 100644 index 0000000..ebd9104 --- /dev/null +++ b/vendor/monolog/monolog/doc/04-extending.md @@ -0,0 +1,76 @@ +# Extending Monolog + +Monolog is fully extensible, allowing you to adapt your logger to your needs. + +## Writing your own handler + +Monolog provides many built-in handlers. But if the one you need does not +exist, you can write it and use it in your logger. The only requirement is +to implement `Monolog\Handler\HandlerInterface`. + +Let's write a PDOHandler to log records to a database. We will extend the +abstract class provided by Monolog to keep things DRY. + +```php +pdo = $pdo; + parent::__construct($level, $bubble); + } + + protected function write(array $record) + { + if (!$this->initialized) { + $this->initialize(); + } + + $this->statement->execute(array( + 'channel' => $record['channel'], + 'level' => $record['level'], + 'message' => $record['formatted'], + 'time' => $record['datetime']->format('U'), + )); + } + + private function initialize() + { + $this->pdo->exec( + 'CREATE TABLE IF NOT EXISTS monolog ' + .'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)' + ); + $this->statement = $this->pdo->prepare( + 'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)' + ); + + $this->initialized = true; + } +} +``` + +You can now use this handler in your logger: + +```php +pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite'))); + +// You can now use your logger +$logger->addInfo('My logger is now ready'); +``` + +The `Monolog\Handler\AbstractProcessingHandler` class provides most of the +logic needed for the handler, including the use of processors and the formatting +of the record (which is why we use ``$record['formatted']`` instead of ``$record['message']``). + +← [Utility classes](03-utilities.md) diff --git a/vendor/monolog/monolog/doc/sockets.md b/vendor/monolog/monolog/doc/sockets.md new file mode 100644 index 0000000..ea9cf0e --- /dev/null +++ b/vendor/monolog/monolog/doc/sockets.md @@ -0,0 +1,39 @@ +Sockets Handler +=============== + +This handler allows you to write your logs to sockets using [fsockopen](http://php.net/fsockopen) +or [pfsockopen](http://php.net/pfsockopen). + +Persistent sockets are mainly useful in web environments where you gain some performance not closing/opening +the connections between requests. + +You can use a `unix://` prefix to access unix sockets and `udp://` to open UDP sockets instead of the default TCP. + +Basic Example +------------- + +```php +setPersistent(true); + +// Now add the handler +$logger->pushHandler($handler, Logger::DEBUG); + +// You can now use your logger +$logger->addInfo('My logger is now ready'); + +``` + +In this example, using syslog-ng, you should see the log on the log server: + + cweb1 [2012-02-26 00:12:03] my_logger.INFO: My logger is now ready [] [] + diff --git a/vendor/monolog/monolog/phpunit.xml.dist b/vendor/monolog/monolog/phpunit.xml.dist new file mode 100644 index 0000000..20d82b6 --- /dev/null +++ b/vendor/monolog/monolog/phpunit.xml.dist @@ -0,0 +1,19 @@ + + + + + + tests/Monolog/ + + + + + + src/Monolog/ + + + + + + + diff --git a/vendor/monolog/monolog/src/Monolog/ErrorHandler.php b/vendor/monolog/monolog/src/Monolog/ErrorHandler.php new file mode 100644 index 0000000..f21eb28 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/ErrorHandler.php @@ -0,0 +1,224 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; +use Monolog\Handler\AbstractHandler; + +/** + * Monolog error handler + * + * A facility to enable logging of runtime errors, exceptions and fatal errors. + * + * Quick setup: ErrorHandler::register($logger); + * + * @author Jordi Boggiano + */ +class ErrorHandler +{ + private $logger; + + private $previousExceptionHandler; + private $uncaughtExceptionLevel; + + private $previousErrorHandler; + private $errorLevelMap; + + private $hasFatalErrorHandler; + private $fatalLevel; + private $reservedMemory; + private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR); + + public function __construct(LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * Registers a new ErrorHandler for a given Logger + * + * By default it will handle errors, exceptions and fatal errors + * + * @param LoggerInterface $logger + * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling + * @param int|false $exceptionLevel a LogLevel::* constant, or false to disable exception handling + * @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling + * @return ErrorHandler + */ + public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null) + { + $handler = new static($logger); + if ($errorLevelMap !== false) { + $handler->registerErrorHandler($errorLevelMap); + } + if ($exceptionLevel !== false) { + $handler->registerExceptionHandler($exceptionLevel); + } + if ($fatalLevel !== false) { + $handler->registerFatalHandler($fatalLevel); + } + + return $handler; + } + + public function registerExceptionHandler($level = null, $callPrevious = true) + { + $prev = set_exception_handler(array($this, 'handleException')); + $this->uncaughtExceptionLevel = $level; + if ($callPrevious && $prev) { + $this->previousExceptionHandler = $prev; + } + } + + public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1) + { + $prev = set_error_handler(array($this, 'handleError'), $errorTypes); + $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap); + if ($callPrevious) { + $this->previousErrorHandler = $prev ?: true; + } + } + + public function registerFatalHandler($level = null, $reservedMemorySize = 20) + { + register_shutdown_function(array($this, 'handleFatalError')); + + $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize); + $this->fatalLevel = $level; + $this->hasFatalErrorHandler = true; + } + + protected function defaultErrorLevelMap() + { + return array( + E_ERROR => LogLevel::CRITICAL, + E_WARNING => LogLevel::WARNING, + E_PARSE => LogLevel::ALERT, + E_NOTICE => LogLevel::NOTICE, + E_CORE_ERROR => LogLevel::CRITICAL, + E_CORE_WARNING => LogLevel::WARNING, + E_COMPILE_ERROR => LogLevel::ALERT, + E_COMPILE_WARNING => LogLevel::WARNING, + E_USER_ERROR => LogLevel::ERROR, + E_USER_WARNING => LogLevel::WARNING, + E_USER_NOTICE => LogLevel::NOTICE, + E_STRICT => LogLevel::NOTICE, + E_RECOVERABLE_ERROR => LogLevel::ERROR, + E_DEPRECATED => LogLevel::NOTICE, + E_USER_DEPRECATED => LogLevel::NOTICE, + ); + } + + /** + * @private + */ + public function handleException($e) + { + $this->logger->log( + $this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel, + sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), + array('exception' => $e) + ); + + if ($this->previousExceptionHandler) { + call_user_func($this->previousExceptionHandler, $e); + } + + exit(255); + } + + /** + * @private + */ + public function handleError($code, $message, $file = '', $line = 0, $context = array()) + { + if (!(error_reporting() & $code)) { + return; + } + + // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries + if (!$this->hasFatalErrorHandler || !in_array($code, self::$fatalErrors, true)) { + $level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL; + $this->logger->log($level, self::codeToString($code).': '.$message, array('code' => $code, 'message' => $message, 'file' => $file, 'line' => $line)); + } + + if ($this->previousErrorHandler === true) { + return false; + } elseif ($this->previousErrorHandler) { + return call_user_func($this->previousErrorHandler, $code, $message, $file, $line, $context); + } + } + + /** + * @private + */ + public function handleFatalError() + { + $this->reservedMemory = null; + + $lastError = error_get_last(); + if ($lastError && in_array($lastError['type'], self::$fatalErrors, true)) { + $this->logger->log( + $this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel, + 'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'], + array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line']) + ); + + if ($this->logger instanceof Logger) { + foreach ($this->logger->getHandlers() as $handler) { + if ($handler instanceof AbstractHandler) { + $handler->close(); + } + } + } + } + } + + private static function codeToString($code) + { + switch ($code) { + case E_ERROR: + return 'E_ERROR'; + case E_WARNING: + return 'E_WARNING'; + case E_PARSE: + return 'E_PARSE'; + case E_NOTICE: + return 'E_NOTICE'; + case E_CORE_ERROR: + return 'E_CORE_ERROR'; + case E_CORE_WARNING: + return 'E_CORE_WARNING'; + case E_COMPILE_ERROR: + return 'E_COMPILE_ERROR'; + case E_COMPILE_WARNING: + return 'E_COMPILE_WARNING'; + case E_USER_ERROR: + return 'E_USER_ERROR'; + case E_USER_WARNING: + return 'E_USER_WARNING'; + case E_USER_NOTICE: + return 'E_USER_NOTICE'; + case E_STRICT: + return 'E_STRICT'; + case E_RECOVERABLE_ERROR: + return 'E_RECOVERABLE_ERROR'; + case E_DEPRECATED: + return 'E_DEPRECATED'; + case E_USER_DEPRECATED: + return 'E_USER_DEPRECATED'; + } + + return 'Unknown PHP error'; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php new file mode 100644 index 0000000..56d3e27 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +/** + * Formats a log message according to the ChromePHP array format + * + * @author Christophe Coevoet + */ +class ChromePHPFormatter implements FormatterInterface +{ + /** + * Translates Monolog log levels to Wildfire levels. + */ + private $logLevels = array( + Logger::DEBUG => 'log', + Logger::INFO => 'info', + Logger::NOTICE => 'info', + Logger::WARNING => 'warn', + Logger::ERROR => 'error', + Logger::CRITICAL => 'error', + Logger::ALERT => 'error', + Logger::EMERGENCY => 'error', + ); + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + // Retrieve the line and file if set and remove them from the formatted extra + $backtrace = 'unknown'; + if (isset($record['extra']['file']) && isset($record['extra']['line'])) { + $backtrace = $record['extra']['file'].' : '.$record['extra']['line']; + unset($record['extra']['file']); + unset($record['extra']['line']); + } + + $message = array('message' => $record['message']); + if ($record['context']) { + $message['context'] = $record['context']; + } + if ($record['extra']) { + $message['extra'] = $record['extra']; + } + if (count($message) === 1) { + $message = reset($message); + } + + return array( + $record['channel'], + $message, + $backtrace, + $this->logLevels[$record['level']], + ); + } + + public function formatBatch(array $records) + { + $formatted = array(); + + foreach ($records as $record) { + $formatted[] = $this->format($record); + } + + return $formatted; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php new file mode 100644 index 0000000..b0b0cf0 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Elastica\Document; + +/** + * Format a log message into an Elastica Document + * + * @author Jelle Vink + */ +class ElasticaFormatter extends NormalizerFormatter +{ + /** + * @var string Elastic search index name + */ + protected $index; + + /** + * @var string Elastic search document type + */ + protected $type; + + /** + * @param string $index Elastic Search index name + * @param string $type Elastic Search document type + */ + public function __construct($index, $type) + { + parent::__construct(\DateTime::ISO8601); + $this->index = $index; + $this->type = $type; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $record = parent::format($record); + + return $this->getDocument($record); + } + + /** + * Getter index + * @return string + */ + public function getIndex() + { + return $this->index; + } + + /** + * Getter type + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Convert a log message into an Elastica Document + * + * @param array $record Log message + * @return Document + */ + protected function getDocument($record) + { + $document = new Document(); + $document->setData($record); + $document->setType($this->type); + $document->setIndex($this->index); + + return $document; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php new file mode 100644 index 0000000..5094af3 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * formats the record to be used in the FlowdockHandler + * + * @author Dominik Liebler + */ +class FlowdockFormatter implements FormatterInterface +{ + /** + * @var string + */ + private $source; + + /** + * @var string + */ + private $sourceEmail; + + /** + * @param string $source + * @param string $sourceEmail + */ + public function __construct($source, $sourceEmail) + { + $this->source = $source; + $this->sourceEmail = $sourceEmail; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $tags = array( + '#logs', + '#' . strtolower($record['level_name']), + '#' . $record['channel'], + ); + + foreach ($record['extra'] as $value) { + $tags[] = '#' . $value; + } + + $subject = sprintf( + 'in %s: %s - %s', + $this->source, + $record['level_name'], + $this->getShortMessage($record['message']) + ); + + $record['flowdock'] = array( + 'source' => $this->source, + 'from_address' => $this->sourceEmail, + 'subject' => $subject, + 'content' => $record['message'], + 'tags' => $tags, + 'project' => $this->source, + ); + + return $record; + } + + /** + * {@inheritdoc} + */ + public function formatBatch(array $records) + { + $formatted = array(); + + foreach ($records as $record) { + $formatted[] = $this->format($record); + } + + return $formatted; + } + + /** + * @param string $message + * + * @return string + */ + public function getShortMessage($message) + { + static $hasMbString; + + if (null === $hasMbString) { + $hasMbString = function_exists('mb_strlen'); + } + + $maxLength = 45; + + if ($hasMbString) { + if (mb_strlen($message, 'UTF-8') > $maxLength) { + $message = mb_substr($message, 0, $maxLength - 4, 'UTF-8') . ' ...'; + } + } else { + if (strlen($message) > $maxLength) { + $message = substr($message, 0, $maxLength - 4) . ' ...'; + } + } + + return $message; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php b/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php new file mode 100644 index 0000000..b5de751 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Interface for formatters + * + * @author Jordi Boggiano + */ +interface FormatterInterface +{ + /** + * Formats a log record. + * + * @param array $record A record to format + * @return mixed The formatted record + */ + public function format(array $record); + + /** + * Formats a set of log records. + * + * @param array $records A set of records to format + * @return mixed The formatted set of records + */ + public function formatBatch(array $records); +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php new file mode 100644 index 0000000..1e43175 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php @@ -0,0 +1,111 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; +use Gelf\Message; + +/** + * Serializes a log message to GELF + * @see http://www.graylog2.org/about/gelf + * + * @author Matt Lehner + */ +class GelfMessageFormatter extends NormalizerFormatter +{ + /** + * @var string the name of the system for the Gelf log message + */ + protected $systemName; + + /** + * @var string a prefix for 'extra' fields from the Monolog record (optional) + */ + protected $extraPrefix; + + /** + * @var string a prefix for 'context' fields from the Monolog record (optional) + */ + protected $contextPrefix; + + /** + * Translates Monolog log levels to Graylog2 log priorities. + */ + private $logLevels = array( + Logger::DEBUG => 7, + Logger::INFO => 6, + Logger::NOTICE => 5, + Logger::WARNING => 4, + Logger::ERROR => 3, + Logger::CRITICAL => 2, + Logger::ALERT => 1, + Logger::EMERGENCY => 0, + ); + + public function __construct($systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_') + { + parent::__construct('U.u'); + + $this->systemName = $systemName ?: gethostname(); + + $this->extraPrefix = $extraPrefix; + $this->contextPrefix = $contextPrefix; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $record = parent::format($record); + + if (!isset($record['datetime'], $record['message'], $record['level'])) { + throw new \InvalidArgumentException('The record should at least contain datetime, message and level keys, '.var_export($record, true).' given'); + } + + $message = new Message(); + $message + ->setTimestamp($record['datetime']) + ->setShortMessage((string) $record['message']) + ->setHost($this->systemName) + ->setLevel($this->logLevels[$record['level']]); + + if (isset($record['channel'])) { + $message->setFacility($record['channel']); + } + if (isset($record['extra']['line'])) { + $message->setLine($record['extra']['line']); + unset($record['extra']['line']); + } + if (isset($record['extra']['file'])) { + $message->setFile($record['extra']['file']); + unset($record['extra']['file']); + } + + foreach ($record['extra'] as $key => $val) { + $message->setAdditional($this->extraPrefix . $key, is_scalar($val) ? $val : $this->toJson($val)); + } + + foreach ($record['context'] as $key => $val) { + $message->setAdditional($this->contextPrefix . $key, is_scalar($val) ? $val : $this->toJson($val)); + } + + if (null === $message->getFile() && isset($record['context']['exception']['file'])) { + if (preg_match("/^(.+):([0-9]+)$/", $record['context']['exception']['file'], $matches)) { + $message->setFile($matches[1]); + $message->setLine($matches[2]); + } + } + + return $message; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php new file mode 100644 index 0000000..255d288 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +/** + * Formats incoming records into an HTML table + * + * This is especially useful for html email logging + * + * @author Tiago Brito + */ +class HtmlFormatter extends NormalizerFormatter +{ + /** + * Translates Monolog log levels to html color priorities. + */ + private $logLevels = array( + Logger::DEBUG => '#cccccc', + Logger::INFO => '#468847', + Logger::NOTICE => '#3a87ad', + Logger::WARNING => '#c09853', + Logger::ERROR => '#f0ad4e', + Logger::CRITICAL => '#FF7708', + Logger::ALERT => '#C12A19', + Logger::EMERGENCY => '#000000', + ); + + /** + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + */ + public function __construct($dateFormat = null) + { + parent::__construct($dateFormat); + } + + /** + * Creates an HTML table row + * + * @param string $th Row header content + * @param string $td Row standard cell content + * @param bool $escapeTd false if td content must not be html escaped + * @return string + */ + private function addRow($th, $td = ' ', $escapeTd = true) + { + $th = htmlspecialchars($th, ENT_NOQUOTES, 'UTF-8'); + if ($escapeTd) { + $td = '
    '.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'
    '; + } + + return "\n$th:\n".$td."\n"; + } + + /** + * Create a HTML h1 tag + * + * @param string $title Text to be in the h1 + * @param integer $level Error level + * @return string + */ + private function addTitle($title, $level) + { + $title = htmlspecialchars($title, ENT_NOQUOTES, 'UTF-8'); + + return '

    '.$title.'

    '; + } + /** + * Formats a log record. + * + * @param array $record A record to format + * @return mixed The formatted record + */ + public function format(array $record) + { + $output = $this->addTitle($record['level_name'], $record['level']); + $output .= ''; + + $output .= $this->addRow('Message', (string) $record['message']); + $output .= $this->addRow('Time', $record['datetime']->format($this->dateFormat)); + $output .= $this->addRow('Channel', $record['channel']); + if ($record['context']) { + $embeddedTable = '
    '; + foreach ($record['context'] as $key => $value) { + $embeddedTable .= $this->addRow($key, $this->convertToString($value)); + } + $embeddedTable .= '
    '; + $output .= $this->addRow('Context', $embeddedTable, false); + } + if ($record['extra']) { + $embeddedTable = ''; + foreach ($record['extra'] as $key => $value) { + $embeddedTable .= $this->addRow($key, $this->convertToString($value)); + } + $embeddedTable .= '
    '; + $output .= $this->addRow('Extra', $embeddedTable, false); + } + + return $output.''; + } + + /** + * Formats a set of log records. + * + * @param array $records A set of records to format + * @return mixed The formatted set of records + */ + public function formatBatch(array $records) + { + $message = ''; + foreach ($records as $record) { + $message .= $this->format($record); + } + + return $message; + } + + protected function convertToString($data) + { + if (null === $data || is_scalar($data)) { + return (string) $data; + } + + $data = $this->normalize($data); + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + return str_replace('\\/', '/', json_encode($data)); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php new file mode 100644 index 0000000..e5a1d2c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Encodes whatever record data is passed to it as json + * + * This can be useful to log to databases or remote APIs + * + * @author Jordi Boggiano + */ +class JsonFormatter implements FormatterInterface +{ + const BATCH_MODE_JSON = 1; + const BATCH_MODE_NEWLINES = 2; + + protected $batchMode; + protected $appendNewline; + + /** + * @param int $batchMode + */ + public function __construct($batchMode = self::BATCH_MODE_JSON, $appendNewline = true) + { + $this->batchMode = $batchMode; + $this->appendNewline = $appendNewline; + } + + /** + * The batch mode option configures the formatting style for + * multiple records. By default, multiple records will be + * formatted as a JSON-encoded array. However, for + * compatibility with some API endpoints, alternative styles + * are available. + * + * @return int + */ + public function getBatchMode() + { + return $this->batchMode; + } + + /** + * True if newlines are appended to every formatted record + * + * @return bool + */ + public function isAppendingNewlines() + { + return $this->appendNewline; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + return json_encode($record) . ($this->appendNewline ? "\n" : ''); + } + + /** + * {@inheritdoc} + */ + public function formatBatch(array $records) + { + switch ($this->batchMode) { + case static::BATCH_MODE_NEWLINES: + return $this->formatBatchNewlines($records); + + case static::BATCH_MODE_JSON: + default: + return $this->formatBatchJson($records); + } + } + + /** + * Return a JSON-encoded array of records. + * + * @param array $records + * @return string + */ + protected function formatBatchJson(array $records) + { + return json_encode($records); + } + + /** + * Use new lines to separate records instead of a + * JSON-encoded array. + * + * @param array $records + * @return string + */ + protected function formatBatchNewlines(array $records) + { + $instance = $this; + + $oldNewline = $this->appendNewline; + $this->appendNewline = false; + array_walk($records, function (&$value, $key) use ($instance) { + $value = $instance->format($value); + }); + $this->appendNewline = $oldNewline; + + return implode("\n", $records); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php new file mode 100644 index 0000000..388e226 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Exception; + +/** + * Formats incoming records into a one-line string + * + * This is especially useful for logging to files + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +class LineFormatter extends NormalizerFormatter +{ + const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"; + + protected $format; + protected $allowInlineLineBreaks; + protected $ignoreEmptyContextAndExtra; + protected $includeStacktraces; + + /** + * @param string $format The format of the message + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + * @param bool $allowInlineLineBreaks Whether to allow inline line breaks in log entries + * @param bool $ignoreEmptyContextAndExtra + */ + public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false, $ignoreEmptyContextAndExtra = false) + { + $this->format = $format ?: static::SIMPLE_FORMAT; + $this->allowInlineLineBreaks = $allowInlineLineBreaks; + $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra; + parent::__construct($dateFormat); + } + + public function includeStacktraces($include = true) + { + $this->includeStacktraces = $include; + if ($this->includeStacktraces) { + $this->allowInlineLineBreaks = true; + } + } + + public function allowInlineLineBreaks($allow = true) + { + $this->allowInlineLineBreaks = $allow; + } + + public function ignoreEmptyContextAndExtra($ignore = true) + { + $this->ignoreEmptyContextAndExtra = $ignore; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $vars = parent::format($record); + + $output = $this->format; + + foreach ($vars['extra'] as $var => $val) { + if (false !== strpos($output, '%extra.'.$var.'%')) { + $output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output); + unset($vars['extra'][$var]); + } + } + + if ($this->ignoreEmptyContextAndExtra) { + if (empty($vars['context'])) { + unset($vars['context']); + $output = str_replace('%context%', '', $output); + } + + if (empty($vars['extra'])) { + unset($vars['extra']); + $output = str_replace('%extra%', '', $output); + } + } + + foreach ($vars as $var => $val) { + if (false !== strpos($output, '%'.$var.'%')) { + $output = str_replace('%'.$var.'%', $this->stringify($val), $output); + } + } + + return $output; + } + + public function formatBatch(array $records) + { + $message = ''; + foreach ($records as $record) { + $message .= $this->format($record); + } + + return $message; + } + + public function stringify($value) + { + return $this->replaceNewlines($this->convertToString($value)); + } + + protected function normalizeException(Exception $e) + { + $previousText = ''; + if ($previous = $e->getPrevious()) { + do { + $previousText .= ', '.get_class($previous).'(code: '.$previous->getCode().'): '.$previous->getMessage().' at '.$previous->getFile().':'.$previous->getLine(); + } while ($previous = $previous->getPrevious()); + } + + $str = '[object] ('.get_class($e).'(code: '.$e->getCode().'): '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().$previousText.')'; + if ($this->includeStacktraces) { + $str .= "\n[stacktrace]\n".$e->getTraceAsString(); + } + + return $str; + } + + protected function convertToString($data) + { + if (null === $data || is_bool($data)) { + return var_export($data, true); + } + + if (is_scalar($data)) { + return (string) $data; + } + + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return $this->toJson($data, true); + } + + return str_replace('\\/', '/', @json_encode($data)); + } + + protected function replaceNewlines($str) + { + if ($this->allowInlineLineBreaks) { + return $str; + } + + return str_replace(array("\r\n", "\r", "\n"), ' ', $str); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php new file mode 100644 index 0000000..f02bceb --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Encodes message information into JSON in a format compatible with Loggly. + * + * @author Adam Pancutt + */ +class LogglyFormatter extends JsonFormatter +{ + /** + * Overrides the default batch mode to new lines for compatibility with the + * Loggly bulk API. + * + * @param integer $batchMode + */ + public function __construct($batchMode = self::BATCH_MODE_NEWLINES, $appendNewline = false) + { + parent::__construct($batchMode, $appendNewline); + } + + /** + * Appends the 'timestamp' parameter for indexing by Loggly. + * + * @see https://www.loggly.com/docs/automated-parsing/#json + * @see \Monolog\Formatter\JsonFormatter::format() + */ + public function format(array $record) + { + if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTime)) { + $record["timestamp"] = $record["datetime"]->format("Y-m-d\TH:i:s.uO"); + // TODO 2.0 unset the 'datetime' parameter, retained for BC + } + + return parent::format($record); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php new file mode 100644 index 0000000..be21b2c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php @@ -0,0 +1,166 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Serializes a log message to Logstash Event Format + * + * @see http://logstash.net/ + * @see https://github.com/logstash/logstash/blob/master/lib/logstash/event.rb + * + * @author Tim Mower + */ +class LogstashFormatter extends NormalizerFormatter +{ + const V0 = 0; + const V1 = 1; + + /** + * @var string the name of the system for the Logstash log message, used to fill the @source field + */ + protected $systemName; + + /** + * @var string an application name for the Logstash log message, used to fill the @type field + */ + protected $applicationName; + + /** + * @var string a prefix for 'extra' fields from the Monolog record (optional) + */ + protected $extraPrefix; + + /** + * @var string a prefix for 'context' fields from the Monolog record (optional) + */ + protected $contextPrefix; + + /** + * @var integer logstash format version to use + */ + protected $version; + + /** + * @param string $applicationName the application that sends the data, used as the "type" field of logstash + * @param string $systemName the system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine + * @param string $extraPrefix prefix for extra keys inside logstash "fields" + * @param string $contextPrefix prefix for context keys inside logstash "fields", defaults to ctxt_ + * @param integer $version the logstash format version to use, defaults to 0 + */ + public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $version = self::V0) + { + // logstash requires a ISO 8601 format date with optional millisecond precision. + parent::__construct('Y-m-d\TH:i:s.uP'); + + $this->systemName = $systemName ?: gethostname(); + $this->applicationName = $applicationName; + $this->extraPrefix = $extraPrefix; + $this->contextPrefix = $contextPrefix; + $this->version = $version; + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + $record = parent::format($record); + + if ($this->version === self::V1) { + $message = $this->formatV1($record); + } else { + $message = $this->formatV0($record); + } + + return $this->toJson($message) . "\n"; + } + + protected function formatV0(array $record) + { + if (empty($record['datetime'])) { + $record['datetime'] = gmdate('c'); + } + $message = array( + '@timestamp' => $record['datetime'], + '@source' => $this->systemName, + '@fields' => array() + ); + if (isset($record['message'])) { + $message['@message'] = $record['message']; + } + if (isset($record['channel'])) { + $message['@tags'] = array($record['channel']); + $message['@fields']['channel'] = $record['channel']; + } + if (isset($record['level'])) { + $message['@fields']['level'] = $record['level']; + } + if ($this->applicationName) { + $message['@type'] = $this->applicationName; + } + if (isset($record['extra']['server'])) { + $message['@source_host'] = $record['extra']['server']; + } + if (isset($record['extra']['url'])) { + $message['@source_path'] = $record['extra']['url']; + } + if (!empty($record['extra'])) { + foreach ($record['extra'] as $key => $val) { + $message['@fields'][$this->extraPrefix . $key] = $val; + } + } + if (!empty($record['context'])) { + foreach ($record['context'] as $key => $val) { + $message['@fields'][$this->contextPrefix . $key] = $val; + } + } + + return $message; + } + + protected function formatV1(array $record) + { + if (empty($record['datetime'])) { + $record['datetime'] = gmdate('c'); + } + $message = array( + '@timestamp' => $record['datetime'], + '@version' => 1, + 'host' => $this->systemName, + ); + if (isset($record['message'])) { + $message['message'] = $record['message']; + } + if (isset($record['channel'])) { + $message['type'] = $record['channel']; + $message['channel'] = $record['channel']; + } + if (isset($record['level_name'])) { + $message['level'] = $record['level_name']; + } + if ($this->applicationName) { + $message['type'] = $this->applicationName; + } + if (!empty($record['extra'])) { + foreach ($record['extra'] as $key => $val) { + $message[$this->extraPrefix . $key] = $val; + } + } + if (!empty($record['context'])) { + foreach ($record['context'] as $key => $val) { + $message[$this->contextPrefix . $key] = $val; + } + } + + return $message; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php new file mode 100644 index 0000000..eb067bb --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Formats a record for use with the MongoDBHandler. + * + * @author Florian Plattner + */ +class MongoDBFormatter implements FormatterInterface +{ + private $exceptionTraceAsString; + private $maxNestingLevel; + + /** + * @param int $maxNestingLevel 0 means infinite nesting, the $record itself is level 1, $record['context'] is 2 + * @param bool $exceptionTraceAsString set to false to log exception traces as a sub documents instead of strings + */ + public function __construct($maxNestingLevel = 3, $exceptionTraceAsString = true) + { + $this->maxNestingLevel = max($maxNestingLevel, 0); + $this->exceptionTraceAsString = (bool) $exceptionTraceAsString; + } + + /** + * {@inheritDoc} + */ + public function format(array $record) + { + return $this->formatArray($record); + } + + /** + * {@inheritDoc} + */ + public function formatBatch(array $records) + { + foreach ($records as $key => $record) { + $records[$key] = $this->format($record); + } + + return $records; + } + + protected function formatArray(array $record, $nestingLevel = 0) + { + if ($this->maxNestingLevel == 0 || $nestingLevel <= $this->maxNestingLevel) { + foreach ($record as $name => $value) { + if ($value instanceof \DateTime) { + $record[$name] = $this->formatDate($value, $nestingLevel + 1); + } elseif ($value instanceof \Exception) { + $record[$name] = $this->formatException($value, $nestingLevel + 1); + } elseif (is_array($value)) { + $record[$name] = $this->formatArray($value, $nestingLevel + 1); + } elseif (is_object($value)) { + $record[$name] = $this->formatObject($value, $nestingLevel + 1); + } + } + } else { + $record = '[...]'; + } + + return $record; + } + + protected function formatObject($value, $nestingLevel) + { + $objectVars = get_object_vars($value); + $objectVars['class'] = get_class($value); + + return $this->formatArray($objectVars, $nestingLevel); + } + + protected function formatException(\Exception $exception, $nestingLevel) + { + $formattedException = array( + 'class' => get_class($exception), + 'message' => $exception->getMessage(), + 'code' => $exception->getCode(), + 'file' => $exception->getFile() . ':' . $exception->getLine(), + ); + + if ($this->exceptionTraceAsString === true) { + $formattedException['trace'] = $exception->getTraceAsString(); + } else { + $formattedException['trace'] = $exception->getTrace(); + } + + return $this->formatArray($formattedException, $nestingLevel); + } + + protected function formatDate(\DateTime $value, $nestingLevel) + { + return new \MongoDate($value->getTimestamp()); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php new file mode 100644 index 0000000..0361935 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php @@ -0,0 +1,193 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Exception; + +/** + * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets + * + * @author Jordi Boggiano + */ +class NormalizerFormatter implements FormatterInterface +{ + const SIMPLE_DATE = "Y-m-d H:i:s"; + + protected $dateFormat; + + /** + * @param string $dateFormat The format of the timestamp: one supported by DateTime::format + */ + public function __construct($dateFormat = null) + { + $this->dateFormat = $dateFormat ?: static::SIMPLE_DATE; + if (!function_exists('json_encode')) { + throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter'); + } + } + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + return $this->normalize($record); + } + + /** + * {@inheritdoc} + */ + public function formatBatch(array $records) + { + foreach ($records as $key => $record) { + $records[$key] = $this->format($record); + } + + return $records; + } + + protected function normalize($data) + { + if (null === $data || is_scalar($data)) { + if (is_float($data)) { + if (is_infinite($data)) { + return ($data > 0 ? '' : '-') . 'INF'; + } + if (is_nan($data)) { + return 'NaN'; + } + } + + return $data; + } + + if (is_array($data) || $data instanceof \Traversable) { + $normalized = array(); + + $count = 1; + foreach ($data as $key => $value) { + if ($count++ >= 1000) { + $normalized['...'] = 'Over 1000 items, aborting normalization'; + break; + } + $normalized[$key] = $this->normalize($value); + } + + return $normalized; + } + + if ($data instanceof \DateTime) { + return $data->format($this->dateFormat); + } + + if (is_object($data)) { + if ($data instanceof Exception) { + return $this->normalizeException($data); + } + + // non-serializable objects that implement __toString stringified + if (method_exists($data, '__toString') && !$data instanceof \JsonSerializable) { + $value = (string) $data; + } else { + // the rest is json-serialized in some way + $value = $this->toJson($data, true); + } + + return sprintf("[object] (%s: %s)", get_class($data), $value); + } + + if (is_resource($data)) { + return sprintf('[resource] (%s)', get_resource_type($data)); + } + + return '[unknown('.gettype($data).')]'; + } + + protected function normalizeException(Exception $e) + { + $data = array( + 'class' => get_class($e), + 'message' => $e->getMessage(), + 'code' => $e->getCode(), + 'file' => $e->getFile().':'.$e->getLine(), + ); + + $trace = $e->getTrace(); + foreach ($trace as $frame) { + if (isset($frame['file'])) { + $data['trace'][] = $frame['file'].':'.$frame['line']; + } else { + // We should again normalize the frames, because it might contain invalid items + $data['trace'][] = $this->toJson($this->normalize($frame), true); + } + } + + if ($previous = $e->getPrevious()) { + $data['previous'] = $this->normalizeException($previous); + } + + return $data; + } + + protected function toJson($data, $ignoreErrors = false) + { + // suppress json_encode errors since it's twitchy with some inputs + if ($ignoreErrors) { + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return @json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + return @json_encode($data); + } + + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + $json = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } else { + $json = json_encode($data); + } + + if ($json === false) { + $this->throwEncodeError(json_last_error(), $data); + } + + return $json; + } + + /** + * Throws an exception according to a given code with a customized message + * + * @param int $code return code of json_last_error function + * @param mixed $data data that was meant to be encoded + * @throws \RuntimeException + */ + private function throwEncodeError($code, $data) + { + switch ($code) { + case JSON_ERROR_DEPTH: + $msg = 'Maximum stack depth exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + $msg = 'Underflow or the modes mismatch'; + break; + case JSON_ERROR_CTRL_CHAR: + $msg = 'Unexpected control character found'; + break; + case JSON_ERROR_UTF8: + $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + default: + $msg = 'Unknown error'; + } + + throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true)); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php new file mode 100644 index 0000000..5d345d5 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * Formats data into an associative array of scalar values. + * Objects and arrays will be JSON encoded. + * + * @author Andrew Lawson + */ +class ScalarFormatter extends NormalizerFormatter +{ + /** + * {@inheritdoc} + */ + public function format(array $record) + { + foreach ($record as $key => $value) { + $record[$key] = $this->normalizeValue($value); + } + + return $record; + } + + /** + * @param mixed $value + * @return mixed + */ + protected function normalizeValue($value) + { + $normalized = $this->normalize($value); + + if (is_array($normalized) || is_object($normalized)) { + return $this->toJson($normalized, true); + } + + return $normalized; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php b/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php new file mode 100644 index 0000000..654710a --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +/** + * Serializes a log message according to Wildfire's header requirements + * + * @author Eric Clemmons (@ericclemmons) + * @author Christophe Coevoet + * @author Kirill chEbba Chebunin + */ +class WildfireFormatter extends NormalizerFormatter +{ + const TABLE = 'table'; + + /** + * Translates Monolog log levels to Wildfire levels. + */ + private $logLevels = array( + Logger::DEBUG => 'LOG', + Logger::INFO => 'INFO', + Logger::NOTICE => 'INFO', + Logger::WARNING => 'WARN', + Logger::ERROR => 'ERROR', + Logger::CRITICAL => 'ERROR', + Logger::ALERT => 'ERROR', + Logger::EMERGENCY => 'ERROR', + ); + + /** + * {@inheritdoc} + */ + public function format(array $record) + { + // Retrieve the line and file if set and remove them from the formatted extra + $file = $line = ''; + if (isset($record['extra']['file'])) { + $file = $record['extra']['file']; + unset($record['extra']['file']); + } + if (isset($record['extra']['line'])) { + $line = $record['extra']['line']; + unset($record['extra']['line']); + } + + $record = $this->normalize($record); + $message = array('message' => $record['message']); + $handleError = false; + if ($record['context']) { + $message['context'] = $record['context']; + $handleError = true; + } + if ($record['extra']) { + $message['extra'] = $record['extra']; + $handleError = true; + } + if (count($message) === 1) { + $message = reset($message); + } + + if (isset($record['context'][self::TABLE])) { + $type = 'TABLE'; + $label = $record['channel'] .': '. $record['message']; + $message = $record['context'][self::TABLE]; + } else { + $type = $this->logLevels[$record['level']]; + $label = $record['channel']; + } + + // Create JSON object describing the appearance of the message in the console + $json = $this->toJson(array( + array( + 'Type' => $type, + 'File' => $file, + 'Line' => $line, + 'Label' => $label, + ), + $message, + ), $handleError); + + // The message itself is a serialization of the above JSON object + it's length + return sprintf( + '%s|%s|', + strlen($json), + $json + ); + } + + public function formatBatch(array $records) + { + throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter'); + } + + protected function normalize($data) + { + if (is_object($data) && !$data instanceof \DateTime) { + return $data; + } + + return parent::normalize($data); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php new file mode 100644 index 0000000..69ede49 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php @@ -0,0 +1,184 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\LineFormatter; + +/** + * Base Handler class providing the Handler structure + * + * @author Jordi Boggiano + */ +abstract class AbstractHandler implements HandlerInterface +{ + protected $level = Logger::DEBUG; + protected $bubble = true; + + /** + * @var FormatterInterface + */ + protected $formatter; + protected $processors = array(); + + /** + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($level = Logger::DEBUG, $bubble = true) + { + $this->setLevel($level); + $this->bubble = $bubble; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return $record['level'] >= $this->level; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + foreach ($records as $record) { + $this->handle($record); + } + } + + /** + * Closes the handler. + * + * This will be called automatically when the object is destroyed + */ + public function close() + { + } + + /** + * {@inheritdoc} + */ + public function pushProcessor($callback) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); + } + array_unshift($this->processors, $callback); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function popProcessor() + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + + return array_shift($this->processors); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + $this->formatter = $formatter; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getFormatter() + { + if (!$this->formatter) { + $this->formatter = $this->getDefaultFormatter(); + } + + return $this->formatter; + } + + /** + * Sets minimum logging level at which this handler will be triggered. + * + * @param integer $level + * @return self + */ + public function setLevel($level) + { + $this->level = Logger::toMonologLevel($level); + + return $this; + } + + /** + * Gets minimum logging level at which this handler will be triggered. + * + * @return integer + */ + public function getLevel() + { + return $this->level; + } + + /** + * Sets the bubbling behavior. + * + * @param Boolean $bubble true means that this handler allows bubbling. + * false means that bubbling is not permitted. + * @return self + */ + public function setBubble($bubble) + { + $this->bubble = $bubble; + + return $this; + } + + /** + * Gets the bubbling behavior. + * + * @return Boolean true means that this handler allows bubbling. + * false means that bubbling is not permitted. + */ + public function getBubble() + { + return $this->bubble; + } + + public function __destruct() + { + try { + $this->close(); + } catch (\Exception $e) { + // do nothing + } + } + + /** + * Gets the default formatter. + * + * @return FormatterInterface + */ + protected function getDefaultFormatter() + { + return new LineFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php new file mode 100644 index 0000000..6f18f72 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Base Handler class providing the Handler structure + * + * Classes extending it should (in most cases) only implement write($record) + * + * @author Jordi Boggiano + * @author Christophe Coevoet + */ +abstract class AbstractProcessingHandler extends AbstractHandler +{ + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if (!$this->isHandling($record)) { + return false; + } + + $record = $this->processRecord($record); + + $record['formatted'] = $this->getFormatter()->format($record); + + $this->write($record); + + return false === $this->bubble; + } + + /** + * Writes the record down to the log of the implementing handler + * + * @param array $record + * @return void + */ + abstract protected function write(array $record); + + /** + * Processes a record. + * + * @param array $record + * @return array + */ + protected function processRecord(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php new file mode 100644 index 0000000..3eb83bd --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +/** + * Common syslog functionality + */ +abstract class AbstractSyslogHandler extends AbstractProcessingHandler +{ + protected $facility; + + /** + * Translates Monolog log levels to syslog log priorities. + */ + protected $logLevels = array( + Logger::DEBUG => LOG_DEBUG, + Logger::INFO => LOG_INFO, + Logger::NOTICE => LOG_NOTICE, + Logger::WARNING => LOG_WARNING, + Logger::ERROR => LOG_ERR, + Logger::CRITICAL => LOG_CRIT, + Logger::ALERT => LOG_ALERT, + Logger::EMERGENCY => LOG_EMERG, + ); + + /** + * List of valid log facility names. + */ + protected $facilities = array( + 'auth' => LOG_AUTH, + 'authpriv' => LOG_AUTHPRIV, + 'cron' => LOG_CRON, + 'daemon' => LOG_DAEMON, + 'kern' => LOG_KERN, + 'lpr' => LOG_LPR, + 'mail' => LOG_MAIL, + 'news' => LOG_NEWS, + 'syslog' => LOG_SYSLOG, + 'user' => LOG_USER, + 'uucp' => LOG_UUCP, + ); + + /** + * @param mixed $facility + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->facilities['local0'] = LOG_LOCAL0; + $this->facilities['local1'] = LOG_LOCAL1; + $this->facilities['local2'] = LOG_LOCAL2; + $this->facilities['local3'] = LOG_LOCAL3; + $this->facilities['local4'] = LOG_LOCAL4; + $this->facilities['local5'] = LOG_LOCAL5; + $this->facilities['local6'] = LOG_LOCAL6; + $this->facilities['local7'] = LOG_LOCAL7; + } + + // convert textual description of facility to syslog constant + if (array_key_exists(strtolower($facility), $this->facilities)) { + $facility = $this->facilities[strtolower($facility)]; + } elseif (!in_array($facility, array_values($this->facilities), true)) { + throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); + } + + $this->facility = $facility; + } + + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%'); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php new file mode 100644 index 0000000..a28ba02 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\JsonFormatter; +use PhpAmqpLib\Message\AMQPMessage; +use PhpAmqpLib\Channel\AMQPChannel; +use AMQPExchange; + +class AmqpHandler extends AbstractProcessingHandler +{ + /** + * @var AMQPExchange|AMQPChannel $exchange + */ + protected $exchange; + + /** + * @var string + */ + protected $exchangeName; + + /** + * @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use + * @param string $exchangeName + * @param int $level + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($exchange, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = true) + { + if ($exchange instanceof AMQPExchange) { + $exchange->setName($exchangeName); + } elseif ($exchange instanceof AMQPChannel) { + $this->exchangeName = $exchangeName; + } else { + throw new \InvalidArgumentException('PhpAmqpLib\Channel\AMQPChannel or AMQPExchange instance required'); + } + $this->exchange = $exchange; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $data = $record["formatted"]; + + $routingKey = sprintf( + '%s.%s', + // TODO 2.0 remove substr call + substr($record['level_name'], 0, 4), + $record['channel'] + ); + + if ($this->exchange instanceof AMQPExchange) { + $this->exchange->publish( + $data, + strtolower($routingKey), + 0, + array( + 'delivery_mode' => 2, + 'Content-type' => 'application/json' + ) + ); + } else { + $this->exchange->basic_publish( + new AMQPMessage( + (string) $data, + array( + 'delivery_mode' => 2, + 'content_type' => 'application/json' + ) + ), + $this->exchangeName, + strtolower($routingKey) + ); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php new file mode 100644 index 0000000..a409952 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php @@ -0,0 +1,192 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; + +/** + * Handler sending logs to browser's javascript console with no browser extension required + * + * @author Olivier Poitrey + */ +class BrowserConsoleHandler extends AbstractProcessingHandler +{ + protected static $initialized = false; + protected static $records = array(); + + /** + * {@inheritDoc} + * + * Formatted output may contain some formatting markers to be transferred to `console.log` using the %c format. + * + * Example of formatted string: + * + * You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white} + * + */ + protected function getDefaultFormatter() + { + return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%'); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + // Accumulate records + self::$records[] = $record; + + // Register shutdown handler if not already done + if (PHP_SAPI !== 'cli' && !self::$initialized) { + self::$initialized = true; + register_shutdown_function(array('Monolog\Handler\BrowserConsoleHandler', 'send')); + } + } + + /** + * Convert records to javascript console commands and send it to the browser. + * This method is automatically called on PHP shutdown if output is HTML or Javascript. + */ + public static function send() + { + $htmlTags = true; + // Check content type + foreach (headers_list() as $header) { + if (stripos($header, 'content-type:') === 0) { + // This handler only works with HTML and javascript outputs + // text/javascript is obsolete in favour of application/javascript, but still used + if (stripos($header, 'application/javascript') !== false || stripos($header, 'text/javascript') !== false) { + $htmlTags = false; + } elseif (stripos($header, 'text/html') === false) { + return; + } + break; + } + } + + if (count(self::$records)) { + if ($htmlTags) { + echo ''; + } else { + echo self::generateScript(); + } + self::reset(); + } + } + + /** + * Forget all logged records + */ + public static function reset() + { + self::$records = array(); + } + + private static function generateScript() + { + $script = array(); + foreach (self::$records as $record) { + $context = self::dump('Context', $record['context']); + $extra = self::dump('Extra', $record['extra']); + + if (empty($context) && empty($extra)) { + $script[] = self::call_array('log', self::handleStyles($record['formatted'])); + } else { + $script = array_merge($script, + array(self::call_array('groupCollapsed', self::handleStyles($record['formatted']))), + $context, + $extra, + array(self::call('groupEnd')) + ); + } + } + + return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);"; + } + + private static function handleStyles($formatted) + { + $args = array(self::quote('font-weight: normal')); + $format = '%c' . $formatted; + preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); + + foreach (array_reverse($matches) as $match) { + $args[] = self::quote(self::handleCustomStyles($match[2][0], $match[1][0])); + $args[] = '"font-weight: normal"'; + + $pos = $match[0][1]; + $format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0])); + } + + array_unshift($args, self::quote($format)); + + return $args; + } + + private static function handleCustomStyles($style, $string) + { + static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey'); + static $labels = array(); + + return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function ($m) use ($string, &$colors, &$labels) { + if (trim($m[1]) === 'autolabel') { + // Format the string as a label with consistent auto assigned background color + if (!isset($labels[$string])) { + $labels[$string] = $colors[count($labels) % count($colors)]; + } + $color = $labels[$string]; + + return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px"; + } + + return $m[1]; + }, $style); + } + + private static function dump($title, array $dict) + { + $script = array(); + $dict = array_filter($dict); + if (empty($dict)) { + return $script; + } + $script[] = self::call('log', self::quote('%c%s'), self::quote('font-weight: bold'), self::quote($title)); + foreach ($dict as $key => $value) { + $value = json_encode($value); + if (empty($value)) { + $value = self::quote(''); + } + $script[] = self::call('log', self::quote('%s: %o'), self::quote($key), $value); + } + + return $script; + } + + private static function quote($arg) + { + return '"' . addcslashes($arg, "\"\n\\") . '"'; + } + + private static function call() + { + $args = func_get_args(); + $method = array_shift($args); + + return self::call_array($method, $args); + } + + private static function call_array($method, array $args) + { + return 'c.' . $method . '(' . implode(', ', $args) . ');'; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php new file mode 100644 index 0000000..6d8136f --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Buffers all records until closing the handler and then pass them as batch. + * + * This is useful for a MailHandler to send only one mail per request instead of + * sending one per log message. + * + * @author Christophe Coevoet + */ +class BufferHandler extends AbstractHandler +{ + protected $handler; + protected $bufferSize = 0; + protected $bufferLimit; + protected $flushOnOverflow; + protected $buffer = array(); + protected $initialized = false; + + /** + * @param HandlerInterface $handler Handler. + * @param integer $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded + */ + public function __construct(HandlerInterface $handler, $bufferLimit = 0, $level = Logger::DEBUG, $bubble = true, $flushOnOverflow = false) + { + parent::__construct($level, $bubble); + $this->handler = $handler; + $this->bufferLimit = (int) $bufferLimit; + $this->flushOnOverflow = $flushOnOverflow; + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return false; + } + + if (!$this->initialized) { + // __destructor() doesn't get called on Fatal errors + register_shutdown_function(array($this, 'close')); + $this->initialized = true; + } + + if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) { + if ($this->flushOnOverflow) { + $this->flush(); + } else { + array_shift($this->buffer); + $this->bufferSize--; + } + } + + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + $this->buffer[] = $record; + $this->bufferSize++; + + return false === $this->bubble; + } + + public function flush() + { + if ($this->bufferSize === 0) { + return; + } + + $this->handler->handleBatch($this->buffer); + $this->clear(); + } + + public function __destruct() + { + // suppress the parent behavior since we already have register_shutdown_function() + // to call close(), and the reference contained there will prevent this from being + // GC'd until the end of the request + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->flush(); + } + + /** + * Clears the buffer without flushing any messages down to the wrapped handler. + */ + public function clear() + { + $this->bufferSize = 0; + $this->buffer = array(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php new file mode 100644 index 0000000..b3f2963 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php @@ -0,0 +1,204 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\ChromePHPFormatter; +use Monolog\Logger; + +/** + * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/) + * + * @author Christophe Coevoet + */ +class ChromePHPHandler extends AbstractProcessingHandler +{ + /** + * Version of the extension + */ + const VERSION = '4.0'; + + /** + * Header name + */ + const HEADER_NAME = 'X-ChromeLogger-Data'; + + protected static $initialized = false; + + /** + * Tracks whether we sent too much data + * + * Chrome limits the headers to 256KB, so when we sent 240KB we stop sending + * + * @var Boolean + */ + protected static $overflowed = false; + + protected static $json = array( + 'version' => self::VERSION, + 'columns' => array('label', 'log', 'backtrace', 'type'), + 'rows' => array(), + ); + + protected static $sendHeaders = true; + + /** + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + if (!function_exists('json_encode')) { + throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s ChromePHPHandler'); + } + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + + if (!empty($messages)) { + $messages = $this->getFormatter()->formatBatch($messages); + self::$json['rows'] = array_merge(self::$json['rows'], $messages); + $this->send(); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new ChromePHPFormatter(); + } + + /** + * Creates & sends header for a record + * + * @see sendHeader() + * @see send() + * @param array $record + */ + protected function write(array $record) + { + self::$json['rows'][] = $record['formatted']; + + $this->send(); + } + + /** + * Sends the log header + * + * @see sendHeader() + */ + protected function send() + { + if (self::$overflowed || !self::$sendHeaders) { + return; + } + + if (!self::$initialized) { + self::$initialized = true; + + self::$sendHeaders = $this->headersAccepted(); + if (!self::$sendHeaders) { + return; + } + + self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; + } + + $json = @json_encode(self::$json); + $data = base64_encode(utf8_encode($json)); + if (strlen($data) > 240 * 1024) { + self::$overflowed = true; + + $record = array( + 'message' => 'Incomplete logs, chrome header size limit reached', + 'context' => array(), + 'level' => Logger::WARNING, + 'level_name' => Logger::getLevelName(Logger::WARNING), + 'channel' => 'monolog', + 'datetime' => new \DateTime(), + 'extra' => array(), + ); + self::$json['rows'][count(self::$json['rows']) - 1] = $this->getFormatter()->format($record); + $json = @json_encode(self::$json); + $data = base64_encode(utf8_encode($json)); + } + + if (trim($data) !== '') { + $this->sendHeader(self::HEADER_NAME, $data); + } + } + + /** + * Send header string to the client + * + * @param string $header + * @param string $content + */ + protected function sendHeader($header, $content) + { + if (!headers_sent() && self::$sendHeaders) { + header(sprintf('%s: %s', $header, $content)); + } + } + + /** + * Verifies if the headers are accepted by the current user agent + * + * @return Boolean + */ + protected function headersAccepted() + { + if (empty($_SERVER['HTTP_USER_AGENT'])) { + return false; + } + + return preg_match('{\bChrome/\d+[\.\d+]*\b}', $_SERVER['HTTP_USER_AGENT']); + } + + /** + * BC getter for the sendHeaders property that has been made static + */ + public function __get($property) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property '.$property); + } + + return static::$sendHeaders; + } + + /** + * BC setter for the sendHeaders property that has been made static + */ + public function __set($property, $value) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property '.$property); + } + + static::$sendHeaders = $value; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php new file mode 100644 index 0000000..b3687c3 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\JsonFormatter; +use Monolog\Logger; + +/** + * CouchDB handler + * + * @author Markus Bachmann + */ +class CouchDBHandler extends AbstractProcessingHandler +{ + private $options; + + public function __construct(array $options = array(), $level = Logger::DEBUG, $bubble = true) + { + $this->options = array_merge(array( + 'host' => 'localhost', + 'port' => 5984, + 'dbname' => 'logger', + 'username' => null, + 'password' => null, + ), $options); + + parent::__construct($level, $bubble); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $basicAuth = null; + if ($this->options['username']) { + $basicAuth = sprintf('%s:%s@', $this->options['username'], $this->options['password']); + } + + $url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname']; + $context = stream_context_create(array( + 'http' => array( + 'method' => 'POST', + 'content' => $record['formatted'], + 'ignore_errors' => true, + 'max_redirects' => 0, + 'header' => 'Content-type: application/json', + ) + )); + + if (false === @file_get_contents($url, null, $context)) { + throw new \RuntimeException(sprintf('Could not connect to %s', $url)); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php new file mode 100644 index 0000000..e7dd854 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Logs to Cube. + * + * @link http://square.github.com/cube/ + * @author Wan Chen + */ +class CubeHandler extends AbstractProcessingHandler +{ + private $udpConnection = null; + private $httpConnection = null; + private $scheme = null; + private $host = null; + private $port = null; + private $acceptedSchemes = array('http', 'udp'); + + /** + * Create a Cube handler + * + * @throws \UnexpectedValueException when given url is not a valid url. + * A valid url must consists of three parts : protocol://host:port + * Only valid protocol used by Cube are http and udp + */ + public function __construct($url, $level = Logger::DEBUG, $bubble = true) + { + $urlInfos = parse_url($url); + + if (!isset($urlInfos['scheme']) || !isset($urlInfos['host']) || !isset($urlInfos['port'])) { + throw new \UnexpectedValueException('URL "'.$url.'" is not valid'); + } + + if (!in_array($urlInfos['scheme'], $this->acceptedSchemes)) { + throw new \UnexpectedValueException( + 'Invalid protocol (' . $urlInfos['scheme'] . ').' + . ' Valid options are ' . implode(', ', $this->acceptedSchemes)); + } + + $this->scheme = $urlInfos['scheme']; + $this->host = $urlInfos['host']; + $this->port = $urlInfos['port']; + + parent::__construct($level, $bubble); + } + + /** + * Establish a connection to an UDP socket + * + * @throws \LogicException when unable to connect to the socket + */ + protected function connectUdp() + { + if (!extension_loaded('sockets')) { + throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler'); + } + + $this->udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0); + if (!$this->udpConnection) { + throw new \LogicException('Unable to create a socket'); + } + + if (!socket_connect($this->udpConnection, $this->host, $this->port)) { + throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port); + } + } + + /** + * Establish a connection to a http server + */ + protected function connectHttp() + { + if (!extension_loaded('curl')) { + throw new \LogicException('The curl extension is needed to use http URLs with the CubeHandler'); + } + + $this->httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put'); + + if (!$this->httpConnection) { + throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port); + } + + curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST"); + curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $date = $record['datetime']; + + $data = array('time' => $date->format('Y-m-d\TH:i:s.uO')); + unset($record['datetime']); + + if (isset($record['context']['type'])) { + $data['type'] = $record['context']['type']; + unset($record['context']['type']); + } else { + $data['type'] = $record['channel']; + } + + $data['data'] = $record['context']; + $data['data']['level'] = $record['level']; + + if ($this->scheme === 'http') { + $this->writeHttp(json_encode($data)); + } else { + $this->writeUdp(json_encode($data)); + } + } + + private function writeUdp($data) + { + if (!$this->udpConnection) { + $this->connectUdp(); + } + + socket_send($this->udpConnection, $data, strlen($data), 0); + } + + private function writeHttp($data) + { + if (!$this->httpConnection) { + $this->connectHttp(); + } + + curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']'); + curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, array( + 'Content-Type: application/json', + 'Content-Length: ' . strlen('['.$data.']')) + ); + + Curl\Util::execute($ch, 5, false); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php b/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php new file mode 100644 index 0000000..adbe4f4 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\Curl; + +class Util +{ + private static $retriableErrorCodes = array( + CURLE_COULDNT_RESOLVE_HOST, + CURLE_COULDNT_CONNECT, + CURLE_HTTP_NOT_FOUND, + CURLE_READ_ERROR, + CURLE_OPERATION_TIMEOUTED, + CURLE_HTTP_POST_ERROR, + CURLE_SSL_CONNECT_ERROR, + ); + + /** + * Executes a CURL request with optional retries and exception on failure + * + * @param resource $ch curl handler + * @throws \RuntimeException + */ + public static function execute($ch, $retries = 5, $closeAfterDone = true) + { + while ($retries--) { + if (curl_exec($ch) === false) { + $curlErrno = curl_errno($ch); + + if (false === in_array($curlErrno, self::$retriableErrorCodes, true) || !$retries) { + $curlError = curl_error($ch); + + if ($closeAfterDone) { + curl_close($ch); + } + + throw new \RuntimeException(sprintf('Curl error (code %s): %s', $curlErrno, $curlError)); + } + + continue; + } + + if ($closeAfterDone) { + curl_close($ch); + } + break; + } + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php new file mode 100644 index 0000000..b91ffec --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\NormalizerFormatter; +use Doctrine\CouchDB\CouchDBClient; + +/** + * CouchDB handler for Doctrine CouchDB ODM + * + * @author Markus Bachmann + */ +class DoctrineCouchDBHandler extends AbstractProcessingHandler +{ + private $client; + + public function __construct(CouchDBClient $client, $level = Logger::DEBUG, $bubble = true) + { + $this->client = $client; + parent::__construct($level, $bubble); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $this->client->postDocument($record['formatted']); + } + + protected function getDefaultFormatter() + { + return new NormalizerFormatter; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php new file mode 100644 index 0000000..e7f843c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Aws\Common\Aws; +use Aws\DynamoDb\DynamoDbClient; +use Monolog\Formatter\ScalarFormatter; +use Monolog\Logger; + +/** + * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/) + * + * @link https://github.com/aws/aws-sdk-php/ + * @author Andrew Lawson + */ +class DynamoDbHandler extends AbstractProcessingHandler +{ + const DATE_FORMAT = 'Y-m-d\TH:i:s.uO'; + + /** + * @var DynamoDbClient + */ + protected $client; + + /** + * @var string + */ + protected $table; + + /** + * @param DynamoDbClient $client + * @param string $table + * @param integer $level + * @param boolean $bubble + */ + public function __construct(DynamoDbClient $client, $table, $level = Logger::DEBUG, $bubble = true) + { + if (!defined('Aws\Common\Aws::VERSION') || version_compare('3.0', Aws::VERSION, '<=')) { + throw new \RuntimeException('The DynamoDbHandler is only known to work with the AWS SDK 2.x releases'); + } + + $this->client = $client; + $this->table = $table; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $filtered = $this->filterEmptyFields($record['formatted']); + $formatted = $this->client->formatAttributes($filtered); + + $this->client->putItem(array( + 'TableName' => $this->table, + 'Item' => $formatted + )); + } + + /** + * @param array $record + * @return array + */ + protected function filterEmptyFields(array $record) + { + return array_filter($record, function ($value) { + return !empty($value) || false === $value || 0 === $value; + }); + } + + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter() + { + return new ScalarFormatter(self::DATE_FORMAT); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php new file mode 100644 index 0000000..96e5d57 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\ElasticaFormatter; +use Monolog\Logger; +use Elastica\Client; +use Elastica\Exception\ExceptionInterface; + +/** + * Elastic Search handler + * + * Usage example: + * + * $client = new \Elastica\Client(); + * $options = array( + * 'index' => 'elastic_index_name', + * 'type' => 'elastic_doc_type', + * ); + * $handler = new ElasticSearchHandler($client, $options); + * $log = new Logger('application'); + * $log->pushHandler($handler); + * + * @author Jelle Vink + */ +class ElasticSearchHandler extends AbstractProcessingHandler +{ + /** + * @var Client + */ + protected $client; + + /** + * @var array Handler config options + */ + protected $options = array(); + + /** + * @param Client $client Elastica Client object + * @param array $options Handler configuration + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(Client $client, array $options = array(), $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + $this->client = $client; + $this->options = array_merge( + array( + 'index' => 'monolog', // Elastic index name + 'type' => 'record', // Elastic document type + 'ignore_error' => false, // Suppress Elastica exceptions + ), + $options + ); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $this->bulkSend(array($record['formatted'])); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + if ($formatter instanceof ElasticaFormatter) { + return parent::setFormatter($formatter); + } + throw new \InvalidArgumentException('ElasticSearchHandler is only compatible with ElasticaFormatter'); + } + + /** + * Getter options + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new ElasticaFormatter($this->options['index'], $this->options['type']); + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $documents = $this->getFormatter()->formatBatch($records); + $this->bulkSend($documents); + } + + /** + * Use Elasticsearch bulk API to send list of documents + * @param array $documents + * @throws \RuntimeException + */ + protected function bulkSend(array $documents) + { + try { + $this->client->addDocuments($documents); + } catch (ExceptionInterface $e) { + if (!$this->options['ignore_error']) { + throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e); + } + } + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php new file mode 100644 index 0000000..d1e1ee6 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; + +/** + * Stores to PHP error_log() handler. + * + * @author Elan Ruusamäe + */ +class ErrorLogHandler extends AbstractProcessingHandler +{ + const OPERATING_SYSTEM = 0; + const SAPI = 4; + + protected $messageType; + protected $expandNewlines; + + /** + * @param integer $messageType Says where the error should go. + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries + */ + public function __construct($messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, $bubble = true, $expandNewlines = false) + { + parent::__construct($level, $bubble); + + if (false === in_array($messageType, self::getAvailableTypes())) { + $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true)); + throw new \InvalidArgumentException($message); + } + + $this->messageType = $messageType; + $this->expandNewlines = $expandNewlines; + } + + /** + * @return array With all available types + */ + public static function getAvailableTypes() + { + return array( + self::OPERATING_SYSTEM, + self::SAPI, + ); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%'); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if ($this->expandNewlines) { + $lines = preg_split('{[\r\n]+}', (string) $record['formatted']); + foreach ($lines as $line) { + error_log($line, $this->messageType); + } + } else { + error_log((string) $record['formatted'], $this->messageType); + } + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php new file mode 100644 index 0000000..dad8227 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Simple handler wrapper that filters records based on a list of levels + * + * It can be configured with an exact list of levels to allow, or a min/max level. + * + * @author Hennadiy Verkh + * @author Jordi Boggiano + */ +class FilterHandler extends AbstractHandler +{ + /** + * Handler or factory callable($record, $this) + * + * @var callable|\Monolog\Handler\HandlerInterface + */ + protected $handler; + + /** + * Minimum level for logs that are passes to handler + * + * @var int[] + */ + protected $acceptedLevels; + + /** + * Whether the messages that are handled can bubble up the stack or not + * + * @var Boolean + */ + protected $bubble; + + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record, $this). + * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided + * @param int $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, $bubble = true) + { + $this->handler = $handler; + $this->bubble = $bubble; + $this->setAcceptedLevels($minLevelOrList, $maxLevel); + + if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { + throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); + } + } + + /** + * @return array + */ + public function getAcceptedLevels() + { + return array_flip($this->acceptedLevels); + } + + /** + * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided + * @param int $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array + */ + public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY) + { + if (is_array($minLevelOrList)) { + $acceptedLevels = array_map('Monolog\Logger::toMonologLevel', $minLevelOrList); + } else { + $minLevelOrList = Logger::toMonologLevel($minLevelOrList); + $maxLevel = Logger::toMonologLevel($maxLevel); + $acceptedLevels = array_values(array_filter(Logger::getLevels(), function ($level) use ($minLevelOrList, $maxLevel) { + return $level >= $minLevelOrList && $level <= $maxLevel; + })); + } + $this->acceptedLevels = array_flip($acceptedLevels); + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return isset($this->acceptedLevels[$record['level']]); + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if (!$this->isHandling($record)) { + return false; + } + + // The same logic as in FingersCrossedHandler + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + $this->handler->handle($record); + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $filtered = array(); + foreach ($records as $record) { + if ($this->isHandling($record)) { + $filtered[] = $record; + } + } + + $this->handler->handleBatch($filtered); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php new file mode 100644 index 0000000..c3e42ef --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\FingersCrossed; + +/** + * Interface for activation strategies for the FingersCrossedHandler. + * + * @author Johannes M. Schmitt + */ +interface ActivationStrategyInterface +{ + /** + * Returns whether the given record activates the handler. + * + * @param array $record + * @return Boolean + */ + public function isHandlerActivated(array $record); +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php new file mode 100644 index 0000000..e3b403f --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php @@ -0,0 +1,59 @@ + +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ + +namespace Monolog\Handler\FingersCrossed; + +use Monolog\Logger; + +/** + * Channel and Error level based monolog activation strategy. Allows to trigger activation + * based on level per channel. e.g. trigger activation on level 'ERROR' by default, except + * for records of the 'sql' channel; those should trigger activation on level 'WARN'. + * + * Example: + * + * + * $activationStrategy = new ChannelLevelActivationStrategy( + * Logger::CRITICAL, + * array( + * 'request' => Logger::ALERT, + * 'sensitive' => Logger::ERROR, + * ) + * ); + * $handler = new FingersCrossedHandler(new StreamHandler('php://stderr'), $activationStrategy); + * + * + * @author Mike Meessen + */ +class ChannelLevelActivationStrategy implements ActivationStrategyInterface +{ + private $defaultActionLevel; + private $channelToActionLevel; + + /** + * @param int $defaultActionLevel The default action level to be used if the record's category doesn't match any + * @param array $channelToActionLevel An array that maps channel names to action levels. + */ + public function __construct($defaultActionLevel, $channelToActionLevel = array()) + { + $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel); + $this->channelToActionLevel = array_map('Monolog\Logger::toMonologLevel', $channelToActionLevel); + } + + public function isHandlerActivated(array $record) + { + if (isset($this->channelToActionLevel[$record['channel']])) { + return $record['level'] >= $this->channelToActionLevel[$record['channel']]; + } + + return $record['level'] >= $this->defaultActionLevel; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php new file mode 100644 index 0000000..6e63085 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\FingersCrossed; + +use Monolog\Logger; + +/** + * Error level based activation strategy. + * + * @author Johannes M. Schmitt + */ +class ErrorLevelActivationStrategy implements ActivationStrategyInterface +{ + private $actionLevel; + + public function __construct($actionLevel) + { + $this->actionLevel = Logger::toMonologLevel($actionLevel); + } + + public function isHandlerActivated(array $record) + { + return $record['level'] >= $this->actionLevel; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php new file mode 100644 index 0000000..30a85dd --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php @@ -0,0 +1,153 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; +use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; +use Monolog\Logger; + +/** + * Buffers all records until a certain level is reached + * + * The advantage of this approach is that you don't get any clutter in your log files. + * Only requests which actually trigger an error (or whatever your actionLevel is) will be + * in the logs, but they will contain all records, not only those above the level threshold. + * + * You can find the various activation strategies in the + * Monolog\Handler\FingersCrossed\ namespace. + * + * @author Jordi Boggiano + */ +class FingersCrossedHandler extends AbstractHandler +{ + protected $handler; + protected $activationStrategy; + protected $buffering = true; + protected $bufferSize; + protected $buffer = array(); + protected $stopBuffering; + protected $passthruLevel; + + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler). + * @param int|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action + * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $stopBuffering Whether the handler should stop buffering after being triggered (default true) + * @param int $passthruLevel Minimum level to always flush to handler on close, even if strategy not triggered + */ + public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = true, $stopBuffering = true, $passthruLevel = null) + { + if (null === $activationStrategy) { + $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING); + } + + // convert simple int activationStrategy to an object + if (!$activationStrategy instanceof ActivationStrategyInterface) { + $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy); + } + + $this->handler = $handler; + $this->activationStrategy = $activationStrategy; + $this->bufferSize = $bufferSize; + $this->bubble = $bubble; + $this->stopBuffering = $stopBuffering; + + if ($passthruLevel !== null) { + $this->passthruLevel = Logger::toMonologLevel($passthruLevel); + } + + if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { + throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); + } + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + if ($this->buffering) { + $this->buffer[] = $record; + if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) { + array_shift($this->buffer); + } + if ($this->activationStrategy->isHandlerActivated($record)) { + if ($this->stopBuffering) { + $this->buffering = false; + } + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + $this->handler->handleBatch($this->buffer); + $this->buffer = array(); + } + } else { + $this->handler->handle($record); + } + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function close() + { + if (null !== $this->passthruLevel) { + $level = $this->passthruLevel; + $this->buffer = array_filter($this->buffer, function ($record) use ($level) { + return $record['level'] >= $level; + }); + if (count($this->buffer) > 0) { + $this->handler->handleBatch($this->buffer); + $this->buffer = array(); + } + } + } + + /** + * Resets the state of the handler. Stops forwarding records to the wrapped handler. + */ + public function reset() + { + $this->buffering = true; + } + + /** + * Clears the buffer without flushing any messages down to the wrapped handler. + * + * It also resets the handler to its initial buffering state. + */ + public function clear() + { + $this->buffer = array(); + $this->reset(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php new file mode 100644 index 0000000..fee4795 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php @@ -0,0 +1,195 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\WildfireFormatter; + +/** + * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol. + * + * @author Eric Clemmons (@ericclemmons) + */ +class FirePHPHandler extends AbstractProcessingHandler +{ + /** + * WildFire JSON header message format + */ + const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'; + + /** + * FirePHP structure for parsing messages & their presentation + */ + const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'; + + /** + * Must reference a "known" plugin, otherwise headers won't display in FirePHP + */ + const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3'; + + /** + * Header prefix for Wildfire to recognize & parse headers + */ + const HEADER_PREFIX = 'X-Wf'; + + /** + * Whether or not Wildfire vendor-specific headers have been generated & sent yet + */ + protected static $initialized = false; + + /** + * Shared static message index between potentially multiple handlers + * @var int + */ + protected static $messageIndex = 1; + + protected static $sendHeaders = true; + + /** + * Base header creation function used by init headers & record headers + * + * @param array $meta Wildfire Plugin, Protocol & Structure Indexes + * @param string $message Log message + * @return array Complete header string ready for the client as key and message as value + */ + protected function createHeader(array $meta, $message) + { + $header = sprintf('%s-%s', self::HEADER_PREFIX, join('-', $meta)); + + return array($header => $message); + } + + /** + * Creates message header from record + * + * @see createHeader() + * @param array $record + * @return string + */ + protected function createRecordHeader(array $record) + { + // Wildfire is extensible to support multiple protocols & plugins in a single request, + // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake. + return $this->createHeader( + array(1, 1, 1, self::$messageIndex++), + $record['formatted'] + ); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new WildfireFormatter(); + } + + /** + * Wildfire initialization headers to enable message parsing + * + * @see createHeader() + * @see sendHeader() + * @return array + */ + protected function getInitHeaders() + { + // Initial payload consists of required headers for Wildfire + return array_merge( + $this->createHeader(array('Protocol', 1), self::PROTOCOL_URI), + $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI), + $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI) + ); + } + + /** + * Send header string to the client + * + * @param string $header + * @param string $content + */ + protected function sendHeader($header, $content) + { + if (!headers_sent() && self::$sendHeaders) { + header(sprintf('%s: %s', $header, $content)); + } + } + + /** + * Creates & sends header for a record, ensuring init headers have been sent prior + * + * @see sendHeader() + * @see sendInitHeaders() + * @param array $record + */ + protected function write(array $record) + { + if (!self::$sendHeaders) { + return; + } + + // WildFire-specific headers must be sent prior to any messages + if (!self::$initialized) { + self::$initialized = true; + + self::$sendHeaders = $this->headersAccepted(); + if (!self::$sendHeaders) { + return; + } + + foreach ($this->getInitHeaders() as $header => $content) { + $this->sendHeader($header, $content); + } + } + + $header = $this->createRecordHeader($record); + if (trim(current($header)) !== '') { + $this->sendHeader(key($header), current($header)); + } + } + + /** + * Verifies if the headers are accepted by the current user agent + * + * @return Boolean + */ + protected function headersAccepted() + { + if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) { + return true; + } + + return isset($_SERVER['HTTP_X_FIREPHP_VERSION']); + } + + /** + * BC getter for the sendHeaders property that has been made static + */ + public function __get($property) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property '.$property); + } + + return static::$sendHeaders; + } + + /** + * BC setter for the sendHeaders property that has been made static + */ + public function __set($property, $value) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property '.$property); + } + + static::$sendHeaders = $value; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php new file mode 100644 index 0000000..388692c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; + +/** + * Sends logs to Fleep.io using Webhook integrations + * + * You'll need a Fleep.io account to use this handler. + * + * @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation + * @author Ando Roots + */ +class FleepHookHandler extends SocketHandler +{ + const FLEEP_HOST = 'fleep.io'; + + const FLEEP_HOOK_URI = '/hook/'; + + /** + * @var string Webhook token (specifies the conversation where logs are sent) + */ + protected $token; + + /** + * Construct a new Fleep.io Handler. + * + * For instructions on how to create a new web hook in your conversations + * see https://fleep.io/integrations/webhooks/ + * + * @param string $token Webhook token + * @param bool|int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @throws MissingExtensionException + */ + public function __construct($token, $level = Logger::DEBUG, $bubble = true) + { + if (!extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FleepHookHandler'); + } + + $this->token = $token; + + $connectionString = 'ssl://' . self::FLEEP_HOST . ':443'; + parent::__construct($connectionString, $level, $bubble); + } + + /** + * Returns the default formatter to use with this handler + * + * Overloaded to remove empty context and extra arrays from the end of the log message. + * + * @return LineFormatter + */ + protected function getDefaultFormatter() + { + return new LineFormatter(null, null, true, true); + } + + /** + * Handles a log record + * + * @param array $record + */ + public function write(array $record) + { + parent::write($record); + $this->closeSocket(); + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST " . self::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n"; + $header .= "Host: " . self::FLEEP_HOST . "\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } + + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = array( + 'message' => $record['formatted'] + ); + + return http_build_query($dataArray); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php new file mode 100644 index 0000000..dd9a361 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\FlowdockFormatter; +use Monolog\Formatter\FormatterInterface; + +/** + * Sends notifications through the Flowdock push API + * + * This must be configured with a FlowdockFormatter instance via setFormatter() + * + * Notes: + * API token - Flowdock API token + * + * @author Dominik Liebler + * @see https://www.flowdock.com/api/push + */ +class FlowdockHandler extends SocketHandler +{ + /** + * @var string + */ + protected $apiToken; + + /** + * @param string $apiToken + * @param bool|int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * + * @throws MissingExtensionException if OpenSSL is missing + */ + public function __construct($apiToken, $level = Logger::DEBUG, $bubble = true) + { + if (!extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler'); + } + + parent::__construct('ssl://api.flowdock.com:443', $level, $bubble); + $this->apiToken = $apiToken; + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter) + { + if (!$formatter instanceof FlowdockFormatter) { + throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); + } + + return parent::setFormatter($formatter); + } + + /** + * Gets the default formatter. + * + * @return FormatterInterface + */ + protected function getDefaultFormatter() + { + throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); + } + + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + + $this->closeSocket(); + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + return json_encode($record['formatted']['flowdock']); + } + + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n"; + $header .= "Host: api.flowdock.com\r\n"; + $header .= "Content-Type: application/json\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php new file mode 100644 index 0000000..28c7b55 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Gelf\IMessagePublisher; +use Gelf\PublisherInterface; +use Gelf\Publisher; +use InvalidArgumentException; +use Monolog\Logger; +use Monolog\Formatter\GelfMessageFormatter; + +/** + * Handler to send messages to a Graylog2 (http://www.graylog2.org) server + * + * @author Matt Lehner + * @author Benjamin Zikarsky + */ +class GelfHandler extends AbstractProcessingHandler +{ + /** + * @var Publisher the publisher object that sends the message to the server + */ + protected $publisher; + + /** + * @param PublisherInterface|IMessagePublisher|Publisher $publisher a publisher object + * @param integer $level The minimum logging level at which this handler will be triggered + * @param boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($publisher, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + if (!$publisher instanceof Publisher && !$publisher instanceof IMessagePublisher && !$publisher instanceof PublisherInterface) { + throw new InvalidArgumentException("Invalid publisher, expected a Gelf\Publisher, Gelf\IMessagePublisher or Gelf\PublisherInterface instance"); + } + + $this->publisher = $publisher; + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->publisher = null; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->publisher->publish($record['formatted']); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new GelfMessageFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php new file mode 100644 index 0000000..99384d3 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Forwards records to multiple handlers + * + * @author Lenar Lõhmus + */ +class GroupHandler extends AbstractHandler +{ + protected $handlers; + + /** + * @param array $handlers Array of Handlers. + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(array $handlers, $bubble = true) + { + foreach ($handlers as $handler) { + if (!$handler instanceof HandlerInterface) { + throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.'); + } + } + + $this->handlers = $handlers; + $this->bubble = $bubble; + } + + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + foreach ($this->handlers as $handler) { + if ($handler->isHandling($record)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + foreach ($this->handlers as $handler) { + $handler->handle($record); + } + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + foreach ($this->handlers as $handler) { + $handler->handleBatch($records); + } + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php b/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php new file mode 100644 index 0000000..d920c4b --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; + +/** + * Interface that all Monolog Handlers must implement + * + * @author Jordi Boggiano + */ +interface HandlerInterface +{ + /** + * Checks whether the given record will be handled by this handler. + * + * This is mostly done for performance reasons, to avoid calling processors for nothing. + * + * Handlers should still check the record levels within handle(), returning false in isHandling() + * is no guarantee that handle() will not be called, and isHandling() might not be called + * for a given record. + * + * @param array $record Partial log record containing only a level key + * + * @return Boolean + */ + public function isHandling(array $record); + + /** + * Handles a record. + * + * All records may be passed to this method, and the handler should discard + * those that it does not want to handle. + * + * The return value of this function controls the bubbling process of the handler stack. + * Unless the bubbling is interrupted (by returning true), the Logger class will keep on + * calling further handlers in the stack with a given log record. + * + * @param array $record The record to handle + * @return Boolean true means that this handler handled the record, and that bubbling is not permitted. + * false means the record was either not processed or that this handler allows bubbling. + */ + public function handle(array $record); + + /** + * Handles a set of records at once. + * + * @param array $records The records to handle (an array of record arrays) + */ + public function handleBatch(array $records); + + /** + * Adds a processor in the stack. + * + * @param callable $callback + * @return self + */ + public function pushProcessor($callback); + + /** + * Removes the processor on top of the stack and returns it. + * + * @return callable + */ + public function popProcessor(); + + /** + * Sets the formatter. + * + * @param FormatterInterface $formatter + * @return self + */ + public function setFormatter(FormatterInterface $formatter); + + /** + * Gets the formatter. + * + * @return FormatterInterface + */ + public function getFormatter(); +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php new file mode 100644 index 0000000..34d3437 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php @@ -0,0 +1,337 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Sends notifications through the hipchat api to a hipchat room + * + * Notes: + * API token - HipChat API token + * Room - HipChat Room Id or name, where messages are sent + * Name - Name used to send the message (from) + * notify - Should the message trigger a notification in the clients + * version - The API version to use (HipChatHandler::API_V1 | HipChatHandler::API_V2) + * + * @author Rafael Dohms + * @see https://www.hipchat.com/docs/api + */ +class HipChatHandler extends SocketHandler +{ + /** + * Use API version 1 + */ + const API_V1 = 'v1'; + + /** + * Use API version v2 + */ + const API_V2 = 'v2'; + + /** + * The maximum allowed length for the name used in the "from" field. + */ + const MAXIMUM_NAME_LENGTH = 15; + + /** + * The maximum allowed length for the message. + */ + const MAXIMUM_MESSAGE_LENGTH = 9500; + + /** + * @var string + */ + private $token; + + /** + * @var string + */ + private $room; + + /** + * @var string + */ + private $name; + + /** + * @var bool + */ + private $notify; + + /** + * @var string + */ + private $format; + + /** + * @var string + */ + private $host; + + /** + * @var string + */ + private $version; + + /** + * @param string $token HipChat API Token + * @param string $room The room that should be alerted of the message (Id or Name) + * @param string $name Name used in the "from" field. Not used for v2 + * @param bool $notify Trigger a notification in clients or not + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $useSSL Whether to connect via SSL. + * @param string $format The format of the messages (default to text, can be set to html if you have html in the messages) + * @param string $host The HipChat server hostname. + * @param string $version The HipChat API version (default HipChatHandler::API_V1) + */ + public function __construct($token, $room, $name = 'Monolog', $notify = false, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $format = 'text', $host = 'api.hipchat.com', $version = self::API_V1) + { + if ($version == self::API_V1 && !$this->validateStringLength($name, static::MAXIMUM_NAME_LENGTH)) { + throw new \InvalidArgumentException('The supplied name is too long. HipChat\'s v1 API supports names up to 15 UTF-8 characters.'); + } + + $connectionString = $useSSL ? 'ssl://'.$host.':443' : $host.':80'; + parent::__construct($connectionString, $level, $bubble); + + $this->token = $token; + $this->name = $name; + $this->notify = $notify; + $this->room = $room; + $this->format = $format; + $this->host = $host; + $this->version = $version; + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = array( + 'notify' => $this->version == self::API_V1 ? + ($this->notify ? 1 : 0) : + ($this->notify ? 'true' : 'false'), + 'message' => $record['formatted'], + 'message_format' => $this->format, + 'color' => $this->getAlertColor($record['level']), + ); + + // if we are using the legacy API then we need to send some additional information + if ($this->version == self::API_V1) { + $dataArray['room_id'] = $this->room; + $dataArray['from'] = $this->name; + } + + return http_build_query($dataArray); + } + + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + if ($this->version == self::API_V1) { + $header = "POST /v1/rooms/message?format=json&auth_token={$this->token} HTTP/1.1\r\n"; + } else { + // needed for rooms with special (spaces, etc) characters in the name + $room = rawurlencode($this->room); + $header = "POST /v2/room/{$room}/notification?auth_token={$this->token} HTTP/1.1\r\n"; + } + + $header .= "Host: {$this->host}\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } + + /** + * Assigns a color to each level of log records. + * + * @param integer $level + * @return string + */ + protected function getAlertColor($level) + { + switch (true) { + case $level >= Logger::ERROR: + return 'red'; + case $level >= Logger::WARNING: + return 'yellow'; + case $level >= Logger::INFO: + return 'green'; + case $level == Logger::DEBUG: + return 'gray'; + default: + return 'yellow'; + } + } + + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + $this->closeSocket(); + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + if (count($records) == 0) { + return true; + } + + $batchRecords = $this->combineRecords($records); + + $handled = false; + foreach ($batchRecords as $batchRecord) { + if ($this->isHandling($batchRecord)) { + $this->write($batchRecord); + $handled = true; + } + } + + if (!$handled) { + return false; + } + + return false === $this->bubble; + } + + /** + * Combines multiple records into one. Error level of the combined record + * will be the highest level from the given records. Datetime will be taken + * from the first record. + * + * @param $records + * @return array + */ + private function combineRecords($records) + { + $batchRecord = null; + $batchRecords = array(); + $messages = array(); + $formattedMessages = array(); + $level = 0; + $levelName = null; + $datetime = null; + + foreach ($records as $record) { + $record = $this->processRecord($record); + + if ($record['level'] > $level) { + $level = $record['level']; + $levelName = $record['level_name']; + } + + if (null === $datetime) { + $datetime = $record['datetime']; + } + + $messages[] = $record['message']; + $messageStr = implode(PHP_EOL, $messages); + $formattedMessages[] = $this->getFormatter()->format($record); + $formattedMessageStr = implode('', $formattedMessages); + + $batchRecord = array( + 'message' => $messageStr, + 'formatted' => $formattedMessageStr, + 'context' => array(), + 'extra' => array(), + ); + + if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) { + // Pop the last message and implode the remaining messages + $lastMessage = array_pop($messages); + $lastFormattedMessage = array_pop($formattedMessages); + $batchRecord['message'] = implode(PHP_EOL, $messages); + $batchRecord['formatted'] = implode('', $formattedMessages); + + $batchRecords[] = $batchRecord; + $messages = array($lastMessage); + $formattedMessages = array($lastFormattedMessage); + + $batchRecord = null; + } + } + + if (null !== $batchRecord) { + $batchRecords[] = $batchRecord; + } + + // Set the max level and datetime for all records + foreach ($batchRecords as &$batchRecord) { + $batchRecord = array_merge( + $batchRecord, + array( + 'level' => $level, + 'level_name' => $levelName, + 'datetime' => $datetime + ) + ); + } + + return $batchRecords; + } + + /** + * Validates the length of a string. + * + * If the `mb_strlen()` function is available, it will use that, as HipChat + * allows UTF-8 characters. Otherwise, it will fall back to `strlen()`. + * + * Note that this might cause false failures in the specific case of using + * a valid name with less than 16 characters, but 16 or more bytes, on a + * system where `mb_strlen()` is unavailable. + * + * @param string $str + * @param int $length + * + * @return bool + */ + private function validateStringLength($str, $length) + { + if (function_exists('mb_strlen')) { + return (mb_strlen($str) <= $length); + } + + return (strlen($str) <= $length); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php new file mode 100644 index 0000000..bc11705 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * IFTTTHandler uses cURL to trigger IFTTT Maker actions + * + * Register a secret key and trigger/event name at https://ifttt.com/maker + * + * value1 will be the channel from monolog's Logger constructor, + * value2 will be the level name (ERROR, WARNING, ..) + * value3 will be the log record's message + * + * @author Nehal Patel + */ +class IFTTTHandler extends AbstractProcessingHandler +{ + private $eventName; + private $secretKey; + + /** + * @param string $eventName The name of the IFTTT Maker event that should be triggered + * @param string $secretKey A valid IFTTT secret key + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($eventName, $secretKey, $level = Logger::ERROR, $bubble = true) + { + $this->eventName = $eventName; + $this->secretKey = $secretKey; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritdoc} + */ + public function write(array $record) + { + $postData = array( + "value1" => $record["channel"], + "value2" => $record["level_name"], + "value3" => $record["message"] + ); + $postString = json_encode($postData); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, "https://maker.ifttt.com/trigger/" . $this->eventName . "/with/key/" . $this->secretKey); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postString); + curl_setopt($ch, CURLOPT_HTTPHEADER, array( + "Content-Type: application/json" + )); + + Curl\Util::execute($ch); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php new file mode 100644 index 0000000..bd56230 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * @author Robert Kaufmann III + */ +class LogEntriesHandler extends SocketHandler +{ + /** + * @var string + */ + protected $logToken; + + /** + * @param string $token Log token supplied by LogEntries + * @param boolean $useSSL Whether or not SSL encryption should be used. + * @param int $level The minimum logging level to trigger this handler + * @param boolean $bubble Whether or not messages that are handled should bubble up the stack. + * + * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing + */ + public function __construct($token, $useSSL = true, $level = Logger::DEBUG, $bubble = true) + { + if ($useSSL && !extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler'); + } + + $endpoint = $useSSL ? 'ssl://data.logentries.com:443' : 'data.logentries.com:80'; + parent::__construct($endpoint, $level, $bubble); + $this->logToken = $token; + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + return $this->logToken . ' ' . $record['formatted']; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php new file mode 100644 index 0000000..bcd62e1 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LogglyFormatter; + +/** + * Sends errors to Loggly. + * + * @author Przemek Sobstel + * @author Adam Pancutt + * @author Gregory Barchard + */ +class LogglyHandler extends AbstractProcessingHandler +{ + const HOST = 'logs-01.loggly.com'; + const ENDPOINT_SINGLE = 'inputs'; + const ENDPOINT_BATCH = 'bulk'; + + protected $token; + + protected $tag = array(); + + public function __construct($token, $level = Logger::DEBUG, $bubble = true) + { + if (!extension_loaded('curl')) { + throw new \LogicException('The curl extension is needed to use the LogglyHandler'); + } + + $this->token = $token; + + parent::__construct($level, $bubble); + } + + public function setTag($tag) + { + $tag = !empty($tag) ? $tag : array(); + $this->tag = is_array($tag) ? $tag : array($tag); + } + + public function addTag($tag) + { + if (!empty($tag)) { + $tag = is_array($tag) ? $tag : array($tag); + $this->tag = array_unique(array_merge($this->tag, $tag)); + } + } + + protected function write(array $record) + { + $this->send($record["formatted"], self::ENDPOINT_SINGLE); + } + + public function handleBatch(array $records) + { + $level = $this->level; + + $records = array_filter($records, function ($record) use ($level) { + return ($record['level'] >= $level); + }); + + if ($records) { + $this->send($this->getFormatter()->formatBatch($records), self::ENDPOINT_BATCH); + } + } + + protected function send($data, $endpoint) + { + $url = sprintf("https://%s/%s/%s/", self::HOST, $endpoint, $this->token); + + $headers = array('Content-Type: application/json'); + + if (!empty($this->tag)) { + $headers[] = 'X-LOGGLY-TAG: '.implode(',', $this->tag); + } + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + Curl\Util::execute($ch); + } + + protected function getDefaultFormatter() + { + return new LogglyFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php new file mode 100644 index 0000000..50ed638 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Base class for all mail handlers + * + * @author Gyula Sallai + */ +abstract class MailHandler extends AbstractProcessingHandler +{ + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + + if (!empty($messages)) { + $this->send((string) $this->getFormatter()->formatBatch($messages), $messages); + } + } + + /** + * Send a mail with the given content + * + * @param string $content formatted email body to be sent + * @param array $records the array of log records that formed this content + */ + abstract protected function send($content, array $records); + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->send((string) $record['formatted'], array($record)); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php new file mode 100644 index 0000000..0ed098a --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * MandrillHandler uses cURL to send the emails to the Mandrill API + * + * @author Adam Nicholson + */ +class MandrillHandler extends MailHandler +{ + protected $message; + protected $apiKey; + + /** + * @param string $apiKey A valid Mandrill API key + * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($apiKey, $message, $level = Logger::ERROR, $bubble = true) + { + parent::__construct($level, $bubble); + + if (!$message instanceof \Swift_Message && is_callable($message)) { + $message = call_user_func($message); + } + if (!$message instanceof \Swift_Message) { + throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it'); + } + $this->message = $message; + $this->apiKey = $apiKey; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $message = clone $this->message; + $message->setBody($content); + $message->setDate(time()); + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json'); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array( + 'key' => $this->apiKey, + 'raw_message' => (string) $message, + 'async' => false, + ))); + + Curl\Util::execute($ch); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php b/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php new file mode 100644 index 0000000..4724a7e --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Exception can be thrown if an extension for an handler is missing + * + * @author Christian Bergau + */ +class MissingExtensionException extends \Exception +{ +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php new file mode 100644 index 0000000..6c431f2 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\NormalizerFormatter; + +/** + * Logs to a MongoDB database. + * + * usage example: + * + * $log = new Logger('application'); + * $mongodb = new MongoDBHandler(new \Mongo("mongodb://localhost:27017"), "logs", "prod"); + * $log->pushHandler($mongodb); + * + * @author Thomas Tourlourat + */ +class MongoDBHandler extends AbstractProcessingHandler +{ + protected $mongoCollection; + + public function __construct($mongo, $database, $collection, $level = Logger::DEBUG, $bubble = true) + { + if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo)) { + throw new \InvalidArgumentException('MongoClient or Mongo instance required'); + } + + $this->mongoCollection = $mongo->selectCollection($database, $collection); + + parent::__construct($level, $bubble); + } + + protected function write(array $record) + { + $this->mongoCollection->save($record["formatted"]); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new NormalizerFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php new file mode 100644 index 0000000..5118a0e --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * NativeMailerHandler uses the mail() function to send the emails + * + * @author Christophe Coevoet + * @author Mark Garrett + */ +class NativeMailerHandler extends MailHandler +{ + /** + * The email addresses to which the message will be sent + * @var array + */ + protected $to; + + /** + * The subject of the email + * @var string + */ + protected $subject; + + /** + * Optional headers for the message + * @var array + */ + protected $headers = array(); + + /** + * Optional parameters for the message + * @var array + */ + protected $parameters = array(); + + /** + * The wordwrap length for the message + * @var integer + */ + protected $maxColumnWidth; + + /** + * The Content-type for the message + * @var string + */ + protected $contentType = 'text/plain'; + + /** + * The encoding for the message + * @var string + */ + protected $encoding = 'utf-8'; + + /** + * @param string|array $to The receiver of the mail + * @param string $subject The subject of the mail + * @param string $from The sender of the mail + * @param integer $level The minimum logging level at which this handler will be triggered + * @param boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $maxColumnWidth The maximum column width that the message lines will have + */ + public function __construct($to, $subject, $from, $level = Logger::ERROR, $bubble = true, $maxColumnWidth = 70) + { + parent::__construct($level, $bubble); + $this->to = is_array($to) ? $to : array($to); + $this->subject = $subject; + $this->addHeader(sprintf('From: %s', $from)); + $this->maxColumnWidth = $maxColumnWidth; + } + + /** + * Add headers to the message + * + * @param string|array $headers Custom added headers + * @return self + */ + public function addHeader($headers) + { + foreach ((array) $headers as $header) { + if (strpos($header, "\n") !== false || strpos($header, "\r") !== false) { + throw new \InvalidArgumentException('Headers can not contain newline characters for security reasons'); + } + $this->headers[] = $header; + } + + return $this; + } + + /** + * Add parameters to the message + * + * @param string|array $parameters Custom added parameters + * @return self + */ + public function addParameter($parameters) + { + $this->parameters = array_merge($this->parameters, (array) $parameters); + + return $this; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $content = wordwrap($content, $this->maxColumnWidth); + $headers = ltrim(implode("\r\n", $this->headers) . "\r\n", "\r\n"); + $headers .= 'Content-type: ' . $this->getContentType() . '; charset=' . $this->getEncoding() . "\r\n"; + if ($this->getContentType() == 'text/html' && false === strpos($headers, 'MIME-Version:')) { + $headers .= 'MIME-Version: 1.0' . "\r\n"; + } + foreach ($this->to as $to) { + mail($to, $this->subject, $content, $headers, implode(' ', $this->parameters)); + } + } + + /** + * @return string $contentType + */ + public function getContentType() + { + return $this->contentType; + } + + /** + * @return string $encoding + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * @param string $contentType The content type of the email - Defaults to text/plain. Use text/html for HTML + * messages. + * @return self + */ + public function setContentType($contentType) + { + if (strpos($contentType, "\n") !== false || strpos($contentType, "\r") !== false) { + throw new \InvalidArgumentException('The content type can not contain newline characters to prevent email header injection'); + } + + $this->contentType = $contentType; + + return $this; + } + + /** + * @param string $encoding + * @return self + */ + public function setEncoding($encoding) + { + if (strpos($encoding, "\n") !== false || strpos($encoding, "\r") !== false) { + throw new \InvalidArgumentException('The encoding can not contain newline characters to prevent email header injection'); + } + + $this->encoding = $encoding; + + return $this; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php new file mode 100644 index 0000000..8cb4ab3 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php @@ -0,0 +1,198 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\NormalizerFormatter; + +/** + * Class to record a log on a NewRelic application. + * Enabling New Relic High Security mode may prevent capture of useful information. + * + * @see https://docs.newrelic.com/docs/agents/php-agent + * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security + */ +class NewRelicHandler extends AbstractProcessingHandler +{ + /** + * Name of the New Relic application that will receive logs from this handler. + * + * @var string + */ + protected $appName; + + /** + * Name of the current transaction + * + * @var string + */ + protected $transactionName; + + /** + * Some context and extra data is passed into the handler as arrays of values. Do we send them as is + * (useful if we are using the API), or explode them for display on the NewRelic RPM website? + * + * @var boolean + */ + protected $explodeArrays; + + /** + * {@inheritDoc} + * + * @param string $appName + * @param boolean $explodeArrays + * @param string $transactionName + */ + public function __construct( + $level = Logger::ERROR, + $bubble = true, + $appName = null, + $explodeArrays = false, + $transactionName = null + ) { + parent::__construct($level, $bubble); + + $this->appName = $appName; + $this->explodeArrays = $explodeArrays; + $this->transactionName = $transactionName; + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + if (!$this->isNewRelicEnabled()) { + throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler'); + } + + if ($appName = $this->getAppName($record['context'])) { + $this->setNewRelicAppName($appName); + } + + if ($transactionName = $this->getTransactionName($record['context'])) { + $this->setNewRelicTransactionName($transactionName); + unset($record['formatted']['context']['transaction_name']); + } + + if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) { + newrelic_notice_error($record['message'], $record['context']['exception']); + unset($record['formatted']['context']['exception']); + } else { + newrelic_notice_error($record['message']); + } + + foreach ($record['formatted']['context'] as $key => $parameter) { + if (is_array($parameter) && $this->explodeArrays) { + foreach ($parameter as $paramKey => $paramValue) { + $this->setNewRelicParameter('context_' . $key . '_' . $paramKey, $paramValue); + } + } else { + $this->setNewRelicParameter('context_' . $key, $parameter); + } + } + + foreach ($record['formatted']['extra'] as $key => $parameter) { + if (is_array($parameter) && $this->explodeArrays) { + foreach ($parameter as $paramKey => $paramValue) { + $this->setNewRelicParameter('extra_' . $key . '_' . $paramKey, $paramValue); + } + } else { + $this->setNewRelicParameter('extra_' . $key, $parameter); + } + } + } + + /** + * Checks whether the NewRelic extension is enabled in the system. + * + * @return bool + */ + protected function isNewRelicEnabled() + { + return extension_loaded('newrelic'); + } + + /** + * Returns the appname where this log should be sent. Each log can override the default appname, set in this + * handler's constructor, by providing the appname in it's context. + * + * @param array $context + * @return null|string + */ + protected function getAppName(array $context) + { + if (isset($context['appname'])) { + return $context['appname']; + } + + return $this->appName; + } + + /** + * Returns the name of the current transaction. Each log can override the default transaction name, set in this + * handler's constructor, by providing the transaction_name in it's context + * + * @param array $context + * + * @return null|string + */ + protected function getTransactionName(array $context) + { + if (isset($context['transaction_name'])) { + return $context['transaction_name']; + } + + return $this->transactionName; + } + + /** + * Sets the NewRelic application that should receive this log. + * + * @param string $appName + */ + protected function setNewRelicAppName($appName) + { + newrelic_set_appname($appName); + } + + /** + * Overwrites the name of the current transaction + * + * @param string $transactionName + */ + protected function setNewRelicTransactionName($transactionName) + { + newrelic_name_transaction($transactionName); + } + + /** + * @param string $key + * @param mixed $value + */ + protected function setNewRelicParameter($key, $value) + { + if (null === $value || is_scalar($value)) { + newrelic_add_custom_parameter($key, $value); + } else { + newrelic_add_custom_parameter($key, @json_encode($value)); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new NormalizerFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php new file mode 100644 index 0000000..3754e45 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Blackhole + * + * Any record it can handle will be thrown away. This can be used + * to put on top of an existing stack to override it temporarily. + * + * @author Jordi Boggiano + */ +class NullHandler extends AbstractHandler +{ + /** + * @param integer $level The minimum logging level at which this handler will be triggered + */ + public function __construct($level = Logger::DEBUG) + { + parent::__construct($level, false); + } + + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return false; + } + + return true; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php new file mode 100644 index 0000000..2b7e353 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php @@ -0,0 +1,242 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Exception; +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; +use PhpConsole\Connector; +use PhpConsole\Handler; +use PhpConsole\Helper; + +/** + * Monolog handler for Google Chrome extension "PHP Console" + * + * Display PHP error/debug log messages in Google Chrome console and notification popups, executes PHP code remotely + * + * Usage: + * 1. Install Google Chrome extension https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef + * 2. See overview https://github.com/barbushin/php-console#overview + * 3. Install PHP Console library https://github.com/barbushin/php-console#installation + * 4. Example (result will looks like http://i.hizliresim.com/vg3Pz4.png) + * + * $logger = new \Monolog\Logger('all', array(new \Monolog\Handler\PHPConsoleHandler())); + * \Monolog\ErrorHandler::register($logger); + * echo $undefinedVar; + * $logger->addDebug('SELECT * FROM users', array('db', 'time' => 0.012)); + * PC::debug($_SERVER); // PHP Console debugger for any type of vars + * + * @author Sergey Barbushin https://www.linkedin.com/in/barbushin + */ +class PHPConsoleHandler extends AbstractProcessingHandler +{ + private $options = array( + 'enabled' => true, // bool Is PHP Console server enabled + 'classesPartialsTraceIgnore' => array('Monolog\\'), // array Hide calls of classes started with... + 'debugTagsKeysInContext' => array(0, 'tag'), // bool Is PHP Console server enabled + 'useOwnErrorsHandler' => false, // bool Enable errors handling + 'useOwnExceptionsHandler' => false, // bool Enable exceptions handling + 'sourcesBasePath' => null, // string Base path of all project sources to strip in errors source paths + 'registerHelper' => true, // bool Register PhpConsole\Helper that allows short debug calls like PC::debug($var, 'ta.g.s') + 'serverEncoding' => null, // string|null Server internal encoding + 'headersLimit' => null, // int|null Set headers size limit for your web-server + 'password' => null, // string|null Protect PHP Console connection by password + 'enableSslOnlyMode' => false, // bool Force connection by SSL for clients with PHP Console installed + 'ipMasks' => array(), // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1') + 'enableEvalListener' => false, // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required) + 'dumperDetectCallbacks' => false, // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings + 'dumperLevelLimit' => 5, // int Maximum dumped vars array or object nested dump level + 'dumperItemsCountLimit' => 100, // int Maximum dumped var same level array items or object properties number + 'dumperItemSizeLimit' => 5000, // int Maximum length of any string or dumped array item + 'dumperDumpSizeLimit' => 500000, // int Maximum approximate size of dumped vars result formatted in JSON + 'detectDumpTraceAndSource' => false, // bool Autodetect and append trace data to debug + 'dataStorage' => null, // PhpConsole\Storage|null Fixes problem with custom $_SESSION handler(see http://goo.gl/Ne8juJ) + ); + + /** @var Connector */ + private $connector; + + /** + * @param array $options See \Monolog\Handler\PHPConsoleHandler::$options for more details + * @param Connector|null $connector Instance of \PhpConsole\Connector class (optional) + * @param int $level + * @param bool $bubble + * @throws Exception + */ + public function __construct(array $options = array(), Connector $connector = null, $level = Logger::DEBUG, $bubble = true) + { + if (!class_exists('PhpConsole\Connector')) { + throw new Exception('PHP Console library not found. See https://github.com/barbushin/php-console#installation'); + } + parent::__construct($level, $bubble); + $this->options = $this->initOptions($options); + $this->connector = $this->initConnector($connector); + } + + private function initOptions(array $options) + { + $wrongOptions = array_diff(array_keys($options), array_keys($this->options)); + if ($wrongOptions) { + throw new Exception('Unknown options: ' . implode(', ', $wrongOptions)); + } + + return array_replace($this->options, $options); + } + + private function initConnector(Connector $connector = null) + { + if (!$connector) { + if ($this->options['dataStorage']) { + Connector::setPostponeStorage($this->options['dataStorage']); + } + $connector = Connector::getInstance(); + } + + if ($this->options['registerHelper'] && !Helper::isRegistered()) { + Helper::register(); + } + + if ($this->options['enabled'] && $connector->isActiveClient()) { + if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) { + $handler = Handler::getInstance(); + $handler->setHandleErrors($this->options['useOwnErrorsHandler']); + $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']); + $handler->start(); + } + if ($this->options['sourcesBasePath']) { + $connector->setSourcesBasePath($this->options['sourcesBasePath']); + } + if ($this->options['serverEncoding']) { + $connector->setServerEncoding($this->options['serverEncoding']); + } + if ($this->options['password']) { + $connector->setPassword($this->options['password']); + } + if ($this->options['enableSslOnlyMode']) { + $connector->enableSslOnlyMode(); + } + if ($this->options['ipMasks']) { + $connector->setAllowedIpMasks($this->options['ipMasks']); + } + if ($this->options['headersLimit']) { + $connector->setHeadersLimit($this->options['headersLimit']); + } + if ($this->options['detectDumpTraceAndSource']) { + $connector->getDebugDispatcher()->detectTraceAndSource = true; + } + $dumper = $connector->getDumper(); + $dumper->levelLimit = $this->options['dumperLevelLimit']; + $dumper->itemsCountLimit = $this->options['dumperItemsCountLimit']; + $dumper->itemSizeLimit = $this->options['dumperItemSizeLimit']; + $dumper->dumpSizeLimit = $this->options['dumperDumpSizeLimit']; + $dumper->detectCallbacks = $this->options['dumperDetectCallbacks']; + if ($this->options['enableEvalListener']) { + $connector->startEvalRequestsListener(); + } + } + + return $connector; + } + + public function getConnector() + { + return $this->connector; + } + + public function getOptions() + { + return $this->options; + } + + public function handle(array $record) + { + if ($this->options['enabled'] && $this->connector->isActiveClient()) { + return parent::handle($record); + } + + return !$this->bubble; + } + + /** + * Writes the record down to the log of the implementing handler + * + * @param array $record + * @return void + */ + protected function write(array $record) + { + if ($record['level'] < Logger::NOTICE) { + $this->handleDebugRecord($record); + } elseif (isset($record['context']['exception']) && $record['context']['exception'] instanceof Exception) { + $this->handleExceptionRecord($record); + } else { + $this->handleErrorRecord($record); + } + } + + private function handleDebugRecord(array $record) + { + $tags = $this->getRecordTags($record); + $message = $record['message']; + if ($record['context']) { + $message .= ' ' . json_encode($this->connector->getDumper()->dump(array_filter($record['context']))); + } + $this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']); + } + + private function handleExceptionRecord(array $record) + { + $this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']); + } + + private function handleErrorRecord(array $record) + { + $context = $record['context']; + + $this->connector->getErrorsDispatcher()->dispatchError( + isset($context['code']) ? $context['code'] : null, + isset($context['message']) ? $context['message'] : $record['message'], + isset($context['file']) ? $context['file'] : null, + isset($context['line']) ? $context['line'] : null, + $this->options['classesPartialsTraceIgnore'] + ); + } + + private function getRecordTags(array &$record) + { + $tags = null; + if (!empty($record['context'])) { + $context = & $record['context']; + foreach ($this->options['debugTagsKeysInContext'] as $key) { + if (!empty($context[$key])) { + $tags = $context[$key]; + if ($key === 0) { + array_shift($context); + } else { + unset($context[$key]); + } + break; + } + } + } + + return $tags ?: strtolower($record['level_name']); + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('%message%'); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php new file mode 100644 index 0000000..1ae8584 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Psr\Log\LoggerInterface; + +/** + * Proxies log messages to an existing PSR-3 compliant logger. + * + * @author Michael Moussa + */ +class PsrHandler extends AbstractHandler +{ + /** + * PSR-3 compliant logger + * + * @var LoggerInterface + */ + protected $logger; + + /** + * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied + * @param int $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(LoggerInterface $logger, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->logger = $logger; + } + + /** + * {@inheritDoc} + */ + public function handle(array $record) + { + if (!$this->isHandling($record)) { + return false; + } + + $this->logger->log(strtolower($record['level_name']), $record['message'], $record['context']); + + return false === $this->bubble; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php new file mode 100644 index 0000000..9917b64 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php @@ -0,0 +1,185 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Sends notifications through the pushover api to mobile phones + * + * @author Sebastian Göttschkes + * @see https://www.pushover.net/api + */ +class PushoverHandler extends SocketHandler +{ + private $token; + private $users; + private $title; + private $user; + private $retry; + private $expire; + + private $highPriorityLevel; + private $emergencyLevel; + private $useFormattedMessage = false; + + /** + * All parameters that can be sent to Pushover + * @see https://pushover.net/api + * @var array + */ + private $parameterNames = array( + 'token' => true, + 'user' => true, + 'message' => true, + 'device' => true, + 'title' => true, + 'url' => true, + 'url_title' => true, + 'priority' => true, + 'timestamp' => true, + 'sound' => true, + 'retry' => true, + 'expire' => true, + 'callback' => true, + ); + + /** + * Sounds the api supports by default + * @see https://pushover.net/api#sounds + * @var array + */ + private $sounds = array( + 'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', + 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', + 'persistent', 'echo', 'updown', 'none', + ); + + /** + * @param string $token Pushover api token + * @param string|array $users Pushover user id or array of ids the message will be sent to + * @param string $title Title sent to the Pushover API + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $useSSL Whether to connect via SSL. Required when pushing messages to users that are not + * the pushover.net app owner. OpenSSL is required for this option. + * @param integer $highPriorityLevel The minimum logging level at which this handler will start + * sending "high priority" requests to the Pushover API + * @param integer $emergencyLevel The minimum logging level at which this handler will start + * sending "emergency" requests to the Pushover API + * @param integer $retry The retry parameter specifies how often (in seconds) the Pushover servers will send the same notification to the user. + * @param integer $expire The expire parameter specifies how many seconds your notification will continue to be retried for (every retry seconds). + */ + public function __construct($token, $users, $title = null, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $highPriorityLevel = Logger::CRITICAL, $emergencyLevel = Logger::EMERGENCY, $retry = 30, $expire = 25200) + { + $connectionString = $useSSL ? 'ssl://api.pushover.net:443' : 'api.pushover.net:80'; + parent::__construct($connectionString, $level, $bubble); + + $this->token = $token; + $this->users = (array) $users; + $this->title = $title ?: gethostname(); + $this->highPriorityLevel = Logger::toMonologLevel($highPriorityLevel); + $this->emergencyLevel = Logger::toMonologLevel($emergencyLevel); + $this->retry = $retry; + $this->expire = $expire; + } + + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + private function buildContent($record) + { + // Pushover has a limit of 512 characters on title and message combined. + $maxMessageLength = 512 - strlen($this->title); + + $message = ($this->useFormattedMessage) ? $record['formatted'] : $record['message']; + $message = substr($message, 0, $maxMessageLength); + + $timestamp = $record['datetime']->getTimestamp(); + + $dataArray = array( + 'token' => $this->token, + 'user' => $this->user, + 'message' => $message, + 'title' => $this->title, + 'timestamp' => $timestamp + ); + + if (isset($record['level']) && $record['level'] >= $this->emergencyLevel) { + $dataArray['priority'] = 2; + $dataArray['retry'] = $this->retry; + $dataArray['expire'] = $this->expire; + } elseif (isset($record['level']) && $record['level'] >= $this->highPriorityLevel) { + $dataArray['priority'] = 1; + } + + // First determine the available parameters + $context = array_intersect_key($record['context'], $this->parameterNames); + $extra = array_intersect_key($record['extra'], $this->parameterNames); + + // Least important info should be merged with subsequent info + $dataArray = array_merge($extra, $context, $dataArray); + + // Only pass sounds that are supported by the API + if (isset($dataArray['sound']) && !in_array($dataArray['sound'], $this->sounds)) { + unset($dataArray['sound']); + } + + return http_build_query($dataArray); + } + + private function buildHeader($content) + { + $header = "POST /1/messages.json HTTP/1.1\r\n"; + $header .= "Host: api.pushover.net\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } + + protected function write(array $record) + { + foreach ($this->users as $user) { + $this->user = $user; + + parent::write($record); + $this->closeSocket(); + } + + $this->user = null; + } + + public function setHighPriorityLevel($value) + { + $this->highPriorityLevel = $value; + } + + public function setEmergencyLevel($value) + { + $this->emergencyLevel = $value; + } + + /** + * Use the formatted message? + * @param boolean $value + */ + public function useFormattedMessage($value) + { + $this->useFormattedMessage = (boolean) $value; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php new file mode 100644 index 0000000..1807705 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php @@ -0,0 +1,207 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Formatter\FormatterInterface; +use Monolog\Logger; +use Raven_Client; + +/** + * Handler to send messages to a Sentry (https://github.com/getsentry/sentry) server + * using raven-php (https://github.com/getsentry/raven-php) + * + * @author Marc Abramowitz + */ +class RavenHandler extends AbstractProcessingHandler +{ + /** + * Translates Monolog log levels to Raven log levels. + */ + private $logLevels = array( + Logger::DEBUG => Raven_Client::DEBUG, + Logger::INFO => Raven_Client::INFO, + Logger::NOTICE => Raven_Client::INFO, + Logger::WARNING => Raven_Client::WARNING, + Logger::ERROR => Raven_Client::ERROR, + Logger::CRITICAL => Raven_Client::FATAL, + Logger::ALERT => Raven_Client::FATAL, + Logger::EMERGENCY => Raven_Client::FATAL, + ); + + /** + * @var Raven_Client the client object that sends the message to the server + */ + protected $ravenClient; + + /** + * @var LineFormatter The formatter to use for the logs generated via handleBatch() + */ + protected $batchFormatter; + + /** + * @param Raven_Client $ravenClient + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(Raven_Client $ravenClient, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->ravenClient = $ravenClient; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $level = $this->level; + + // filter records based on their level + $records = array_filter($records, function ($record) use ($level) { + return $record['level'] >= $level; + }); + + if (!$records) { + return; + } + + // the record with the highest severity is the "main" one + $record = array_reduce($records, function ($highest, $record) { + if ($record['level'] >= $highest['level']) { + return $record; + } + + return $highest; + }); + + // the other ones are added as a context item + $logs = array(); + foreach ($records as $r) { + $logs[] = $this->processRecord($r); + } + + if ($logs) { + $record['context']['logs'] = (string) $this->getBatchFormatter()->formatBatch($logs); + } + + $this->handle($record); + } + + /** + * Sets the formatter for the logs generated by handleBatch(). + * + * @param FormatterInterface $formatter + */ + public function setBatchFormatter(FormatterInterface $formatter) + { + $this->batchFormatter = $formatter; + } + + /** + * Gets the formatter for the logs generated by handleBatch(). + * + * @return FormatterInterface + */ + public function getBatchFormatter() + { + if (!$this->batchFormatter) { + $this->batchFormatter = $this->getDefaultBatchFormatter(); + } + + return $this->batchFormatter; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $previousUserContext = false; + $options = array(); + $options['level'] = $this->logLevels[$record['level']]; + $options['tags'] = array(); + if (!empty($record['extra']['tags'])) { + $options['tags'] = array_merge($options['tags'], $record['extra']['tags']); + unset($record['extra']['tags']); + } + if (!empty($record['context']['tags'])) { + $options['tags'] = array_merge($options['tags'], $record['context']['tags']); + unset($record['context']['tags']); + } + if (!empty($record['context']['logger'])) { + $options['logger'] = $record['context']['logger']; + unset($record['context']['logger']); + } else { + $options['logger'] = $record['channel']; + } + foreach ($this->getExtraParameters() as $key) { + foreach (array('extra', 'context') as $source) { + if (!empty($record[$source][$key])) { + $options[$key] = $record[$source][$key]; + unset($record[$source][$key]); + } + } + } + if (!empty($record['context'])) { + $options['extra']['context'] = $record['context']; + if (!empty($record['context']['user'])) { + $previousUserContext = $this->ravenClient->context->user; + $this->ravenClient->user_context($record['context']['user']); + unset($options['extra']['context']['user']); + } + } + if (!empty($record['extra'])) { + $options['extra']['extra'] = $record['extra']; + } + + if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) { + $options['extra']['message'] = $record['formatted']; + $this->ravenClient->captureException($record['context']['exception'], $options); + } else { + $this->ravenClient->captureMessage($record['formatted'], array(), $options); + } + + if ($previousUserContext !== false) { + $this->ravenClient->user_context($previousUserContext); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('[%channel%] %message%'); + } + + /** + * Gets the default formatter for the logs generated by handleBatch(). + * + * @return FormatterInterface + */ + protected function getDefaultBatchFormatter() + { + return new LineFormatter(); + } + + /** + * Gets extra parameters supported by Raven that can be found in "extra" and "context" + * + * @return array + */ + protected function getExtraParameters() + { + return array('checksum', 'release'); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php new file mode 100644 index 0000000..157e2f9 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; + +/** + * Logs to a Redis key using rpush + * + * usage example: + * + * $log = new Logger('application'); + * $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs", "prod"); + * $log->pushHandler($redis); + * + * @author Thomas Tourlourat + */ +class RedisHandler extends AbstractProcessingHandler +{ + private $redisClient; + private $redisKey; + protected $capSize; + + /** + * @param \Predis\Client|\Redis $redis The redis instance + * @param string $key The key name to push records to + * @param integer $level The minimum logging level at which this handler will be triggered + * @param boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param integer $capSize Number of entries to limit list size to + */ + public function __construct($redis, $key, $level = Logger::DEBUG, $bubble = true, $capSize = false) + { + if (!(($redis instanceof \Predis\Client) || ($redis instanceof \Redis))) { + throw new \InvalidArgumentException('Predis\Client or Redis instance required'); + } + + $this->redisClient = $redis; + $this->redisKey = $key; + $this->capSize = $capSize; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + if ($this->capSize) { + $this->writeCapped($record); + } else { + $this->redisClient->rpush($this->redisKey, $record["formatted"]); + } + } + + /** + * Write and cap the collection + * Writes the record to the redis list and caps its + * + * @param array $record associative record array + * @return void + */ + protected function writeCapped(array $record) + { + if ($this->redisClient instanceof \Redis) { + $this->redisClient->multi() + ->rpush($this->redisKey, $record["formatted"]) + ->ltrim($this->redisKey, -$this->capSize, -1) + ->execute(); + } else { + $redisKey = $this->redisKey; + $capSize = $this->capSize; + $this->redisClient->transaction(function ($tx) use ($record, $redisKey, $capSize) { + $tx->rpush($redisKey, $record["formatted"]); + $tx->ltrim($redisKey, -$capSize, -1); + }); + } + } + + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php new file mode 100644 index 0000000..0ad618d --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use RollbarNotifier; +use Exception; +use Monolog\Logger; + +/** + * Sends errors to Rollbar + * + * @author Paul Statezny + */ +class RollbarHandler extends AbstractProcessingHandler +{ + /** + * Rollbar notifier + * + * @var RollbarNotifier + */ + protected $rollbarNotifier; + + /** + * Records whether any log records have been added since the last flush of the rollbar notifier + * + * @var bool + */ + private $hasRecords = false; + + /** + * @param RollbarNotifier $rollbarNotifier RollbarNotifier object constructed with valid token + * @param integer $level The minimum logging level at which this handler will be triggered + * @param boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(RollbarNotifier $rollbarNotifier, $level = Logger::ERROR, $bubble = true) + { + $this->rollbarNotifier = $rollbarNotifier; + + parent::__construct($level, $bubble); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (isset($record['context']['exception']) && $record['context']['exception'] instanceof Exception) { + $context = $record['context']; + $exception = $context['exception']; + unset($context['exception']); + + $payload = array(); + if (isset($context['payload'])) { + $payload = $context['payload']; + unset($context['payload']); + } + + $this->rollbarNotifier->report_exception($exception, $context, $payload); + } else { + $extraData = array( + 'level' => $record['level'], + 'channel' => $record['channel'], + 'datetime' => $record['datetime']->format('U'), + ); + + $this->rollbarNotifier->report_message( + $record['message'], + $record['level_name'], + array_merge($record['context'], $record['extra'], $extraData) + ); + } + + $this->hasRecords = true; + } + + /** + * {@inheritdoc} + */ + public function close() + { + if ($this->hasRecords) { + $this->rollbarNotifier->flush(); + $this->hasRecords = false; + } + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php new file mode 100644 index 0000000..0a20377 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php @@ -0,0 +1,155 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores logs to files that are rotated every day and a limited number of files are kept. + * + * This rotation is only intended to be used as a workaround. Using logrotate to + * handle the rotation is strongly encouraged when you can use it. + * + * @author Christophe Coevoet + * @author Jordi Boggiano + */ +class RotatingFileHandler extends StreamHandler +{ + protected $filename; + protected $maxFiles; + protected $mustRotate; + protected $nextRotation; + protected $filenameFormat; + protected $dateFormat; + + /** + * @param string $filename + * @param integer $maxFiles The maximal amount of files to keep (0 means unlimited) + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) + * @param Boolean $useLocking Try to lock log file before doing any writes + */ + public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false) + { + $this->filename = $filename; + $this->maxFiles = (int) $maxFiles; + $this->nextRotation = new \DateTime('tomorrow'); + $this->filenameFormat = '{filename}-{date}'; + $this->dateFormat = 'Y-m-d'; + + parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking); + } + + /** + * {@inheritdoc} + */ + public function close() + { + parent::close(); + + if (true === $this->mustRotate) { + $this->rotate(); + } + } + + public function setFilenameFormat($filenameFormat, $dateFormat) + { + $this->filenameFormat = $filenameFormat; + $this->dateFormat = $dateFormat; + $this->url = $this->getTimedFilename(); + $this->close(); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + // on the first record written, if the log is new, we should rotate (once per day) + if (null === $this->mustRotate) { + $this->mustRotate = !file_exists($this->url); + } + + if ($this->nextRotation < $record['datetime']) { + $this->mustRotate = true; + $this->close(); + } + + parent::write($record); + } + + /** + * Rotates the files. + */ + protected function rotate() + { + // update filename + $this->url = $this->getTimedFilename(); + $this->nextRotation = new \DateTime('tomorrow'); + + // skip GC of old logs if files are unlimited + if (0 === $this->maxFiles) { + return; + } + + $logFiles = glob($this->getGlobPattern()); + if ($this->maxFiles >= count($logFiles)) { + // no files to remove + return; + } + + // Sorting the files by name to remove the older ones + usort($logFiles, function ($a, $b) { + return strcmp($b, $a); + }); + + foreach (array_slice($logFiles, $this->maxFiles) as $file) { + if (is_writable($file)) { + unlink($file); + } + } + + $this->mustRotate = false; + } + + protected function getTimedFilename() + { + $fileInfo = pathinfo($this->filename); + $timedFilename = str_replace( + array('{filename}', '{date}'), + array($fileInfo['filename'], date($this->dateFormat)), + $fileInfo['dirname'] . '/' . $this->filenameFormat + ); + + if (!empty($fileInfo['extension'])) { + $timedFilename .= '.'.$fileInfo['extension']; + } + + return $timedFilename; + } + + protected function getGlobPattern() + { + $fileInfo = pathinfo($this->filename); + $glob = str_replace( + array('{filename}', '{date}'), + array($fileInfo['filename'], '*'), + $fileInfo['dirname'] . '/' . $this->filenameFormat + ); + if (!empty($fileInfo['extension'])) { + $glob .= '.'.$fileInfo['extension']; + } + + return $glob; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php new file mode 100644 index 0000000..9509ae3 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Sampling handler + * + * A sampled event stream can be useful for logging high frequency events in + * a production environment where you only need an idea of what is happening + * and are not concerned with capturing every occurrence. Since the decision to + * handle or not handle a particular event is determined randomly, the + * resulting sampled log is not guaranteed to contain 1/N of the events that + * occurred in the application, but based on the Law of large numbers, it will + * tend to be close to this ratio with a large number of attempts. + * + * @author Bryan Davis + * @author Kunal Mehta + */ +class SamplingHandler extends AbstractHandler +{ + /** + * @var callable|HandlerInterface $handler + */ + protected $handler; + + /** + * @var int $factor + */ + protected $factor; + + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler). + * @param int $factor Sample factor + */ + public function __construct($handler, $factor) + { + parent::__construct(); + $this->handler = $handler; + $this->factor = $factor; + + if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { + throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); + } + } + + public function isHandling(array $record) + { + return $this->handler->isHandling($record); + } + + public function handle(array $record) + { + if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) { + // The same logic as in FingersCrossedHandler + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + $this->handler->handle($record); + } + + return false === $this->bubble; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php new file mode 100644 index 0000000..61245ff --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php @@ -0,0 +1,284 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +/** + * Sends notifications through Slack API + * + * @author Greg Kedzierski + * @see https://api.slack.com/ + */ +class SlackHandler extends SocketHandler +{ + /** + * Slack API token + * @var string + */ + private $token; + + /** + * Slack channel (encoded ID or name) + * @var string + */ + private $channel; + + /** + * Name of a bot + * @var string + */ + private $username; + + /** + * Emoji icon name + * @var string + */ + private $iconEmoji; + + /** + * Whether the message should be added to Slack as attachment (plain text otherwise) + * @var bool + */ + private $useAttachment; + + /** + * Whether the the context/extra messages added to Slack as attachments are in a short style + * @var bool + */ + private $useShortAttachment; + + /** + * Whether the attachment should include context and extra data + * @var bool + */ + private $includeContextAndExtra; + + /** + * @var LineFormatter + */ + private $lineFormatter; + + /** + * @param string $token Slack API token + * @param string $channel Slack channel (encoded ID or name) + * @param string $username Name of a bot + * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise) + * @param string|null $iconEmoji The emoji name to use (or null) + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style + * @param bool $includeContextAndExtra Whether the attachment should include context and extra data + */ + public function __construct($token, $channel, $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $level = Logger::CRITICAL, $bubble = true, $useShortAttachment = false, $includeContextAndExtra = false) + { + if (!extension_loaded('openssl')) { + throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler'); + } + + parent::__construct('ssl://slack.com:443', $level, $bubble); + + $this->token = $token; + $this->channel = $channel; + $this->username = $username; + $this->iconEmoji = trim($iconEmoji, ':'); + $this->useAttachment = $useAttachment; + $this->useShortAttachment = $useShortAttachment; + $this->includeContextAndExtra = $includeContextAndExtra; + if ($this->includeContextAndExtra) { + $this->lineFormatter = new LineFormatter; + } + } + + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + + return $this->buildHeader($content) . $content; + } + + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = $this->prepareContentData($record); + + return http_build_query($dataArray); + } + + /** + * Prepares content data + * + * @param array $record + * @return array + */ + protected function prepareContentData($record) + { + $dataArray = array( + 'token' => $this->token, + 'channel' => $this->channel, + 'username' => $this->username, + 'text' => '', + 'attachments' => array() + ); + + if ($this->useAttachment) { + $attachment = array( + 'fallback' => $record['message'], + 'color' => $this->getAttachmentColor($record['level']), + 'fields' => array() + ); + + if ($this->useShortAttachment) { + $attachment['title'] = $record['level_name']; + $attachment['text'] = $record['message']; + } else { + $attachment['title'] = 'Message'; + $attachment['text'] = $record['message']; + $attachment['fields'][] = array( + 'title' => 'Level', + 'value' => $record['level_name'], + 'short' => true + ); + } + + if ($this->includeContextAndExtra) { + if (!empty($record['extra'])) { + if ($this->useShortAttachment) { + $attachment['fields'][] = array( + 'title' => "Extra", + 'value' => $this->stringify($record['extra']), + 'short' => $this->useShortAttachment + ); + } else { + // Add all extra fields as individual fields in attachment + foreach ($record['extra'] as $var => $val) { + $attachment['fields'][] = array( + 'title' => $var, + 'value' => $val, + 'short' => $this->useShortAttachment + ); + } + } + } + + if (!empty($record['context'])) { + if ($this->useShortAttachment) { + $attachment['fields'][] = array( + 'title' => "Context", + 'value' => $this->stringify($record['context']), + 'short' => $this->useShortAttachment + ); + } else { + // Add all context fields as individual fields in attachment + foreach ($record['context'] as $var => $val) { + $attachment['fields'][] = array( + 'title' => $var, + 'value' => $val, + 'short' => $this->useShortAttachment + ); + } + } + } + } + + $dataArray['attachments'] = json_encode(array($attachment)); + } else { + $dataArray['text'] = $record['message']; + } + + if ($this->iconEmoji) { + $dataArray['icon_emoji'] = ":{$this->iconEmoji}:"; + } + + return $dataArray; + } + + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST /api/chat.postMessage HTTP/1.1\r\n"; + $header .= "Host: slack.com\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . strlen($content) . "\r\n"; + $header .= "\r\n"; + + return $header; + } + + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + $this->closeSocket(); + } + + /** + * Returned a Slack message attachment color associated with + * provided level. + * + * @param int $level + * @return string + */ + protected function getAttachmentColor($level) + { + switch (true) { + case $level >= Logger::ERROR: + return 'danger'; + case $level >= Logger::WARNING: + return 'warning'; + case $level >= Logger::INFO: + return 'good'; + default: + return '#e3e4e6'; + } + } + + /** + * Stringifies an array of key/value pairs to be used in attachment fields + * + * @param array $fields + * @access protected + * @return string + */ + protected function stringify($fields) + { + $string = ''; + foreach ($fields as $var => $val) { + $string .= $var.': '.$this->lineFormatter->stringify($val)." | "; + } + + $string = rtrim($string, " |"); + + return $string; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php new file mode 100644 index 0000000..a3e7252 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php @@ -0,0 +1,284 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores to any socket - uses fsockopen() or pfsockopen(). + * + * @author Pablo de Leon Belloc + * @see http://php.net/manual/en/function.fsockopen.php + */ +class SocketHandler extends AbstractProcessingHandler +{ + private $connectionString; + private $connectionTimeout; + private $resource; + private $timeout = 0; + private $persistent = false; + private $errno; + private $errstr; + + /** + * @param string $connectionString Socket connection string + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($connectionString, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + $this->connectionString = $connectionString; + $this->connectionTimeout = (float) ini_get('default_socket_timeout'); + } + + /** + * Connect (if necessary) and write to the socket + * + * @param array $record + * + * @throws \UnexpectedValueException + * @throws \RuntimeException + */ + protected function write(array $record) + { + $this->connectIfNotConnected(); + $data = $this->generateDataStream($record); + $this->writeToSocket($data); + } + + /** + * We will not close a PersistentSocket instance so it can be reused in other requests. + */ + public function close() + { + if (!$this->isPersistent()) { + $this->closeSocket(); + } + } + + /** + * Close socket, if open + */ + public function closeSocket() + { + if (is_resource($this->resource)) { + fclose($this->resource); + $this->resource = null; + } + } + + /** + * Set socket connection to nbe persistent. It only has effect before the connection is initiated. + * + * @param boolean $persistent + */ + public function setPersistent($persistent) + { + $this->persistent = (boolean) $persistent; + } + + /** + * Set connection timeout. Only has effect before we connect. + * + * @param float $seconds + * + * @see http://php.net/manual/en/function.fsockopen.php + */ + public function setConnectionTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->connectionTimeout = (float) $seconds; + } + + /** + * Set write timeout. Only has effect before we connect. + * + * @param float $seconds + * + * @see http://php.net/manual/en/function.stream-set-timeout.php + */ + public function setTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->timeout = (float) $seconds; + } + + /** + * Get current connection string + * + * @return string + */ + public function getConnectionString() + { + return $this->connectionString; + } + + /** + * Get persistent setting + * + * @return boolean + */ + public function isPersistent() + { + return $this->persistent; + } + + /** + * Get current connection timeout setting + * + * @return float + */ + public function getConnectionTimeout() + { + return $this->connectionTimeout; + } + + /** + * Get current in-transfer timeout + * + * @return float + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * Check to see if the socket is currently available. + * + * UDP might appear to be connected but might fail when writing. See http://php.net/fsockopen for details. + * + * @return boolean + */ + public function isConnected() + { + return is_resource($this->resource) + && !feof($this->resource); // on TCP - other party can close connection. + } + + /** + * Wrapper to allow mocking + */ + protected function pfsockopen() + { + return @pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); + } + + /** + * Wrapper to allow mocking + */ + protected function fsockopen() + { + return @fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); + } + + /** + * Wrapper to allow mocking + * + * @see http://php.net/manual/en/function.stream-set-timeout.php + */ + protected function streamSetTimeout() + { + $seconds = floor($this->timeout); + $microseconds = round(($this->timeout - $seconds) * 1e6); + + return stream_set_timeout($this->resource, $seconds, $microseconds); + } + + /** + * Wrapper to allow mocking + */ + protected function fwrite($data) + { + return @fwrite($this->resource, $data); + } + + /** + * Wrapper to allow mocking + */ + protected function streamGetMetadata() + { + return stream_get_meta_data($this->resource); + } + + private function validateTimeout($value) + { + $ok = filter_var($value, FILTER_VALIDATE_FLOAT); + if ($ok === false || $value < 0) { + throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got $value)"); + } + } + + private function connectIfNotConnected() + { + if ($this->isConnected()) { + return; + } + $this->connect(); + } + + protected function generateDataStream($record) + { + return (string) $record['formatted']; + } + + private function connect() + { + $this->createSocketResource(); + $this->setSocketTimeout(); + } + + private function createSocketResource() + { + if ($this->isPersistent()) { + $resource = $this->pfsockopen(); + } else { + $resource = $this->fsockopen(); + } + if (!$resource) { + throw new \UnexpectedValueException("Failed connecting to $this->connectionString ($this->errno: $this->errstr)"); + } + $this->resource = $resource; + } + + private function setSocketTimeout() + { + if (!$this->streamSetTimeout()) { + throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()"); + } + } + + private function writeToSocket($data) + { + $length = strlen($data); + $sent = 0; + while ($this->isConnected() && $sent < $length) { + if (0 == $sent) { + $chunk = $this->fwrite($data); + } else { + $chunk = $this->fwrite(substr($data, $sent)); + } + if ($chunk === false) { + throw new \RuntimeException("Could not write to socket"); + } + $sent += $chunk; + $socketInfo = $this->streamGetMetadata(); + if ($socketInfo['timed_out']) { + throw new \RuntimeException("Write timed-out"); + } + } + if (!$this->isConnected() && $sent < $length) { + throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent $sent of $length)"); + } + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php new file mode 100644 index 0000000..28b9b11 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Stores to any stream resource + * + * Can be used to store into php://stderr, remote and local files, etc. + * + * @author Jordi Boggiano + */ +class StreamHandler extends AbstractProcessingHandler +{ + protected $stream; + protected $url; + private $errorMessage; + protected $filePermission; + protected $useLocking; + private $dirCreated; + + /** + * @param resource|string $stream + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) + * @param Boolean $useLocking Try to lock log file before doing any writes + * + * @throws \Exception If a missing directory is not buildable + * @throws \InvalidArgumentException If stream is not a resource or string + */ + public function __construct($stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false) + { + parent::__construct($level, $bubble); + if (is_resource($stream)) { + $this->stream = $stream; + } elseif (is_string($stream)) { + $this->url = $stream; + } else { + throw new \InvalidArgumentException('A stream must either be a resource or a string.'); + } + + $this->filePermission = $filePermission; + $this->useLocking = $useLocking; + } + + /** + * {@inheritdoc} + */ + public function close() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } + $this->stream = null; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (!is_resource($this->stream)) { + if (!$this->url) { + throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); + } + $this->createDir(); + $this->errorMessage = null; + set_error_handler(array($this, 'customErrorHandler')); + $this->stream = fopen($this->url, 'a'); + if ($this->filePermission !== null) { + @chmod($this->url, $this->filePermission); + } + restore_error_handler(); + if (!is_resource($this->stream)) { + $this->stream = null; + throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url)); + } + } + + if ($this->useLocking) { + // ignoring errors here, there's not much we can do about them + flock($this->stream, LOCK_EX); + } + + fwrite($this->stream, (string) $record['formatted']); + + if ($this->useLocking) { + flock($this->stream, LOCK_UN); + } + } + + private function customErrorHandler($code, $msg) + { + $this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg); + } + + /** + * @param string $stream + * + * @return null|string + */ + private function getDirFromStream($stream) + { + $pos = strpos($stream, '://'); + if ($pos === false) { + return dirname($stream); + } + + if ('file://' === substr($stream, 0, 7)) { + return dirname(substr($stream, 7)); + } + + return; + } + + private function createDir() + { + // Do not try to create dir if it has already been tried. + if ($this->dirCreated) { + return; + } + + $dir = $this->getDirFromStream($this->url); + if (null !== $dir && !is_dir($dir)) { + $this->errorMessage = null; + set_error_handler(array($this, 'customErrorHandler')); + $status = mkdir($dir, 0777, true); + restore_error_handler(); + if (false === $status) { + throw new \UnexpectedValueException(sprintf('There is no existing directory at "%s" and its not buildable: '.$this->errorMessage, $dir)); + } + } + $this->dirCreated = true; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php new file mode 100644 index 0000000..5c2b156 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * SwiftMailerHandler uses Swift_Mailer to send the emails + * + * @author Gyula Sallai + */ +class SwiftMailerHandler extends MailHandler +{ + protected $mailer; + private $messageTemplate; + + /** + * @param \Swift_Mailer $mailer The mailer to use + * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true) + { + parent::__construct($level, $bubble); + + $this->mailer = $mailer; + $this->messageTemplate = $message; + } + + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $this->mailer->send($this->buildMessage($content, $records)); + } + + /** + * Creates instance of Swift_Message to be sent + * + * @param string $content formatted email body to be sent + * @param array $records Log records that formed the content + * @return \Swift_Message + */ + protected function buildMessage($content, array $records) + { + $message = null; + if ($this->messageTemplate instanceof \Swift_Message) { + $message = clone $this->messageTemplate; + $message->generateId(); + } elseif (is_callable($this->messageTemplate)) { + $message = call_user_func($this->messageTemplate, $content, $records); + } + + if (!$message instanceof \Swift_Message) { + throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it'); + } + + $message->setBody($content); + $message->setDate(time()); + + return $message; + } + + /** + * BC getter, to be removed in 2.0 + */ + public function __get($name) + { + if ($name === 'message') { + trigger_error('SwiftMailerHandler->message is deprecated, use ->buildMessage() instead to retrieve the message', E_USER_DEPRECATED); + + return $this->buildMessage(null, array()); + } + + throw new \InvalidArgumentException('Invalid property '.$name); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php new file mode 100644 index 0000000..47c73e1 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * Logs to syslog service. + * + * usage example: + * + * $log = new Logger('application'); + * $syslog = new SyslogHandler('myfacility', 'local6'); + * $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%"); + * $syslog->setFormatter($formatter); + * $log->pushHandler($syslog); + * + * @author Sven Paulus + */ +class SyslogHandler extends AbstractSyslogHandler +{ + protected $ident; + protected $logopts; + + /** + * @param string $ident + * @param mixed $facility + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID + */ + public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true, $logopts = LOG_PID) + { + parent::__construct($facility, $level, $bubble); + + $this->ident = $ident; + $this->logopts = $logopts; + } + + /** + * {@inheritdoc} + */ + public function close() + { + closelog(); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (!openlog($this->ident, $this->logopts, $this->facility)) { + throw new \LogicException('Can\'t open syslog for ident "'.$this->ident.'" and facility "'.$this->facility.'"'); + } + syslog($this->logLevels[$record['level']], (string) $record['formatted']); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php b/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php new file mode 100644 index 0000000..3bff085 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler\SyslogUdp; + +class UdpSocket +{ + const DATAGRAM_MAX_LENGTH = 65023; + + protected $ip; + protected $port; + protected $socket; + + public function __construct($ip, $port = 514) + { + $this->ip = $ip; + $this->port = $port; + $this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + } + + public function write($line, $header = "") + { + $this->send($this->assembleMessage($line, $header)); + } + + public function close() + { + if (is_resource($this->socket)) { + socket_close($this->socket); + $this->socket = null; + } + } + + protected function send($chunk) + { + if (!is_resource($this->socket)) { + throw new \LogicException('The UdpSocket to '.$this->ip.':'.$this->port.' has been closed and can not be written to anymore'); + } + socket_sendto($this->socket, $chunk, strlen($chunk), $flags = 0, $this->ip, $this->port); + } + + protected function assembleMessage($line, $header) + { + $chunkSize = self::DATAGRAM_MAX_LENGTH - strlen($header); + + return $header . substr($line, 0, $chunkSize); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php new file mode 100644 index 0000000..2e32fa7 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Handler\SyslogUdp\UdpSocket; + +/** + * A Handler for logging to a remote syslogd server. + * + * @author Jesper Skovgaard Nielsen + */ +class SyslogUdpHandler extends AbstractSyslogHandler +{ + protected $socket; + + /** + * @param string $host + * @param int $port + * @param mixed $facility + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($host, $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($facility, $level, $bubble); + + $this->socket = new UdpSocket($host, $port ?: 514); + } + + protected function write(array $record) + { + $lines = $this->splitMessageIntoLines($record['formatted']); + + $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']]); + + foreach ($lines as $line) { + $this->socket->write($line, $header); + } + } + + public function close() + { + $this->socket->close(); + } + + private function splitMessageIntoLines($message) + { + if (is_array($message)) { + $message = implode("\n", $message); + } + + return preg_split('/$\R?^/m', $message); + } + + /** + * Make common syslog header (see rfc5424) + */ + protected function makeCommonSyslogHeader($severity) + { + $priority = $severity + $this->facility; + + return "<$priority>1 "; + } + + /** + * Inject your own socket, mainly used for testing + */ + public function setSocket($socket) + { + $this->socket = $socket; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php new file mode 100644 index 0000000..e24fa9e --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php @@ -0,0 +1,148 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Used for testing purposes. + * + * It records all records and gives you access to them for verification. + * + * @author Jordi Boggiano + * + * @method boolean hasEmergency($record) + * @method boolean hasAlert($record) + * @method boolean hasCritical($record) + * @method boolean hasError($record) + * @method boolean hasWarning($record) + * @method boolean hasNotice($record) + * @method boolean hasInfo($record) + * @method boolean hasDebug($record) + * + * @method boolean hasEmergencyRecords() + * @method boolean hasAlertRecords() + * @method boolean hasCriticalRecords() + * @method boolean hasErrorRecords() + * @method boolean hasWarningRecords() + * @method boolean hasNoticeRecords() + * @method boolean hasInfoRecords() + * @method boolean hasDebugRecords() + * + * @method boolean hasEmergencyThatContains($message) + * @method boolean hasAlertThatContains($message) + * @method boolean hasCriticalThatContains($message) + * @method boolean hasErrorThatContains($message) + * @method boolean hasWarningThatContains($message) + * @method boolean hasNoticeThatContains($message) + * @method boolean hasInfoThatContains($message) + * @method boolean hasDebugThatContains($message) + * + * @method boolean hasEmergencyThatMatches($message) + * @method boolean hasAlertThatMatches($message) + * @method boolean hasCriticalThatMatches($message) + * @method boolean hasErrorThatMatches($message) + * @method boolean hasWarningThatMatches($message) + * @method boolean hasNoticeThatMatches($message) + * @method boolean hasInfoThatMatches($message) + * @method boolean hasDebugThatMatches($message) + * + * @method boolean hasEmergencyThatPasses($message) + * @method boolean hasAlertThatPasses($message) + * @method boolean hasCriticalThatPasses($message) + * @method boolean hasErrorThatPasses($message) + * @method boolean hasWarningThatPasses($message) + * @method boolean hasNoticeThatPasses($message) + * @method boolean hasInfoThatPasses($message) + * @method boolean hasDebugThatPasses($message) + */ +class TestHandler extends AbstractProcessingHandler +{ + protected $records = array(); + protected $recordsByLevel = array(); + + public function getRecords() + { + return $this->records; + } + + protected function hasRecordRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + protected function hasRecord($record, $level) + { + if (is_array($record)) { + $record = $record['message']; + } + + return $this->hasRecordThatPasses(function ($rec) use ($record) { + return $rec['message'] === $record; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses($predicate, $level) + { + if (!is_callable($predicate)) { + throw new \InvalidArgumentException("Expected a callable for hasRecordThatSucceeds"); + } + + if (!isset($this->recordsByLevel[$level])) { + return false; + } + + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . 'Record' . $matches[3]; + $level = constant('Monolog\Logger::' . strtoupper($matches[2])); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + + return call_user_func_array(array($this, $genericMethod), $args); + } + } + + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php new file mode 100644 index 0000000..05a8817 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * Forwards records to multiple handlers suppressing failures of each handler + * and continuing through to give every handler a chance to succeed. + * + * @author Craig D'Amelio + */ +class WhatFailureGroupHandler extends GroupHandler +{ + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + } + + foreach ($this->handlers as $handler) { + try { + $handler->handle($record); + } catch (\Exception $e) { + // What failure? + } + } + + return false === $this->bubble; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + foreach ($this->handlers as $handler) { + try { + $handler->handleBatch($records); + } catch (\Exception $e) { + // What failure? + } + } + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php new file mode 100644 index 0000000..f22cf21 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\NormalizerFormatter; +use Monolog\Logger; + +/** + * Handler sending logs to Zend Monitor + * + * @author Christian Bergau + */ +class ZendMonitorHandler extends AbstractProcessingHandler +{ + /** + * Monolog level / ZendMonitor Custom Event priority map + * + * @var array + */ + protected $levelMap = array( + Logger::DEBUG => 1, + Logger::INFO => 2, + Logger::NOTICE => 3, + Logger::WARNING => 4, + Logger::ERROR => 5, + Logger::CRITICAL => 6, + Logger::ALERT => 7, + Logger::EMERGENCY => 0, + ); + + /** + * Construct + * + * @param int $level + * @param bool $bubble + * @throws MissingExtensionException + */ + public function __construct($level = Logger::DEBUG, $bubble = true) + { + if (!function_exists('zend_monitor_custom_event')) { + throw new MissingExtensionException('You must have Zend Server installed in order to use this handler'); + } + parent::__construct($level, $bubble); + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->writeZendMonitorCustomEvent( + $this->levelMap[$record['level']], + $record['message'], + $record['formatted'] + ); + } + + /** + * Write a record to Zend Monitor + * + * @param int $level + * @param string $message + * @param array $formatted + */ + protected function writeZendMonitorCustomEvent($level, $message, $formatted) + { + zend_monitor_custom_event($level, $message, $formatted); + } + + /** + * {@inheritdoc} + */ + public function getDefaultFormatter() + { + return new NormalizerFormatter(); + } + + /** + * Get the level map + * + * @return array + */ + public function getLevelMap() + { + return $this->levelMap; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Logger.php b/vendor/monolog/monolog/src/Monolog/Logger.php new file mode 100644 index 0000000..d31a098 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Logger.php @@ -0,0 +1,649 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use Monolog\Handler\HandlerInterface; +use Monolog\Handler\StreamHandler; +use Psr\Log\LoggerInterface; +use Psr\Log\InvalidArgumentException; + +/** + * Monolog log channel + * + * It contains a stack of Handlers and a stack of Processors, + * and uses them to store records that are added to it. + * + * @author Jordi Boggiano + */ +class Logger implements LoggerInterface +{ + /** + * Detailed debug information + */ + const DEBUG = 100; + + /** + * Interesting events + * + * Examples: User logs in, SQL logs. + */ + const INFO = 200; + + /** + * Uncommon events + */ + const NOTICE = 250; + + /** + * Exceptional occurrences that are not errors + * + * Examples: Use of deprecated APIs, poor use of an API, + * undesirable things that are not necessarily wrong. + */ + const WARNING = 300; + + /** + * Runtime errors + */ + const ERROR = 400; + + /** + * Critical conditions + * + * Example: Application component unavailable, unexpected exception. + */ + const CRITICAL = 500; + + /** + * Action must be taken immediately + * + * Example: Entire website down, database unavailable, etc. + * This should trigger the SMS alerts and wake you up. + */ + const ALERT = 550; + + /** + * Urgent alert. + */ + const EMERGENCY = 600; + + /** + * Monolog API version + * + * This is only bumped when API breaks are done and should + * follow the major version of the library + * + * @var int + */ + const API = 1; + + /** + * Logging levels from syslog protocol defined in RFC 5424 + * + * @var array $levels Logging levels + */ + protected static $levels = array( + 100 => 'DEBUG', + 200 => 'INFO', + 250 => 'NOTICE', + 300 => 'WARNING', + 400 => 'ERROR', + 500 => 'CRITICAL', + 550 => 'ALERT', + 600 => 'EMERGENCY', + ); + + /** + * @var \DateTimeZone + */ + protected static $timezone; + + /** + * @var string + */ + protected $name; + + /** + * The handler stack + * + * @var HandlerInterface[] + */ + protected $handlers; + + /** + * Processors that will process all log records + * + * To process records of a single handler instead, add the processor on that specific handler + * + * @var callable[] + */ + protected $processors; + + /** + * @param string $name The logging channel + * @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc. + * @param callable[] $processors Optional array of processors + */ + public function __construct($name, array $handlers = array(), array $processors = array()) + { + $this->name = $name; + $this->handlers = $handlers; + $this->processors = $processors; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Pushes a handler on to the stack. + * + * @param HandlerInterface $handler + * @return $this + */ + public function pushHandler(HandlerInterface $handler) + { + array_unshift($this->handlers, $handler); + + return $this; + } + + /** + * Pops a handler from the stack + * + * @return HandlerInterface + */ + public function popHandler() + { + if (!$this->handlers) { + throw new \LogicException('You tried to pop from an empty handler stack.'); + } + + return array_shift($this->handlers); + } + + /** + * Set handlers, replacing all existing ones. + * + * If a map is passed, keys will be ignored. + * + * @param HandlerInterface[] $handlers + * @return $this + */ + public function setHandlers(array $handlers) + { + $this->handlers = array(); + foreach (array_reverse($handlers) as $handler) { + $this->pushHandler($handler); + } + + return $this; + } + + /** + * @return HandlerInterface[] + */ + public function getHandlers() + { + return $this->handlers; + } + + /** + * Adds a processor on to the stack. + * + * @param callable $callback + * @return $this + */ + public function pushProcessor($callback) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); + } + array_unshift($this->processors, $callback); + + return $this; + } + + /** + * Removes the processor on top of the stack and returns it. + * + * @return callable + */ + public function popProcessor() + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + + return array_shift($this->processors); + } + + /** + * @return callable[] + */ + public function getProcessors() + { + return $this->processors; + } + + /** + * Adds a log record. + * + * @param integer $level The logging level + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addRecord($level, $message, array $context = array()) + { + if (!$this->handlers) { + $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG)); + } + + $levelName = static::getLevelName($level); + + // check if any handler will handle this message so we can return early and save cycles + $handlerKey = null; + foreach ($this->handlers as $key => $handler) { + if ($handler->isHandling(array('level' => $level))) { + $handlerKey = $key; + break; + } + } + + if (null === $handlerKey) { + return false; + } + + if (!static::$timezone) { + static::$timezone = new \DateTimeZone(date_default_timezone_get() ?: 'UTC'); + } + + $record = array( + 'message' => (string) $message, + 'context' => $context, + 'level' => $level, + 'level_name' => $levelName, + 'channel' => $this->name, + 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), static::$timezone)->setTimezone(static::$timezone), + 'extra' => array(), + ); + + foreach ($this->processors as $processor) { + $record = call_user_func($processor, $record); + } + while (isset($this->handlers[$handlerKey]) && + false === $this->handlers[$handlerKey]->handle($record)) { + $handlerKey++; + } + + return true; + } + + /** + * Adds a log record at the DEBUG level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addDebug($message, array $context = array()) + { + return $this->addRecord(static::DEBUG, $message, $context); + } + + /** + * Adds a log record at the INFO level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addInfo($message, array $context = array()) + { + return $this->addRecord(static::INFO, $message, $context); + } + + /** + * Adds a log record at the NOTICE level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addNotice($message, array $context = array()) + { + return $this->addRecord(static::NOTICE, $message, $context); + } + + /** + * Adds a log record at the WARNING level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addWarning($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + + /** + * Adds a log record at the ERROR level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addError($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + + /** + * Adds a log record at the CRITICAL level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addCritical($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + + /** + * Adds a log record at the ALERT level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addAlert($message, array $context = array()) + { + return $this->addRecord(static::ALERT, $message, $context); + } + + /** + * Adds a log record at the EMERGENCY level. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function addEmergency($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + + /** + * Gets all supported logging levels. + * + * @return array Assoc array with human-readable level names => level codes. + */ + public static function getLevels() + { + return array_flip(static::$levels); + } + + /** + * Gets the name of the logging level. + * + * @param integer $level + * @return string + */ + public static function getLevelName($level) + { + if (!isset(static::$levels[$level])) { + throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); + } + + return static::$levels[$level]; + } + + /** + * Converts PSR-3 levels to Monolog ones if necessary + * + * @param string|int Level number (monolog) or name (PSR-3) + * @return int + */ + public static function toMonologLevel($level) + { + if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) { + return constant(__CLASS__.'::'.strtoupper($level)); + } + + return $level; + } + + /** + * Checks whether the Logger has a handler that listens on the given level + * + * @param integer $level + * @return Boolean + */ + public function isHandling($level) + { + $record = array( + 'level' => $level, + ); + + foreach ($this->handlers as $handler) { + if ($handler->isHandling($record)) { + return true; + } + } + + return false; + } + + /** + * Adds a log record at an arbitrary level. + * + * This method allows for compatibility with common interfaces. + * + * @param mixed $level The log level + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function log($level, $message, array $context = array()) + { + $level = static::toMonologLevel($level); + + return $this->addRecord($level, $message, $context); + } + + /** + * Adds a log record at the DEBUG level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function debug($message, array $context = array()) + { + return $this->addRecord(static::DEBUG, $message, $context); + } + + /** + * Adds a log record at the INFO level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function info($message, array $context = array()) + { + return $this->addRecord(static::INFO, $message, $context); + } + + /** + * Adds a log record at the NOTICE level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function notice($message, array $context = array()) + { + return $this->addRecord(static::NOTICE, $message, $context); + } + + /** + * Adds a log record at the WARNING level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function warn($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + + /** + * Adds a log record at the WARNING level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function warning($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + + /** + * Adds a log record at the ERROR level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function err($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + + /** + * Adds a log record at the ERROR level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function error($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + + /** + * Adds a log record at the CRITICAL level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function crit($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + + /** + * Adds a log record at the CRITICAL level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function critical($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + + /** + * Adds a log record at the ALERT level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function alert($message, array $context = array()) + { + return $this->addRecord(static::ALERT, $message, $context); + } + + /** + * Adds a log record at the EMERGENCY level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function emerg($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + + /** + * Adds a log record at the EMERGENCY level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return Boolean Whether the record has been processed + */ + public function emergency($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + + /** + * Set the timezone to be used for the timestamp of log records. + * + * This is stored globally for all Logger instances + * + * @param \DateTimeZone $tz Timezone object + */ + public static function setTimezone(\DateTimeZone $tz) + { + self::$timezone = $tz; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php new file mode 100644 index 0000000..1899400 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\Logger; + +/** + * Injects Git branch and Git commit SHA in all records + * + * @author Nick Otter + * @author Jordi Boggiano + */ +class GitProcessor +{ + private $level; + private static $cache; + + public function __construct($level = Logger::DEBUG) + { + $this->level = Logger::toMonologLevel($level); + } + + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // return if the level is not high enough + if ($record['level'] < $this->level) { + return $record; + } + + $record['extra']['git'] = self::getGitInfo(); + + return $record; + } + + private static function getGitInfo() + { + if (self::$cache) { + return self::$cache; + } + + $branches = `git branch -v --no-abbrev`; + if (preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) { + return self::$cache = array( + 'branch' => $matches[1], + 'commit' => $matches[2], + ); + } + + return self::$cache = array(); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php new file mode 100644 index 0000000..8f553fe --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\Logger; + +/** + * Injects line/file:class/function where the log message came from + * + * Warning: This only works if the handler processes the logs directly. + * If you put the processor on a handler that is behind a FingersCrossedHandler + * for example, the processor will only be called once the trigger level is reached, + * and all the log records will have the same file/line/.. data from the call that + * triggered the FingersCrossedHandler. + * + * @author Jordi Boggiano + */ +class IntrospectionProcessor +{ + private $level; + + private $skipClassesPartials; + + private $skipFunctions = array( + 'call_user_func', + 'call_user_func_array', + ); + + public function __construct($level = Logger::DEBUG, array $skipClassesPartials = array()) + { + $this->level = Logger::toMonologLevel($level); + $this->skipClassesPartials = array_merge(array('Monolog\\'), $skipClassesPartials); + } + + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // return if the level is not high enough + if ($record['level'] < $this->level) { + return $record; + } + + $trace = debug_backtrace(); + + // skip first since it's always the current method + array_shift($trace); + // the call_user_func call is also skipped + array_shift($trace); + + $i = 0; + + while ($this->isTraceClassOrSkippedFunction($trace, $i)) { + if (isset($trace[$i]['class'])) { + foreach ($this->skipClassesPartials as $part) { + if (strpos($trace[$i]['class'], $part) !== false) { + $i++; + continue 2; + } + } + } elseif (in_array($trace[$i]['function'], $this->skipFunctions)) { + $i++; + continue; + } + + break; + } + + // we should have the call source now + $record['extra'] = array_merge( + $record['extra'], + array( + 'file' => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null, + 'line' => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null, + 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null, + 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null, + ) + ); + + return $record; + } + + private function isTraceClassOrSkippedFunction(array $trace, $index) + { + if (!isset($trace[$index])) { + return false; + } + + return isset($trace[$index]['class']) || in_array($trace[$index]['function'], $this->skipFunctions); + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php new file mode 100644 index 0000000..0543e92 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Injects memory_get_peak_usage in all records + * + * @see Monolog\Processor\MemoryProcessor::__construct() for options + * @author Rob Jensen + */ +class MemoryPeakUsageProcessor extends MemoryProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $bytes = memory_get_peak_usage($this->realUsage); + $formatted = $this->formatBytes($bytes); + + $record['extra']['memory_peak_usage'] = $formatted; + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php new file mode 100644 index 0000000..eb802c0 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Some methods that are common for all memory processors + * + * @author Rob Jensen + */ +abstract class MemoryProcessor +{ + /** + * @var boolean If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported. + */ + protected $realUsage; + + /** + * @var boolean If true, then format memory size to human readable string (MB, KB, B depending on size) + */ + protected $useFormatting; + + /** + * @param boolean $realUsage Set this to true to get the real size of memory allocated from system. + * @param boolean $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size) + */ + public function __construct($realUsage = true, $useFormatting = true) + { + $this->realUsage = (boolean) $realUsage; + $this->useFormatting = (boolean) $useFormatting; + } + + /** + * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is + * + * @param int $bytes + * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as is + */ + protected function formatBytes($bytes) + { + $bytes = (int) $bytes; + + if (!$this->useFormatting) { + return $bytes; + } + + if ($bytes > 1024 * 1024) { + return round($bytes / 1024 / 1024, 2).' MB'; + } elseif ($bytes > 1024) { + return round($bytes / 1024, 2).' KB'; + } + + return $bytes . ' B'; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php new file mode 100644 index 0000000..2783d65 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Injects memory_get_usage in all records + * + * @see Monolog\Processor\MemoryProcessor::__construct() for options + * @author Rob Jensen + */ +class MemoryUsageProcessor extends MemoryProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $bytes = memory_get_usage($this->realUsage); + $formatted = $this->formatBytes($bytes); + + $record['extra']['memory_usage'] = $formatted; + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php new file mode 100644 index 0000000..9d3f559 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Adds value of getmypid into records + * + * @author Andreas Hörnicke + */ +class ProcessIdProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $record['extra']['process_id'] = getmypid(); + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php new file mode 100644 index 0000000..c2686ce --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Processes a record's message according to PSR-3 rules + * + * It replaces {foo} with the value from $context['foo'] + * + * @author Jordi Boggiano + */ +class PsrLogMessageProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + if (false === strpos($record['message'], '{')) { + return $record; + } + + $replacements = array(); + foreach ($record['context'] as $key => $val) { + if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) { + $replacements['{'.$key.'}'] = $val; + } elseif (is_object($val)) { + $replacements['{'.$key.'}'] = '[object '.get_class($val).']'; + } else { + $replacements['{'.$key.'}'] = '['.gettype($val).']'; + } + } + + $record['message'] = strtr($record['message'], $replacements); + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php new file mode 100644 index 0000000..7e2df2a --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Adds a tags array into record + * + * @author Martijn Riemers + */ +class TagProcessor +{ + private $tags; + + public function __construct(array $tags = array()) + { + $this->setTags($tags); + } + + public function addTags(array $tags = array()) + { + $this->tags = array_merge($this->tags, $tags); + } + + public function setTags(array $tags = array()) + { + $this->tags = $tags; + } + + public function __invoke(array $record) + { + $record['extra']['tags'] = $this->tags; + + return $record; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php new file mode 100644 index 0000000..812707c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Adds a unique identifier into records + * + * @author Simon Mönch + */ +class UidProcessor +{ + private $uid; + + public function __construct($length = 7) + { + if (!is_int($length) || $length > 32 || $length < 1) { + throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32'); + } + + $this->uid = substr(hash('md5', uniqid('', true)), 0, $length); + } + + public function __invoke(array $record) + { + $record['extra']['uid'] = $this->uid; + + return $record; + } + + /** + * @return string + */ + public function getUid() + { + return $this->uid; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php b/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php new file mode 100644 index 0000000..21f22a6 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +/** + * Injects url/method and remote IP of the current web request in all records + * + * @author Jordi Boggiano + */ +class WebProcessor +{ + /** + * @var array|\ArrayAccess + */ + protected $serverData; + + /** + * @var array + */ + protected $extraFields = array( + 'url' => 'REQUEST_URI', + 'ip' => 'REMOTE_ADDR', + 'http_method' => 'REQUEST_METHOD', + 'server' => 'SERVER_NAME', + 'referrer' => 'HTTP_REFERER', + ); + + /** + * @param array|\ArrayAccess $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data + * @param array|null $extraFields Extra field names to be added (all available by default) + */ + public function __construct($serverData = null, array $extraFields = null) + { + if (null === $serverData) { + $this->serverData = &$_SERVER; + } elseif (is_array($serverData) || $serverData instanceof \ArrayAccess) { + $this->serverData = $serverData; + } else { + throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.'); + } + + if (null !== $extraFields) { + foreach (array_keys($this->extraFields) as $fieldName) { + if (!in_array($fieldName, $extraFields)) { + unset($this->extraFields[$fieldName]); + } + } + } + } + + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // skip processing if for some reason request data + // is not present (CLI or wonky SAPIs) + if (!isset($this->serverData['REQUEST_URI'])) { + return $record; + } + + $record['extra'] = $this->appendExtraFields($record['extra']); + + return $record; + } + + /** + * @param string $extraName + * @param string $serverName + * @return $this + */ + public function addExtraField($extraName, $serverName) + { + $this->extraFields[$extraName] = $serverName; + + return $this; + } + + /** + * @param array $extra + * @return array + */ + private function appendExtraFields(array $extra) + { + foreach ($this->extraFields as $extraName => $serverName) { + $extra[$extraName] = isset($this->serverData[$serverName]) ? $this->serverData[$serverName] : null; + } + + if (isset($this->serverData['UNIQUE_ID'])) { + $extra['unique_id'] = $this->serverData['UNIQUE_ID']; + } + + return $extra; + } +} diff --git a/vendor/monolog/monolog/src/Monolog/Registry.php b/vendor/monolog/monolog/src/Monolog/Registry.php new file mode 100644 index 0000000..a33cb7c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Registry.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use InvalidArgumentException; + +/** + * Monolog log registry + * + * Allows to get `Logger` instances in the global scope + * via static method calls on this class. + * + * + * $application = new Monolog\Logger('application'); + * $api = new Monolog\Logger('api'); + * + * Monolog\Registry::addLogger($application); + * Monolog\Registry::addLogger($api); + * + * function testLogger() + * { + * Monolog\Registry::api()->addError('Sent to $api Logger instance'); + * Monolog\Registry::application()->addError('Sent to $application Logger instance'); + * } + * + * + * @author Tomas Tatarko + */ +class Registry +{ + /** + * List of all loggers in the registry (by named indexes) + * + * @var Logger[] + */ + private static $loggers = array(); + + /** + * Adds new logging channel to the registry + * + * @param Logger $logger Instance of the logging channel + * @param string|null $name Name of the logging channel ($logger->getName() by default) + * @param boolean $overwrite Overwrite instance in the registry if the given name already exists? + * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists + */ + public static function addLogger(Logger $logger, $name = null, $overwrite = false) + { + $name = $name ?: $logger->getName(); + + if (isset(self::$loggers[$name]) && !$overwrite) { + throw new InvalidArgumentException('Logger with the given name already exists'); + } + + self::$loggers[$name] = $logger; + } + + /** + * Checks if such logging channel exists by name or instance + * + * @param string|Logger $logger Name or logger instance + */ + public static function hasLogger($logger) + { + if ($logger instanceof Logger) { + $index = array_search($logger, self::$loggers, true); + + return false !== $index; + } else { + return isset(self::$loggers[$logger]); + } + } + + /** + * Removes instance from registry by name or instance + * + * @param string|Logger $logger Name or logger instance + */ + public static function removeLogger($logger) + { + if ($logger instanceof Logger) { + if (false !== ($idx = array_search($logger, self::$loggers, true))) { + unset(self::$loggers[$idx]); + } + } else { + unset(self::$loggers[$logger]); + } + } + + /** + * Clears the registry + */ + public static function clear() + { + self::$loggers = array(); + } + + /** + * Gets Logger instance from the registry + * + * @param string $name Name of the requested Logger instance + * @return Logger Requested instance of Logger + * @throws \InvalidArgumentException If named Logger instance is not in the registry + */ + public static function getInstance($name) + { + if (!isset(self::$loggers[$name])) { + throw new InvalidArgumentException(sprintf('Requested "%s" logger instance is not in the registry', $name)); + } + + return self::$loggers[$name]; + } + + /** + * Gets Logger instance from the registry via static method call + * + * @param string $name Name of the requested Logger instance + * @param array $arguments Arguments passed to static method call + * @return Logger Requested instance of Logger + * @throws \InvalidArgumentException If named Logger instance is not in the registry + */ + public static function __callStatic($name, $arguments) + { + return self::getInstance($name); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php new file mode 100644 index 0000000..a9a3f30 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use Monolog\Handler\TestHandler; + +class ErrorHandlerTest extends \PHPUnit_Framework_TestCase +{ + public function testHandleError() + { + $logger = new Logger('test', array($handler = new TestHandler)); + $errHandler = new ErrorHandler($logger); + + $errHandler->registerErrorHandler(array(E_USER_NOTICE => Logger::EMERGENCY), false); + trigger_error('Foo', E_USER_ERROR); + $this->assertCount(1, $handler->getRecords()); + $this->assertTrue($handler->hasErrorRecords()); + trigger_error('Foo', E_USER_NOTICE); + $this->assertCount(2, $handler->getRecords()); + $this->assertTrue($handler->hasEmergencyRecords()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php new file mode 100644 index 0000000..e7f7334 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php @@ -0,0 +1,158 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +class ChromePHPFormatterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Monolog\Formatter\ChromePHPFormatter::format + */ + public function testDefaultFormat() + { + $formatter = new ChromePHPFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('ip' => '127.0.0.1'), + 'message' => 'log', + ); + + $message = $formatter->format($record); + + $this->assertEquals( + array( + 'meh', + array( + 'message' => 'log', + 'context' => array('from' => 'logger'), + 'extra' => array('ip' => '127.0.0.1'), + ), + 'unknown', + 'error' + ), + $message + ); + } + + /** + * @covers Monolog\Formatter\ChromePHPFormatter::format + */ + public function testFormatWithFileAndLine() + { + $formatter = new ChromePHPFormatter(); + $record = array( + 'level' => Logger::CRITICAL, + 'level_name' => 'CRITICAL', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14), + 'message' => 'log', + ); + + $message = $formatter->format($record); + + $this->assertEquals( + array( + 'meh', + array( + 'message' => 'log', + 'context' => array('from' => 'logger'), + 'extra' => array('ip' => '127.0.0.1'), + ), + 'test : 14', + 'error' + ), + $message + ); + } + + /** + * @covers Monolog\Formatter\ChromePHPFormatter::format + */ + public function testFormatWithoutContext() + { + $formatter = new ChromePHPFormatter(); + $record = array( + 'level' => Logger::DEBUG, + 'level_name' => 'DEBUG', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + $message = $formatter->format($record); + + $this->assertEquals( + array( + 'meh', + 'log', + 'unknown', + 'log' + ), + $message + ); + } + + /** + * @covers Monolog\Formatter\ChromePHPFormatter::formatBatch + */ + public function testBatchFormatThrowException() + { + $formatter = new ChromePHPFormatter(); + $records = array( + array( + 'level' => Logger::INFO, + 'level_name' => 'INFO', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ), + array( + 'level' => Logger::WARNING, + 'level_name' => 'WARNING', + 'channel' => 'foo', + 'context' => array(), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log2', + ), + ); + + $this->assertEquals( + array( + array( + 'meh', + 'log', + 'unknown', + 'info' + ), + array( + 'foo', + 'log2', + 'unknown', + 'warn' + ), + ), + $formatter->formatBatch($records) + ); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php new file mode 100644 index 0000000..546e5c2 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +class ElasticaFormatterTest extends \PHPUnit_Framework_TestCase +{ + public function setUp() + { + if (!class_exists("Elastica\Document")) { + $this->markTestSkipped("ruflin/elastica not installed"); + } + } + + /** + * @covers Monolog\Formatter\ElasticaFormatter::__construct + * @covers Monolog\Formatter\ElasticaFormatter::format + * @covers Monolog\Formatter\ElasticaFormatter::getDocument + */ + public function testFormat() + { + // test log message + $msg = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + // expected values + $expected = $msg; + $expected['datetime'] = '1970-01-01T00:00:00+0000'; + $expected['context'] = array( + 'class' => '[object] (stdClass: {})', + 'foo' => 7, + 0 => 'bar', + ); + + // format log message + $formatter = new ElasticaFormatter('my_index', 'doc_type'); + $doc = $formatter->format($msg); + $this->assertInstanceOf('Elastica\Document', $doc); + + // Document parameters + $params = $doc->getParams(); + $this->assertEquals('my_index', $params['_index']); + $this->assertEquals('doc_type', $params['_type']); + + // Document data values + $data = $doc->getData(); + foreach (array_keys($expected) as $key) { + $this->assertEquals($expected[$key], $data[$key]); + } + } + + /** + * @covers Monolog\Formatter\ElasticaFormatter::getIndex + * @covers Monolog\Formatter\ElasticaFormatter::getType + */ + public function testGetters() + { + $formatter = new ElasticaFormatter('my_index', 'doc_type'); + $this->assertEquals('my_index', $formatter->getIndex()); + $this->assertEquals('doc_type', $formatter->getType()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php new file mode 100644 index 0000000..1b2fd97 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; +use Monolog\TestCase; + +class FlowdockFormatterTest extends TestCase +{ + /** + * @covers Monolog\Formatter\FlowdockFormatter::format + */ + public function testFormat() + { + $formatter = new FlowdockFormatter('test_source', 'source@test.com'); + $record = $this->getRecord(); + + $expected = array( + 'source' => 'test_source', + 'from_address' => 'source@test.com', + 'subject' => 'in test_source: WARNING - test', + 'content' => 'test', + 'tags' => array('#logs', '#warning', '#test'), + 'project' => 'test_source', + ); + $formatted = $formatter->format($record); + + $this->assertEquals($expected, $formatted['flowdock']); + } + + /** + * @ covers Monolog\Formatter\FlowdockFormatter::formatBatch + */ + public function testFormatBatch() + { + $formatter = new FlowdockFormatter('test_source', 'source@test.com'); + $records = array( + $this->getRecord(Logger::WARNING), + $this->getRecord(Logger::DEBUG), + ); + $formatted = $formatter->formatBatch($records); + + $this->assertArrayHasKey('flowdock', $formatted[0]); + $this->assertArrayHasKey('flowdock', $formatted[1]); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php new file mode 100644 index 0000000..6ac1485 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php @@ -0,0 +1,204 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase +{ + public function setUp() + { + if (!class_exists('\Gelf\Message')) { + $this->markTestSkipped("graylog2/gelf-php or mlehner/gelf-php is not installed"); + } + } + + /** + * @covers Monolog\Formatter\GelfMessageFormatter::format + */ + public function testDefaultFormatter() + { + $formatter = new GelfMessageFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + $message = $formatter->format($record); + + $this->assertInstanceOf('Gelf\Message', $message); + $this->assertEquals(0, $message->getTimestamp()); + $this->assertEquals('log', $message->getShortMessage()); + $this->assertEquals('meh', $message->getFacility()); + $this->assertEquals(null, $message->getLine()); + $this->assertEquals(null, $message->getFile()); + $this->assertEquals($this->isLegacy() ? 3 : 'error', $message->getLevel()); + $this->assertNotEmpty($message->getHost()); + + $formatter = new GelfMessageFormatter('mysystem'); + + $message = $formatter->format($record); + + $this->assertInstanceOf('Gelf\Message', $message); + $this->assertEquals('mysystem', $message->getHost()); + } + + /** + * @covers Monolog\Formatter\GelfMessageFormatter::format + */ + public function testFormatWithFileAndLine() + { + $formatter = new GelfMessageFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('file' => 'test', 'line' => 14), + 'message' => 'log', + ); + + $message = $formatter->format($record); + + $this->assertInstanceOf('Gelf\Message', $message); + $this->assertEquals('test', $message->getFile()); + $this->assertEquals(14, $message->getLine()); + } + + /** + * @covers Monolog\Formatter\GelfMessageFormatter::format + * @expectedException InvalidArgumentException + */ + public function testFormatInvalidFails() + { + $formatter = new GelfMessageFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + ); + + $formatter->format($record); + } + + /** + * @covers Monolog\Formatter\GelfMessageFormatter::format + */ + public function testFormatWithContext() + { + $formatter = new GelfMessageFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('key' => 'pair'), + 'message' => 'log' + ); + + $message = $formatter->format($record); + + $this->assertInstanceOf('Gelf\Message', $message); + + $message_array = $message->toArray(); + + $this->assertArrayHasKey('_ctxt_from', $message_array); + $this->assertEquals('logger', $message_array['_ctxt_from']); + + // Test with extraPrefix + $formatter = new GelfMessageFormatter(null, null, 'CTX'); + $message = $formatter->format($record); + + $this->assertInstanceOf('Gelf\Message', $message); + + $message_array = $message->toArray(); + + $this->assertArrayHasKey('_CTXfrom', $message_array); + $this->assertEquals('logger', $message_array['_CTXfrom']); + } + + /** + * @covers Monolog\Formatter\GelfMessageFormatter::format + */ + public function testFormatWithContextContainingException() + { + $formatter = new GelfMessageFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger', 'exception' => array( + 'class' => '\Exception', + 'file' => '/some/file/in/dir.php:56', + 'trace' => array('/some/file/1.php:23', '/some/file/2.php:3') + )), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log' + ); + + $message = $formatter->format($record); + + $this->assertInstanceOf('Gelf\Message', $message); + + $this->assertEquals("/some/file/in/dir.php", $message->getFile()); + $this->assertEquals("56", $message->getLine()); + } + + /** + * @covers Monolog\Formatter\GelfMessageFormatter::format + */ + public function testFormatWithExtra() + { + $formatter = new GelfMessageFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('key' => 'pair'), + 'message' => 'log' + ); + + $message = $formatter->format($record); + + $this->assertInstanceOf('Gelf\Message', $message); + + $message_array = $message->toArray(); + + $this->assertArrayHasKey('_key', $message_array); + $this->assertEquals('pair', $message_array['_key']); + + // Test with extraPrefix + $formatter = new GelfMessageFormatter(null, 'EXT'); + $message = $formatter->format($record); + + $this->assertInstanceOf('Gelf\Message', $message); + + $message_array = $message->toArray(); + + $this->assertArrayHasKey('_EXTkey', $message_array); + $this->assertEquals('pair', $message_array['_EXTkey']); + } + + private function isLegacy() + { + return interface_exists('\Gelf\IMessagePublisher'); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php new file mode 100644 index 0000000..69e2007 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; +use Monolog\TestCase; + +class JsonFormatterTest extends TestCase +{ + /** + * @covers Monolog\Formatter\JsonFormatter::__construct + * @covers Monolog\Formatter\JsonFormatter::getBatchMode + * @covers Monolog\Formatter\JsonFormatter::isAppendingNewlines + */ + public function testConstruct() + { + $formatter = new JsonFormatter(); + $this->assertEquals(JsonFormatter::BATCH_MODE_JSON, $formatter->getBatchMode()); + $this->assertEquals(true, $formatter->isAppendingNewlines()); + $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES, false); + $this->assertEquals(JsonFormatter::BATCH_MODE_NEWLINES, $formatter->getBatchMode()); + $this->assertEquals(false, $formatter->isAppendingNewlines()); + } + + /** + * @covers Monolog\Formatter\JsonFormatter::format + */ + public function testFormat() + { + $formatter = new JsonFormatter(); + $record = $this->getRecord(); + $this->assertEquals(json_encode($record)."\n", $formatter->format($record)); + + $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); + $record = $this->getRecord(); + $this->assertEquals(json_encode($record), $formatter->format($record)); + } + + /** + * @covers Monolog\Formatter\JsonFormatter::formatBatch + * @covers Monolog\Formatter\JsonFormatter::formatBatchJson + */ + public function testFormatBatch() + { + $formatter = new JsonFormatter(); + $records = array( + $this->getRecord(Logger::WARNING), + $this->getRecord(Logger::DEBUG), + ); + $this->assertEquals(json_encode($records), $formatter->formatBatch($records)); + } + + /** + * @covers Monolog\Formatter\JsonFormatter::formatBatch + * @covers Monolog\Formatter\JsonFormatter::formatBatchNewlines + */ + public function testFormatBatchNewlines() + { + $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES); + $records = $expected = array( + $this->getRecord(Logger::WARNING), + $this->getRecord(Logger::DEBUG), + ); + array_walk($expected, function (&$value, $key) { + $value = json_encode($value); + }); + $this->assertEquals(implode("\n", $expected), $formatter->formatBatch($records)); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php new file mode 100644 index 0000000..875bd57 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php @@ -0,0 +1,208 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * @covers Monolog\Formatter\LineFormatter + */ +class LineFormatterTest extends \PHPUnit_Framework_TestCase +{ + public function testDefFormatWithString() + { + $formatter = new LineFormatter(null, 'Y-m-d'); + $message = $formatter->format(array( + 'level_name' => 'WARNING', + 'channel' => 'log', + 'context' => array(), + 'message' => 'foo', + 'datetime' => new \DateTime, + 'extra' => array(), + )); + $this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message); + } + + public function testDefFormatWithArrayContext() + { + $formatter = new LineFormatter(null, 'Y-m-d'); + $message = $formatter->format(array( + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'message' => 'foo', + 'datetime' => new \DateTime, + 'extra' => array(), + 'context' => array( + 'foo' => 'bar', + 'baz' => 'qux', + 'bool' => false, + 'null' => null, + ) + )); + $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foo {"foo":"bar","baz":"qux","bool":false,"null":null} []'."\n", $message); + } + + public function testDefFormatExtras() + { + $formatter = new LineFormatter(null, 'Y-m-d'); + $message = $formatter->format(array( + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime, + 'extra' => array('ip' => '127.0.0.1'), + 'message' => 'log', + )); + $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] {"ip":"127.0.0.1"}'."\n", $message); + } + + public function testFormatExtras() + { + $formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra.file% %extra%\n", 'Y-m-d'); + $message = $formatter->format(array( + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime, + 'extra' => array('ip' => '127.0.0.1', 'file' => 'test'), + 'message' => 'log', + )); + $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] test {"ip":"127.0.0.1"}'."\n", $message); + } + + public function testContextAndExtraOptionallyNotShownIfEmpty() + { + $formatter = new LineFormatter(null, 'Y-m-d', false, true); + $message = $formatter->format(array( + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime, + 'extra' => array(), + 'message' => 'log', + )); + $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log '."\n", $message); + } + + public function testDefFormatWithObject() + { + $formatter = new LineFormatter(null, 'Y-m-d'); + $message = $formatter->format(array( + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime, + 'extra' => array('foo' => new TestFoo, 'bar' => new TestBar, 'baz' => array(), 'res' => fopen('php://memory', 'rb')), + 'message' => 'foobar', + )); + + $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\\\Formatter\\\\TestFoo: {\\"foo\\":\\"foo\\"})","bar":"[object] (Monolog\\\\Formatter\\\\TestBar: bar)","baz":[],"res":"[resource] (stream)"}'."\n", $message); + } + + public function testDefFormatWithException() + { + $formatter = new LineFormatter(null, 'Y-m-d'); + $message = $formatter->format(array( + 'level_name' => 'CRITICAL', + 'channel' => 'core', + 'context' => array('exception' => new \RuntimeException('Foo')), + 'datetime' => new \DateTime, + 'extra' => array(), + 'message' => 'foobar', + )); + + $path = str_replace('\\/', '/', json_encode(__FILE__)); + + $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).')"} []'."\n", $message); + } + + public function testDefFormatWithPreviousException() + { + $formatter = new LineFormatter(null, 'Y-m-d'); + $previous = new \LogicException('Wut?'); + $message = $formatter->format(array( + 'level_name' => 'CRITICAL', + 'channel' => 'core', + 'context' => array('exception' => new \RuntimeException('Foo', 0, $previous)), + 'datetime' => new \DateTime, + 'extra' => array(), + 'message' => 'foobar', + )); + + $path = str_replace('\\/', '/', json_encode(__FILE__)); + + $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).', LogicException(code: 0): Wut? at '.substr($path, 1, -1).':'.(__LINE__ - 12).')"} []'."\n", $message); + } + + public function testBatchFormat() + { + $formatter = new LineFormatter(null, 'Y-m-d'); + $message = $formatter->formatBatch(array( + array( + 'level_name' => 'CRITICAL', + 'channel' => 'test', + 'message' => 'bar', + 'context' => array(), + 'datetime' => new \DateTime, + 'extra' => array(), + ), + array( + 'level_name' => 'WARNING', + 'channel' => 'log', + 'message' => 'foo', + 'context' => array(), + 'datetime' => new \DateTime, + 'extra' => array(), + ), + )); + $this->assertEquals('['.date('Y-m-d').'] test.CRITICAL: bar [] []'."\n".'['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message); + } + + public function testFormatShouldStripInlineLineBreaks() + { + $formatter = new LineFormatter(null, 'Y-m-d'); + $message = $formatter->format( + array( + 'message' => "foo\nbar", + 'context' => array(), + 'extra' => array(), + ) + ); + + $this->assertRegExp('/foo bar/', $message); + } + + public function testFormatShouldNotStripInlineLineBreaksWhenFlagIsSet() + { + $formatter = new LineFormatter(null, 'Y-m-d', true); + $message = $formatter->format( + array( + 'message' => "foo\nbar", + 'context' => array(), + 'extra' => array(), + ) + ); + + $this->assertRegExp('/foo\nbar/', $message); + } +} + +class TestFoo +{ + public $foo = 'foo'; +} + +class TestBar +{ + public function __toString() + { + return 'bar'; + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php new file mode 100644 index 0000000..6d59b3f --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\TestCase; + +class LogglyFormatterTest extends TestCase +{ + /** + * @covers Monolog\Formatter\LogglyFormatter::__construct + */ + public function testConstruct() + { + $formatter = new LogglyFormatter(); + $this->assertEquals(LogglyFormatter::BATCH_MODE_NEWLINES, $formatter->getBatchMode()); + $formatter = new LogglyFormatter(LogglyFormatter::BATCH_MODE_JSON); + $this->assertEquals(LogglyFormatter::BATCH_MODE_JSON, $formatter->getBatchMode()); + } + + /** + * @covers Monolog\Formatter\LogglyFormatter::format + */ + public function testFormat() + { + $formatter = new LogglyFormatter(); + $record = $this->getRecord(); + $formatted_decoded = json_decode($formatter->format($record), true); + $this->assertArrayHasKey("timestamp", $formatted_decoded); + $this->assertEquals(new \DateTime($formatted_decoded["timestamp"]), $record["datetime"]); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php new file mode 100644 index 0000000..de4a3c2 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php @@ -0,0 +1,289 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +class LogstashFormatterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Monolog\Formatter\LogstashFormatter::format + */ + public function testDefaultFormatter() + { + $formatter = new LogstashFormatter('test', 'hostname'); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + $message = json_decode($formatter->format($record), true); + + $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']); + $this->assertEquals('log', $message['@message']); + $this->assertEquals('meh', $message['@fields']['channel']); + $this->assertContains('meh', $message['@tags']); + $this->assertEquals(Logger::ERROR, $message['@fields']['level']); + $this->assertEquals('test', $message['@type']); + $this->assertEquals('hostname', $message['@source']); + + $formatter = new LogstashFormatter('mysystem'); + + $message = json_decode($formatter->format($record), true); + + $this->assertEquals('mysystem', $message['@type']); + } + + /** + * @covers Monolog\Formatter\LogstashFormatter::format + */ + public function testFormatWithFileAndLine() + { + $formatter = new LogstashFormatter('test'); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('file' => 'test', 'line' => 14), + 'message' => 'log', + ); + + $message = json_decode($formatter->format($record), true); + + $this->assertEquals('test', $message['@fields']['file']); + $this->assertEquals(14, $message['@fields']['line']); + } + + /** + * @covers Monolog\Formatter\LogstashFormatter::format + */ + public function testFormatWithContext() + { + $formatter = new LogstashFormatter('test'); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('key' => 'pair'), + 'message' => 'log' + ); + + $message = json_decode($formatter->format($record), true); + + $message_array = $message['@fields']; + + $this->assertArrayHasKey('ctxt_from', $message_array); + $this->assertEquals('logger', $message_array['ctxt_from']); + + // Test with extraPrefix + $formatter = new LogstashFormatter('test', null, null, 'CTX'); + $message = json_decode($formatter->format($record), true); + + $message_array = $message['@fields']; + + $this->assertArrayHasKey('CTXfrom', $message_array); + $this->assertEquals('logger', $message_array['CTXfrom']); + } + + /** + * @covers Monolog\Formatter\LogstashFormatter::format + */ + public function testFormatWithExtra() + { + $formatter = new LogstashFormatter('test'); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('key' => 'pair'), + 'message' => 'log' + ); + + $message = json_decode($formatter->format($record), true); + + $message_array = $message['@fields']; + + $this->assertArrayHasKey('key', $message_array); + $this->assertEquals('pair', $message_array['key']); + + // Test with extraPrefix + $formatter = new LogstashFormatter('test', null, 'EXT'); + $message = json_decode($formatter->format($record), true); + + $message_array = $message['@fields']; + + $this->assertArrayHasKey('EXTkey', $message_array); + $this->assertEquals('pair', $message_array['EXTkey']); + } + + public function testFormatWithApplicationName() + { + $formatter = new LogstashFormatter('app', 'test'); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('key' => 'pair'), + 'message' => 'log' + ); + + $message = json_decode($formatter->format($record), true); + + $this->assertArrayHasKey('@type', $message); + $this->assertEquals('app', $message['@type']); + } + + /** + * @covers Monolog\Formatter\LogstashFormatter::format + */ + public function testDefaultFormatterV1() + { + $formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_', LogstashFormatter::V1); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + $message = json_decode($formatter->format($record), true); + + $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']); + $this->assertEquals("1", $message['@version']); + $this->assertEquals('log', $message['message']); + $this->assertEquals('meh', $message['channel']); + $this->assertEquals('ERROR', $message['level']); + $this->assertEquals('test', $message['type']); + $this->assertEquals('hostname', $message['host']); + + $formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_', LogstashFormatter::V1); + + $message = json_decode($formatter->format($record), true); + + $this->assertEquals('mysystem', $message['type']); + } + + /** + * @covers Monolog\Formatter\LogstashFormatter::format + */ + public function testFormatWithFileAndLineV1() + { + $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('file' => 'test', 'line' => 14), + 'message' => 'log', + ); + + $message = json_decode($formatter->format($record), true); + + $this->assertEquals('test', $message['file']); + $this->assertEquals(14, $message['line']); + } + + /** + * @covers Monolog\Formatter\LogstashFormatter::format + */ + public function testFormatWithContextV1() + { + $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('key' => 'pair'), + 'message' => 'log' + ); + + $message = json_decode($formatter->format($record), true); + + $this->assertArrayHasKey('ctxt_from', $message); + $this->assertEquals('logger', $message['ctxt_from']); + + // Test with extraPrefix + $formatter = new LogstashFormatter('test', null, null, 'CTX', LogstashFormatter::V1); + $message = json_decode($formatter->format($record), true); + + $this->assertArrayHasKey('CTXfrom', $message); + $this->assertEquals('logger', $message['CTXfrom']); + } + + /** + * @covers Monolog\Formatter\LogstashFormatter::format + */ + public function testFormatWithExtraV1() + { + $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('key' => 'pair'), + 'message' => 'log' + ); + + $message = json_decode($formatter->format($record), true); + + $this->assertArrayHasKey('key', $message); + $this->assertEquals('pair', $message['key']); + + // Test with extraPrefix + $formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_', LogstashFormatter::V1); + $message = json_decode($formatter->format($record), true); + + $this->assertArrayHasKey('EXTkey', $message); + $this->assertEquals('pair', $message['EXTkey']); + } + + public function testFormatWithApplicationNameV1() + { + $formatter = new LogstashFormatter('app', 'test', null, 'ctxt_', LogstashFormatter::V1); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('key' => 'pair'), + 'message' => 'log' + ); + + $message = json_decode($formatter->format($record), true); + + $this->assertArrayHasKey('type', $message); + $this->assertEquals('app', $message['type']); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php new file mode 100644 index 0000000..1554ef4 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php @@ -0,0 +1,253 @@ + + */ +class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase +{ + public function setUp() + { + if (!class_exists('MongoDate')) { + $this->markTestSkipped('mongo extension not installed'); + } + } + + public function constructArgumentProvider() + { + return array( + array(1, true, 1, true), + array(0, false, 0, false), + ); + } + + /** + * @param $traceDepth + * @param $traceAsString + * @param $expectedTraceDepth + * @param $expectedTraceAsString + * + * @dataProvider constructArgumentProvider + */ + public function testConstruct($traceDepth, $traceAsString, $expectedTraceDepth, $expectedTraceAsString) + { + $formatter = new MongoDBFormatter($traceDepth, $traceAsString); + + $reflTrace = new \ReflectionProperty($formatter, 'exceptionTraceAsString'); + $reflTrace->setAccessible(true); + $this->assertEquals($expectedTraceAsString, $reflTrace->getValue($formatter)); + + $reflDepth = new\ReflectionProperty($formatter, 'maxNestingLevel'); + $reflDepth->setAccessible(true); + $this->assertEquals($expectedTraceDepth, $reflDepth->getValue($formatter)); + } + + public function testSimpleFormat() + { + $record = array( + 'message' => 'some log message', + 'context' => array(), + 'level' => Logger::WARNING, + 'level_name' => Logger::getLevelName(Logger::WARNING), + 'channel' => 'test', + 'datetime' => new \DateTime('2014-02-01 00:00:00'), + 'extra' => array(), + ); + + $formatter = new MongoDBFormatter(); + $formattedRecord = $formatter->format($record); + + $this->assertCount(7, $formattedRecord); + $this->assertEquals('some log message', $formattedRecord['message']); + $this->assertEquals(array(), $formattedRecord['context']); + $this->assertEquals(Logger::WARNING, $formattedRecord['level']); + $this->assertEquals(Logger::getLevelName(Logger::WARNING), $formattedRecord['level_name']); + $this->assertEquals('test', $formattedRecord['channel']); + $this->assertInstanceOf('\MongoDate', $formattedRecord['datetime']); + $this->assertEquals('0.00000000 1391212800', $formattedRecord['datetime']->__toString()); + $this->assertEquals(array(), $formattedRecord['extra']); + } + + public function testRecursiveFormat() + { + $someObject = new \stdClass(); + $someObject->foo = 'something'; + $someObject->bar = 'stuff'; + + $record = array( + 'message' => 'some log message', + 'context' => array( + 'stuff' => new \DateTime('2014-02-01 02:31:33'), + 'some_object' => $someObject, + 'context_string' => 'some string', + 'context_int' => 123456, + 'except' => new \Exception('exception message', 987), + ), + 'level' => Logger::WARNING, + 'level_name' => Logger::getLevelName(Logger::WARNING), + 'channel' => 'test', + 'datetime' => new \DateTime('2014-02-01 00:00:00'), + 'extra' => array(), + ); + + $formatter = new MongoDBFormatter(); + $formattedRecord = $formatter->format($record); + + $this->assertCount(5, $formattedRecord['context']); + $this->assertInstanceOf('\MongoDate', $formattedRecord['context']['stuff']); + $this->assertEquals('0.00000000 1391221893', $formattedRecord['context']['stuff']->__toString()); + $this->assertEquals( + array( + 'foo' => 'something', + 'bar' => 'stuff', + 'class' => 'stdClass', + ), + $formattedRecord['context']['some_object'] + ); + $this->assertEquals('some string', $formattedRecord['context']['context_string']); + $this->assertEquals(123456, $formattedRecord['context']['context_int']); + + $this->assertCount(5, $formattedRecord['context']['except']); + $this->assertEquals('exception message', $formattedRecord['context']['except']['message']); + $this->assertEquals(987, $formattedRecord['context']['except']['code']); + $this->assertInternalType('string', $formattedRecord['context']['except']['file']); + $this->assertInternalType('integer', $formattedRecord['context']['except']['code']); + $this->assertInternalType('string', $formattedRecord['context']['except']['trace']); + $this->assertEquals('Exception', $formattedRecord['context']['except']['class']); + } + + public function testFormatDepthArray() + { + $record = array( + 'message' => 'some log message', + 'context' => array( + 'nest2' => array( + 'property' => 'anything', + 'nest3' => array( + 'nest4' => 'value', + 'property' => 'nothing' + ) + ) + ), + 'level' => Logger::WARNING, + 'level_name' => Logger::getLevelName(Logger::WARNING), + 'channel' => 'test', + 'datetime' => new \DateTime('2014-02-01 00:00:00'), + 'extra' => array(), + ); + + $formatter = new MongoDBFormatter(2); + $formattedResult = $formatter->format($record); + + $this->assertEquals( + array( + 'nest2' => array( + 'property' => 'anything', + 'nest3' => '[...]', + ) + ), + $formattedResult['context'] + ); + } + + public function testFormatDepthArrayInfiniteNesting() + { + $record = array( + 'message' => 'some log message', + 'context' => array( + 'nest2' => array( + 'property' => 'something', + 'nest3' => array( + 'property' => 'anything', + 'nest4' => array( + 'property' => 'nothing', + ), + ) + ) + ), + 'level' => Logger::WARNING, + 'level_name' => Logger::getLevelName(Logger::WARNING), + 'channel' => 'test', + 'datetime' => new \DateTime('2014-02-01 00:00:00'), + 'extra' => array(), + ); + + $formatter = new MongoDBFormatter(0); + $formattedResult = $formatter->format($record); + + $this->assertEquals( + array( + 'nest2' => array( + 'property' => 'something', + 'nest3' => array( + 'property' => 'anything', + 'nest4' => array( + 'property' => 'nothing', + ) + ), + ) + ), + $formattedResult['context'] + ); + } + + public function testFormatDepthObjects() + { + $someObject = new \stdClass(); + $someObject->property = 'anything'; + $someObject->nest3 = new \stdClass(); + $someObject->nest3->property = 'nothing'; + $someObject->nest3->nest4 = 'invisible'; + + $record = array( + 'message' => 'some log message', + 'context' => array( + 'nest2' => $someObject + ), + 'level' => Logger::WARNING, + 'level_name' => Logger::getLevelName(Logger::WARNING), + 'channel' => 'test', + 'datetime' => new \DateTime('2014-02-01 00:00:00'), + 'extra' => array(), + ); + + $formatter = new MongoDBFormatter(2, true); + $formattedResult = $formatter->format($record); + + $this->assertEquals( + array( + 'nest2' => array( + 'property' => 'anything', + 'nest3' => '[...]', + 'class' => 'stdClass', + ), + ), + $formattedResult['context'] + ); + } + + public function testFormatDepthException() + { + $record = array( + 'message' => 'some log message', + 'context' => array( + 'nest2' => new \Exception('exception message', 987), + ), + 'level' => Logger::WARNING, + 'level_name' => Logger::getLevelName(Logger::WARNING), + 'channel' => 'test', + 'datetime' => new \DateTime('2014-02-01 00:00:00'), + 'extra' => array(), + ); + + $formatter = new MongoDBFormatter(2, false); + $formattedRecord = $formatter->format($record); + + $this->assertEquals('exception message', $formattedRecord['context']['nest2']['message']); + $this->assertEquals(987, $formattedRecord['context']['nest2']['code']); + $this->assertEquals('[...]', $formattedRecord['context']['nest2']['trace']); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php new file mode 100644 index 0000000..c484dfe --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -0,0 +1,270 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +/** + * @covers Monolog\Formatter\NormalizerFormatter + */ +class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase +{ + public function testFormat() + { + $formatter = new NormalizerFormatter('Y-m-d'); + $formatted = $formatter->format(array( + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'message' => 'foo', + 'datetime' => new \DateTime, + 'extra' => array('foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => array(), 'res' => fopen('php://memory', 'rb')), + 'context' => array( + 'foo' => 'bar', + 'baz' => 'qux', + 'inf' => INF, + '-inf' => -INF, + 'nan' => acos(4), + ), + )); + + $this->assertEquals(array( + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'message' => 'foo', + 'datetime' => date('Y-m-d'), + 'extra' => array( + 'foo' => '[object] (Monolog\\Formatter\\TestFooNorm: {"foo":"foo"})', + 'bar' => '[object] (Monolog\\Formatter\\TestBarNorm: bar)', + 'baz' => array(), + 'res' => '[resource] (stream)', + ), + 'context' => array( + 'foo' => 'bar', + 'baz' => 'qux', + 'inf' => 'INF', + '-inf' => '-INF', + 'nan' => 'NaN', + ) + ), $formatted); + } + + public function testFormatExceptions() + { + $formatter = new NormalizerFormatter('Y-m-d'); + $e = new \LogicException('bar'); + $e2 = new \RuntimeException('foo', 0, $e); + $formatted = $formatter->format(array( + 'exception' => $e2, + )); + + $this->assertGreaterThan(5, count($formatted['exception']['trace'])); + $this->assertTrue(isset($formatted['exception']['previous'])); + unset($formatted['exception']['trace'], $formatted['exception']['previous']); + + $this->assertEquals(array( + 'exception' => array( + 'class' => get_class($e2), + 'message' => $e2->getMessage(), + 'code' => $e2->getCode(), + 'file' => $e2->getFile().':'.$e2->getLine(), + ) + ), $formatted); + } + + public function testBatchFormat() + { + $formatter = new NormalizerFormatter('Y-m-d'); + $formatted = $formatter->formatBatch(array( + array( + 'level_name' => 'CRITICAL', + 'channel' => 'test', + 'message' => 'bar', + 'context' => array(), + 'datetime' => new \DateTime, + 'extra' => array(), + ), + array( + 'level_name' => 'WARNING', + 'channel' => 'log', + 'message' => 'foo', + 'context' => array(), + 'datetime' => new \DateTime, + 'extra' => array(), + ), + )); + $this->assertEquals(array( + array( + 'level_name' => 'CRITICAL', + 'channel' => 'test', + 'message' => 'bar', + 'context' => array(), + 'datetime' => date('Y-m-d'), + 'extra' => array(), + ), + array( + 'level_name' => 'WARNING', + 'channel' => 'log', + 'message' => 'foo', + 'context' => array(), + 'datetime' => date('Y-m-d'), + 'extra' => array(), + ), + ), $formatted); + } + + /** + * Test issue #137 + */ + public function testIgnoresRecursiveObjectReferences() + { + // set up the recursion + $foo = new \stdClass(); + $bar = new \stdClass(); + + $foo->bar = $bar; + $bar->foo = $foo; + + // set an error handler to assert that the error is not raised anymore + $that = $this; + set_error_handler(function ($level, $message, $file, $line, $context) use ($that) { + if (error_reporting() & $level) { + restore_error_handler(); + $that->fail("$message should not be raised"); + } + }); + + $formatter = new NormalizerFormatter(); + $reflMethod = new \ReflectionMethod($formatter, 'toJson'); + $reflMethod->setAccessible(true); + $res = $reflMethod->invoke($formatter, array($foo, $bar), true); + + restore_error_handler(); + + $this->assertEquals(@json_encode(array($foo, $bar)), $res); + } + + public function testIgnoresInvalidTypes() + { + // set up the recursion + $resource = fopen(__FILE__, 'r'); + + // set an error handler to assert that the error is not raised anymore + $that = $this; + set_error_handler(function ($level, $message, $file, $line, $context) use ($that) { + if (error_reporting() & $level) { + restore_error_handler(); + $that->fail("$message should not be raised"); + } + }); + + $formatter = new NormalizerFormatter(); + $reflMethod = new \ReflectionMethod($formatter, 'toJson'); + $reflMethod->setAccessible(true); + $res = $reflMethod->invoke($formatter, array($resource), true); + + restore_error_handler(); + + $this->assertEquals(@json_encode(array($resource)), $res); + } + + /** + * @expectedException RuntimeException + */ + public function testThrowsOnInvalidEncoding() + { + $formatter = new NormalizerFormatter(); + $reflMethod = new \ReflectionMethod($formatter, 'toJson'); + $reflMethod->setAccessible(true); + + // send an invalid unicode sequence + $res = $reflMethod->invoke($formatter, array('message' => "\xB1\x31")); + if (PHP_VERSION_ID < 50500 && $res === '{"message":null}') { + throw new \RuntimeException('PHP 5.3/5.4 throw a warning and null the value instead of returning false entirely'); + } + } + + public function testExceptionTraceWithArgs() + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('Not supported in HHVM since it detects errors differently'); + } + + // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered + // and no file or line are included in the trace because it's treated as internal function + set_error_handler(function ($errno, $errstr, $errfile, $errline) { + throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); + }); + + try { + // This will contain $resource and $wrappedResource as arguments in the trace item + $resource = fopen('php://memory', 'rw+'); + fwrite($resource, 'test_resource'); + $wrappedResource = new TestFooNorm; + $wrappedResource->foo = $resource; + // Just do something stupid with a resource/wrapped resource as argument + array_keys($wrappedResource); + } catch (\Exception $e) { + restore_error_handler(); + } + + $formatter = new NormalizerFormatter(); + $record = array('context' => array('exception' => $e)); + $result = $formatter->format($record); + + $this->assertRegExp( + '%"resource":"\[resource\] \(stream\)"%', + $result['context']['exception']['trace'][0] + ); + + if (version_compare(PHP_VERSION, '5.5.0', '>=')) { + $pattern = '%"wrappedResource":"\[object\] \(Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm: \)"%'; + } else { + $pattern = '%\\\\"foo\\\\":null%'; + } + + // Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4 + $this->assertRegExp( + $pattern, + $result['context']['exception']['trace'][0] + ); + } +} + +class TestFooNorm +{ + public $foo = 'foo'; +} + +class TestBarNorm +{ + public function __toString() + { + return 'bar'; + } +} + +class TestStreamFoo +{ + public $foo; + public $resource; + + public function __construct($resource) + { + $this->resource = $resource; + $this->foo = 'BAR'; + } + + public function __toString() + { + fseek($this->resource, 0); + + return $this->foo . ' - ' . (string) stream_get_contents($this->resource); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php new file mode 100644 index 0000000..2a35446 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php @@ -0,0 +1,100 @@ +formatter = new ScalarFormatter(); + } + + public function buildTrace(\Exception $e) + { + $data = array(); + $trace = $e->getTrace(); + foreach ($trace as $frame) { + if (isset($frame['file'])) { + $data[] = $frame['file'].':'.$frame['line']; + } else { + $data[] = json_encode($frame); + } + } + + return $data; + } + + public function encodeJson($data) + { + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + return json_encode($data); + } + + public function testFormat() + { + $exception = new \Exception('foo'); + $formatted = $this->formatter->format(array( + 'foo' => 'string', + 'bar' => 1, + 'baz' => false, + 'bam' => array(1, 2, 3), + 'bat' => array('foo' => 'bar'), + 'bap' => \DateTime::createFromFormat(\DateTime::ISO8601, '1970-01-01T00:00:00+0000'), + 'ban' => $exception + )); + + $this->assertSame(array( + 'foo' => 'string', + 'bar' => 1, + 'baz' => false, + 'bam' => $this->encodeJson(array(1, 2, 3)), + 'bat' => $this->encodeJson(array('foo' => 'bar')), + 'bap' => '1970-01-01 00:00:00', + 'ban' => $this->encodeJson(array( + 'class' => get_class($exception), + 'message' => $exception->getMessage(), + 'code' => $exception->getCode(), + 'file' => $exception->getFile() . ':' . $exception->getLine(), + 'trace' => $this->buildTrace($exception) + )) + ), $formatted); + } + + public function testFormatWithErrorContext() + { + $context = array('file' => 'foo', 'line' => 1); + $formatted = $this->formatter->format(array( + 'context' => $context + )); + + $this->assertSame(array( + 'context' => $this->encodeJson($context) + ), $formatted); + } + + public function testFormatWithExceptionContext() + { + $exception = new \Exception('foo'); + $formatted = $this->formatter->format(array( + 'context' => array( + 'exception' => $exception + ) + )); + + $this->assertSame(array( + 'context' => $this->encodeJson(array( + 'exception' => array( + 'class' => get_class($exception), + 'message' => $exception->getMessage(), + 'code' => $exception->getCode(), + 'file' => $exception->getFile() . ':' . $exception->getLine(), + 'trace' => $this->buildTrace($exception) + ) + )) + ), $formatted); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php b/vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php new file mode 100644 index 0000000..52f15a3 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +class WildfireFormatterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Monolog\Formatter\WildfireFormatter::format + */ + public function testDefaultFormat() + { + $wildfire = new WildfireFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('ip' => '127.0.0.1'), + 'message' => 'log', + ); + + $message = $wildfire->format($record); + + $this->assertEquals( + '125|[{"Type":"ERROR","File":"","Line":"","Label":"meh"},' + .'{"message":"log","context":{"from":"logger"},"extra":{"ip":"127.0.0.1"}}]|', + $message + ); + } + + /** + * @covers Monolog\Formatter\WildfireFormatter::format + */ + public function testFormatWithFileAndLine() + { + $wildfire = new WildfireFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('from' => 'logger'), + 'datetime' => new \DateTime("@0"), + 'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14), + 'message' => 'log', + ); + + $message = $wildfire->format($record); + + $this->assertEquals( + '129|[{"Type":"ERROR","File":"test","Line":14,"Label":"meh"},' + .'{"message":"log","context":{"from":"logger"},"extra":{"ip":"127.0.0.1"}}]|', + $message + ); + } + + /** + * @covers Monolog\Formatter\WildfireFormatter::format + */ + public function testFormatWithoutContext() + { + $wildfire = new WildfireFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + $message = $wildfire->format($record); + + $this->assertEquals( + '58|[{"Type":"ERROR","File":"","Line":"","Label":"meh"},"log"]|', + $message + ); + } + + /** + * @covers Monolog\Formatter\WildfireFormatter::formatBatch + * @expectedException BadMethodCallException + */ + public function testBatchFormatThrowException() + { + $wildfire = new WildfireFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array(), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + $wildfire->formatBatch(array($record)); + } + + /** + * @covers Monolog\Formatter\WildfireFormatter::format + */ + public function testTableFormat() + { + $wildfire = new WildfireFormatter(); + $record = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'table-channel', + 'context' => array( + WildfireFormatter::TABLE => array( + array('col1', 'col2', 'col3'), + array('val1', 'val2', 'val3'), + array('foo1', 'foo2', 'foo3'), + array('bar1', 'bar2', 'bar3'), + ), + ), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'table-message', + ); + + $message = $wildfire->format($record); + + $this->assertEquals( + '171|[{"Type":"TABLE","File":"","Line":"","Label":"table-channel: table-message"},[["col1","col2","col3"],["val1","val2","val3"],["foo1","foo2","foo3"],["bar1","bar2","bar3"]]]|', + $message + ); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php new file mode 100644 index 0000000..568eb9d --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; +use Monolog\Processor\WebProcessor; + +class AbstractHandlerTest extends TestCase +{ + /** + * @covers Monolog\Handler\AbstractHandler::__construct + * @covers Monolog\Handler\AbstractHandler::getLevel + * @covers Monolog\Handler\AbstractHandler::setLevel + * @covers Monolog\Handler\AbstractHandler::getBubble + * @covers Monolog\Handler\AbstractHandler::setBubble + * @covers Monolog\Handler\AbstractHandler::getFormatter + * @covers Monolog\Handler\AbstractHandler::setFormatter + */ + public function testConstructAndGetSet() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false)); + $this->assertEquals(Logger::WARNING, $handler->getLevel()); + $this->assertEquals(false, $handler->getBubble()); + + $handler->setLevel(Logger::ERROR); + $handler->setBubble(true); + $handler->setFormatter($formatter = new LineFormatter); + $this->assertEquals(Logger::ERROR, $handler->getLevel()); + $this->assertEquals(true, $handler->getBubble()); + $this->assertSame($formatter, $handler->getFormatter()); + } + + /** + * @covers Monolog\Handler\AbstractHandler::handleBatch + */ + public function testHandleBatch() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler'); + $handler->expects($this->exactly(2)) + ->method('handle'); + $handler->handleBatch(array($this->getRecord(), $this->getRecord())); + } + + /** + * @covers Monolog\Handler\AbstractHandler::isHandling + */ + public function testIsHandling() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false)); + $this->assertTrue($handler->isHandling($this->getRecord())); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG))); + } + + /** + * @covers Monolog\Handler\AbstractHandler::__construct + */ + public function testHandlesPsrStyleLevels() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array('warning', false)); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG))); + $handler->setLevel('debug'); + $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG))); + } + + /** + * @covers Monolog\Handler\AbstractHandler::getFormatter + * @covers Monolog\Handler\AbstractHandler::getDefaultFormatter + */ + public function testGetFormatterInitializesDefault() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler'); + $this->assertInstanceOf('Monolog\Formatter\LineFormatter', $handler->getFormatter()); + } + + /** + * @covers Monolog\Handler\AbstractHandler::pushProcessor + * @covers Monolog\Handler\AbstractHandler::popProcessor + * @expectedException LogicException + */ + public function testPushPopProcessor() + { + $logger = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler'); + $processor1 = new WebProcessor; + $processor2 = new WebProcessor; + + $logger->pushProcessor($processor1); + $logger->pushProcessor($processor2); + + $this->assertEquals($processor2, $logger->popProcessor()); + $this->assertEquals($processor1, $logger->popProcessor()); + $logger->popProcessor(); + } + + /** + * @covers Monolog\Handler\AbstractHandler::pushProcessor + * @expectedException InvalidArgumentException + */ + public function testPushProcessorWithNonCallable() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler'); + + $handler->pushProcessor(new \stdClass()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php new file mode 100644 index 0000000..24d4f63 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; +use Monolog\Processor\WebProcessor; + +class AbstractProcessingHandlerTest extends TestCase +{ + /** + * @covers Monolog\Handler\AbstractProcessingHandler::handle + */ + public function testHandleLowerLevelMessage() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, true)); + $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG))); + } + + /** + * @covers Monolog\Handler\AbstractProcessingHandler::handle + */ + public function testHandleBubbling() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, true)); + $this->assertFalse($handler->handle($this->getRecord())); + } + + /** + * @covers Monolog\Handler\AbstractProcessingHandler::handle + */ + public function testHandleNotBubbling() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, false)); + $this->assertTrue($handler->handle($this->getRecord())); + } + + /** + * @covers Monolog\Handler\AbstractProcessingHandler::handle + */ + public function testHandleIsFalseWhenNotHandled() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, false)); + $this->assertTrue($handler->handle($this->getRecord())); + $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG))); + } + + /** + * @covers Monolog\Handler\AbstractProcessingHandler::processRecord + */ + public function testProcessRecord() + { + $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler'); + $handler->pushProcessor(new WebProcessor(array( + 'REQUEST_URI' => '', + 'REQUEST_METHOD' => '', + 'REMOTE_ADDR' => '', + 'SERVER_NAME' => '', + 'UNIQUE_ID' => '', + ))); + $handledRecord = null; + $handler->expects($this->once()) + ->method('write') + ->will($this->returnCallback(function ($record) use (&$handledRecord) { + $handledRecord = $record; + })) + ; + $handler->handle($this->getRecord()); + $this->assertEquals(6, count($handledRecord['extra'])); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php new file mode 100644 index 0000000..a71d625 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; +use PhpAmqpLib\Message\AMQPMessage; +use PhpAmqpLib\Connection\AMQPConnection; + +/** + * @covers Monolog\Handler\RotatingFileHandler + */ +class AmqpHandlerTest extends TestCase +{ + public function testHandleAmqpExt() + { + if (!class_exists('AMQPConnection') || !class_exists('AMQPExchange')) { + $this->markTestSkipped("amqp-php not installed"); + } + + if (!class_exists('AMQPChannel')) { + $this->markTestSkipped("Please update AMQP to version >= 1.0"); + } + + $messages = array(); + + $exchange = $this->getMock('AMQPExchange', array('publish', 'setName'), array(), '', false); + $exchange->expects($this->once()) + ->method('setName') + ->with('log') + ; + $exchange->expects($this->any()) + ->method('publish') + ->will($this->returnCallback(function ($message, $routing_key, $flags = 0, $attributes = array()) use (&$messages) { + $messages[] = array($message, $routing_key, $flags, $attributes); + })) + ; + + $handler = new AmqpHandler($exchange, 'log'); + + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $expected = array( + array( + 'message' => 'test', + 'context' => array( + 'data' => array(), + 'foo' => 34, + ), + 'level' => 300, + 'level_name' => 'WARNING', + 'channel' => 'test', + 'extra' => array(), + ), + 'warn.test', + 0, + array( + 'delivery_mode' => 2, + 'Content-type' => 'application/json' + ) + ); + + $handler->handle($record); + + $this->assertCount(1, $messages); + $messages[0][0] = json_decode($messages[0][0], true); + unset($messages[0][0]['datetime']); + $this->assertEquals($expected, $messages[0]); + } + + public function testHandlePhpAmqpLib() + { + if (!class_exists('PhpAmqpLib\Connection\AMQPConnection')) { + $this->markTestSkipped("php-amqplib not installed"); + } + + $messages = array(); + + $exchange = $this->getMock('PhpAmqpLib\Channel\AMQPChannel', array('basic_publish', '__destruct'), array(), '', false); + + $exchange->expects($this->any()) + ->method('basic_publish') + ->will($this->returnCallback(function (AMQPMessage $msg, $exchange = "", $routing_key = "", $mandatory = false, $immediate = false, $ticket = null) use (&$messages) { + $messages[] = array($msg, $exchange, $routing_key, $mandatory, $immediate, $ticket); + })) + ; + + $handler = new AmqpHandler($exchange, 'log'); + + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $expected = array( + array( + 'message' => 'test', + 'context' => array( + 'data' => array(), + 'foo' => 34, + ), + 'level' => 300, + 'level_name' => 'WARNING', + 'channel' => 'test', + 'extra' => array(), + ), + 'log', + 'warn.test', + false, + false, + null, + array( + 'delivery_mode' => 2, + 'content_type' => 'application/json' + ) + ); + + $handler->handle($record); + + $this->assertCount(1, $messages); + + /* @var $msg AMQPMessage */ + $msg = $messages[0][0]; + $messages[0][0] = json_decode($msg->body, true); + $messages[0][] = $msg->get_properties(); + unset($messages[0][0]['datetime']); + + $this->assertEquals($expected, $messages[0]); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php new file mode 100644 index 0000000..ffb1d74 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @covers Monolog\Handler\BrowserConsoleHandlerTest + */ +class BrowserConsoleHandlerTest extends TestCase +{ + protected function setUp() + { + BrowserConsoleHandler::reset(); + } + + protected function generateScript() + { + $reflMethod = new \ReflectionMethod('Monolog\Handler\BrowserConsoleHandler', 'generateScript'); + $reflMethod->setAccessible(true); + + return $reflMethod->invoke(null); + } + + public function testStyling() + { + $handler = new BrowserConsoleHandler(); + $handler->setFormatter($this->getIdentityFormatter()); + + $handler->handle($this->getRecord(Logger::DEBUG, 'foo[[bar]]{color: red}')); + + $expected = <<assertEquals($expected, $this->generateScript()); + } + + public function testEscaping() + { + $handler = new BrowserConsoleHandler(); + $handler->setFormatter($this->getIdentityFormatter()); + + $handler->handle($this->getRecord(Logger::DEBUG, "[foo] [[\"bar\n[baz]\"]]{color: red}")); + + $expected = <<assertEquals($expected, $this->generateScript()); + } + + public function testAutolabel() + { + $handler = new BrowserConsoleHandler(); + $handler->setFormatter($this->getIdentityFormatter()); + + $handler->handle($this->getRecord(Logger::DEBUG, '[[foo]]{macro: autolabel}')); + $handler->handle($this->getRecord(Logger::DEBUG, '[[bar]]{macro: autolabel}')); + $handler->handle($this->getRecord(Logger::DEBUG, '[[foo]]{macro: autolabel}')); + + $expected = <<assertEquals($expected, $this->generateScript()); + } + + public function testContext() + { + $handler = new BrowserConsoleHandler(); + $handler->setFormatter($this->getIdentityFormatter()); + + $handler->handle($this->getRecord(Logger::DEBUG, 'test', array('foo' => 'bar'))); + + $expected = <<assertEquals($expected, $this->generateScript()); + } + + public function testConcurrentHandlers() + { + $handler1 = new BrowserConsoleHandler(); + $handler1->setFormatter($this->getIdentityFormatter()); + + $handler2 = new BrowserConsoleHandler(); + $handler2->setFormatter($this->getIdentityFormatter()); + + $handler1->handle($this->getRecord(Logger::DEBUG, 'test1')); + $handler2->handle($this->getRecord(Logger::DEBUG, 'test2')); + $handler1->handle($this->getRecord(Logger::DEBUG, 'test3')); + $handler2->handle($this->getRecord(Logger::DEBUG, 'test4')); + + $expected = <<assertEquals($expected, $this->generateScript()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php new file mode 100644 index 0000000..da8b3c3 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php @@ -0,0 +1,158 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +class BufferHandlerTest extends TestCase +{ + private $shutdownCheckHandler; + + /** + * @covers Monolog\Handler\BufferHandler::__construct + * @covers Monolog\Handler\BufferHandler::handle + * @covers Monolog\Handler\BufferHandler::close + */ + public function testHandleBuffers() + { + $test = new TestHandler(); + $handler = new BufferHandler($test); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $this->assertFalse($test->hasDebugRecords()); + $this->assertFalse($test->hasInfoRecords()); + $handler->close(); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue(count($test->getRecords()) === 2); + } + + /** + * @covers Monolog\Handler\BufferHandler::close + * @covers Monolog\Handler\BufferHandler::flush + */ + public function testPropagatesRecordsAtEndOfRequest() + { + $test = new TestHandler(); + $handler = new BufferHandler($test); + $handler->handle($this->getRecord(Logger::WARNING)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $this->shutdownCheckHandler = $test; + register_shutdown_function(array($this, 'checkPropagation')); + } + + public function checkPropagation() + { + if (!$this->shutdownCheckHandler->hasWarningRecords() || !$this->shutdownCheckHandler->hasDebugRecords()) { + echo '!!! BufferHandlerTest::testPropagatesRecordsAtEndOfRequest failed to verify that the messages have been propagated' . PHP_EOL; + exit(1); + } + } + + /** + * @covers Monolog\Handler\BufferHandler::handle + */ + public function testHandleBufferLimit() + { + $test = new TestHandler(); + $handler = new BufferHandler($test, 2); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->handle($this->getRecord(Logger::WARNING)); + $handler->close(); + $this->assertTrue($test->hasWarningRecords()); + $this->assertTrue($test->hasInfoRecords()); + $this->assertFalse($test->hasDebugRecords()); + } + + /** + * @covers Monolog\Handler\BufferHandler::handle + */ + public function testHandleBufferLimitWithFlushOnOverflow() + { + $test = new TestHandler(); + $handler = new BufferHandler($test, 3, Logger::DEBUG, true, true); + + // send two records + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $this->assertFalse($test->hasDebugRecords()); + $this->assertCount(0, $test->getRecords()); + + // overflow + $handler->handle($this->getRecord(Logger::INFO)); + $this->assertTrue($test->hasDebugRecords()); + $this->assertCount(3, $test->getRecords()); + + // should buffer again + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertCount(3, $test->getRecords()); + + $handler->close(); + $this->assertCount(5, $test->getRecords()); + $this->assertTrue($test->hasWarningRecords()); + $this->assertTrue($test->hasInfoRecords()); + } + + /** + * @covers Monolog\Handler\BufferHandler::handle + */ + public function testHandleLevel() + { + $test = new TestHandler(); + $handler = new BufferHandler($test, 0, Logger::INFO); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->handle($this->getRecord(Logger::WARNING)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->close(); + $this->assertTrue($test->hasWarningRecords()); + $this->assertTrue($test->hasInfoRecords()); + $this->assertFalse($test->hasDebugRecords()); + } + + /** + * @covers Monolog\Handler\BufferHandler::flush + */ + public function testFlush() + { + $test = new TestHandler(); + $handler = new BufferHandler($test, 0); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->flush(); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue($test->hasDebugRecords()); + $this->assertFalse($test->hasWarningRecords()); + } + + /** + * @covers Monolog\Handler\BufferHandler::handle + */ + public function testHandleUsesProcessors() + { + $test = new TestHandler(); + $handler = new BufferHandler($test); + $handler->pushProcessor(function ($record) { + $record['extra']['foo'] = true; + + return $record; + }); + $handler->handle($this->getRecord(Logger::WARNING)); + $handler->flush(); + $this->assertTrue($test->hasWarningRecords()); + $records = $test->getRecords(); + $this->assertTrue($records[0]['extra']['foo']); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php new file mode 100644 index 0000000..4d64025 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php @@ -0,0 +1,141 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @covers Monolog\Handler\ChromePHPHandler + */ +class ChromePHPHandlerTest extends TestCase +{ + protected function setUp() + { + TestChromePHPHandler::reset(); + $_SERVER['HTTP_USER_AGENT'] = 'Monolog Test; Chrome/1.0'; + } + + public function testHeaders() + { + $handler = new TestChromePHPHandler(); + $handler->setFormatter($this->getIdentityFormatter()); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::WARNING)); + + $expected = array( + 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array( + 'version' => ChromePHPHandler::VERSION, + 'columns' => array('label', 'log', 'backtrace', 'type'), + 'rows' => array( + 'test', + 'test', + ), + 'request_uri' => '', + )))) + ); + + $this->assertEquals($expected, $handler->getHeaders()); + } + + public function testHeadersOverflow() + { + $handler = new TestChromePHPHandler(); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 150 * 1024))); + + // overflow chrome headers limit + $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 100 * 1024))); + + $expected = array( + 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array( + 'version' => ChromePHPHandler::VERSION, + 'columns' => array('label', 'log', 'backtrace', 'type'), + 'rows' => array( + array( + 'test', + 'test', + 'unknown', + 'log', + ), + array( + 'test', + str_repeat('a', 150 * 1024), + 'unknown', + 'warn', + ), + array( + 'monolog', + 'Incomplete logs, chrome header size limit reached', + 'unknown', + 'warn', + ), + ), + 'request_uri' => '', + )))) + ); + + $this->assertEquals($expected, $handler->getHeaders()); + } + + public function testConcurrentHandlers() + { + $handler = new TestChromePHPHandler(); + $handler->setFormatter($this->getIdentityFormatter()); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::WARNING)); + + $handler2 = new TestChromePHPHandler(); + $handler2->setFormatter($this->getIdentityFormatter()); + $handler2->handle($this->getRecord(Logger::DEBUG)); + $handler2->handle($this->getRecord(Logger::WARNING)); + + $expected = array( + 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array( + 'version' => ChromePHPHandler::VERSION, + 'columns' => array('label', 'log', 'backtrace', 'type'), + 'rows' => array( + 'test', + 'test', + 'test', + 'test', + ), + 'request_uri' => '', + )))) + ); + + $this->assertEquals($expected, $handler2->getHeaders()); + } +} + +class TestChromePHPHandler extends ChromePHPHandler +{ + protected $headers = array(); + + public static function reset() + { + self::$initialized = false; + self::$overflowed = false; + self::$sendHeaders = true; + self::$json['rows'] = array(); + } + + protected function sendHeader($header, $content) + { + $this->headers[$header] = $content; + } + + public function getHeaders() + { + return $this->headers; + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php new file mode 100644 index 0000000..9fc4b38 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +class CouchDBHandlerTest extends TestCase +{ + public function testHandle() + { + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $handler = new CouchDBHandler(); + + try { + $handler->handle($record); + } catch (\RuntimeException $e) { + $this->markTestSkipped('Could not connect to couchdb server on http://localhost:5984'); + } + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php new file mode 100644 index 0000000..d67da90 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +class DoctrineCouchDBHandlerTest extends TestCase +{ + protected function setup() + { + if (!class_exists('Doctrine\CouchDB\CouchDBClient')) { + $this->markTestSkipped('The "doctrine/couchdb" package is not installed'); + } + } + + public function testHandle() + { + $client = $this->getMockBuilder('Doctrine\\CouchDB\\CouchDBClient') + ->setMethods(array('postDocument')) + ->disableOriginalConstructor() + ->getMock(); + + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $expected = array( + 'message' => 'test', + 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34), + 'level' => Logger::WARNING, + 'level_name' => 'WARNING', + 'channel' => 'test', + 'datetime' => $record['datetime']->format('Y-m-d H:i:s'), + 'extra' => array(), + ); + + $client->expects($this->once()) + ->method('postDocument') + ->with($expected); + + $handler = new DoctrineCouchDBHandler($client); + $handler->handle($record); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php new file mode 100644 index 0000000..42d4323 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; + +class DynamoDbHandlerTest extends TestCase +{ + private $client; + + public function setUp() + { + if (!class_exists('Aws\DynamoDb\DynamoDbClient')) { + $this->markTestSkipped('aws/aws-sdk-php not installed'); + } + + $this->client = $this->getMockBuilder('Aws\DynamoDb\DynamoDbClient') + ->setMethods(array('formatAttributes', '__call')) + ->disableOriginalConstructor()->getMock(); + } + + public function testConstruct() + { + $this->assertInstanceOf('Monolog\Handler\DynamoDbHandler', new DynamoDbHandler($this->client, 'foo')); + } + + public function testInterface() + { + $this->assertInstanceOf('Monolog\Handler\HandlerInterface', new DynamoDbHandler($this->client, 'foo')); + } + + public function testGetFormatter() + { + $handler = new DynamoDbHandler($this->client, 'foo'); + $this->assertInstanceOf('Monolog\Formatter\ScalarFormatter', $handler->getFormatter()); + } + + public function testHandle() + { + $record = $this->getRecord(); + $formatter = $this->getMock('Monolog\Formatter\FormatterInterface'); + $formatted = array('foo' => 1, 'bar' => 2); + $handler = new DynamoDbHandler($this->client, 'foo'); + $handler->setFormatter($formatter); + + $formatter + ->expects($this->once()) + ->method('format') + ->with($record) + ->will($this->returnValue($formatted)); + $this->client + ->expects($this->once()) + ->method('formatAttributes') + ->with($this->isType('array')) + ->will($this->returnValue($formatted)); + $this->client + ->expects($this->once()) + ->method('__call') + ->with('putItem', array(array( + 'TableName' => 'foo', + 'Item' => $formatted + ))); + + $handler->handle($record); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php new file mode 100644 index 0000000..1687074 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php @@ -0,0 +1,239 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\ElasticaFormatter; +use Monolog\Formatter\NormalizerFormatter; +use Monolog\TestCase; +use Monolog\Logger; +use Elastica\Client; +use Elastica\Request; +use Elastica\Response; + +class ElasticSearchHandlerTest extends TestCase +{ + /** + * @var Client mock + */ + protected $client; + + /** + * @var array Default handler options + */ + protected $options = array( + 'index' => 'my_index', + 'type' => 'doc_type', + ); + + public function setUp() + { + // Elastica lib required + if (!class_exists("Elastica\Client")) { + $this->markTestSkipped("ruflin/elastica not installed"); + } + + // base mock Elastica Client object + $this->client = $this->getMockBuilder('Elastica\Client') + ->setMethods(array('addDocuments')) + ->disableOriginalConstructor() + ->getMock(); + } + + /** + * @covers Monolog\Handler\ElasticSearchHandler::write + * @covers Monolog\Handler\ElasticSearchHandler::handleBatch + * @covers Monolog\Handler\ElasticSearchHandler::bulkSend + * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter + */ + public function testHandle() + { + // log message + $msg = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + // format expected result + $formatter = new ElasticaFormatter($this->options['index'], $this->options['type']); + $expected = array($formatter->format($msg)); + + // setup ES client mock + $this->client->expects($this->any()) + ->method('addDocuments') + ->with($expected); + + // perform tests + $handler = new ElasticSearchHandler($this->client, $this->options); + $handler->handle($msg); + $handler->handleBatch(array($msg)); + } + + /** + * @covers Monolog\Handler\ElasticSearchHandler::setFormatter + */ + public function testSetFormatter() + { + $handler = new ElasticSearchHandler($this->client); + $formatter = new ElasticaFormatter('index_new', 'type_new'); + $handler->setFormatter($formatter); + $this->assertInstanceOf('Monolog\Formatter\ElasticaFormatter', $handler->getFormatter()); + $this->assertEquals('index_new', $handler->getFormatter()->getIndex()); + $this->assertEquals('type_new', $handler->getFormatter()->getType()); + } + + /** + * @covers Monolog\Handler\ElasticSearchHandler::setFormatter + * @expectedException InvalidArgumentException + * @expectedExceptionMessage ElasticSearchHandler is only compatible with ElasticaFormatter + */ + public function testSetFormatterInvalid() + { + $handler = new ElasticSearchHandler($this->client); + $formatter = new NormalizerFormatter(); + $handler->setFormatter($formatter); + } + + /** + * @covers Monolog\Handler\ElasticSearchHandler::__construct + * @covers Monolog\Handler\ElasticSearchHandler::getOptions + */ + public function testOptions() + { + $expected = array( + 'index' => $this->options['index'], + 'type' => $this->options['type'], + 'ignore_error' => false, + ); + $handler = new ElasticSearchHandler($this->client, $this->options); + $this->assertEquals($expected, $handler->getOptions()); + } + + /** + * @covers Monolog\Handler\ElasticSearchHandler::bulkSend + * @dataProvider providerTestConnectionErrors + */ + public function testConnectionErrors($ignore, $expectedError) + { + $clientOpts = array('host' => '127.0.0.1', 'port' => 1); + $client = new Client($clientOpts); + $handlerOpts = array('ignore_error' => $ignore); + $handler = new ElasticSearchHandler($client, $handlerOpts); + + if ($expectedError) { + $this->setExpectedException($expectedError[0], $expectedError[1]); + $handler->handle($this->getRecord()); + } else { + $this->assertFalse($handler->handle($this->getRecord())); + } + } + + /** + * @return array + */ + public function providerTestConnectionErrors() + { + return array( + array(false, array('RuntimeException', 'Error sending messages to Elasticsearch')), + array(true, false), + ); + } + + /** + * Integration test using localhost Elastic Search server + * + * @covers Monolog\Handler\ElasticSearchHandler::__construct + * @covers Monolog\Handler\ElasticSearchHandler::handleBatch + * @covers Monolog\Handler\ElasticSearchHandler::bulkSend + * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter + */ + public function testHandleIntegration() + { + $msg = array( + 'level' => Logger::ERROR, + 'level_name' => 'ERROR', + 'channel' => 'meh', + 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass), + 'datetime' => new \DateTime("@0"), + 'extra' => array(), + 'message' => 'log', + ); + + $expected = $msg; + $expected['datetime'] = $msg['datetime']->format(\DateTime::ISO8601); + $expected['context'] = array( + 'class' => '[object] (stdClass: {})', + 'foo' => 7, + 0 => 'bar', + ); + + $client = new Client(); + $handler = new ElasticSearchHandler($client, $this->options); + try { + $handler->handleBatch(array($msg)); + } catch (\RuntimeException $e) { + $this->markTestSkipped("Cannot connect to Elastic Search server on localhost"); + } + + // check document id from ES server response + $documentId = $this->getCreatedDocId($client->getLastResponse()); + $this->assertNotEmpty($documentId, 'No elastic document id received'); + + // retrieve document source from ES and validate + $document = $this->getDocSourceFromElastic( + $client, + $this->options['index'], + $this->options['type'], + $documentId + ); + $this->assertEquals($expected, $document); + + // remove test index from ES + $client->request("/{$this->options['index']}", Request::DELETE); + } + + /** + * Return last created document id from ES response + * @param Response $response Elastica Response object + * @return string|null + */ + protected function getCreatedDocId(Response $response) + { + $data = $response->getData(); + if (!empty($data['items'][0]['create']['_id'])) { + return $data['items'][0]['create']['_id']; + } + } + + /** + * Retrieve document by id from Elasticsearch + * @param Client $client Elastica client + * @param string $index + * @param string $type + * @param string $documentId + * @return array + */ + protected function getDocSourceFromElastic(Client $client, $index, $type, $documentId) + { + $resp = $client->request("/{$index}/{$type}/{$documentId}", Request::GET); + $data = $resp->getData(); + if (!empty($data['_source'])) { + return $data['_source']; + } + + return array(); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php new file mode 100644 index 0000000..99785cb --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +function error_log() +{ + $GLOBALS['error_log'][] = func_get_args(); +} + +class ErrorLogHandlerTest extends TestCase +{ + protected function setUp() + { + $GLOBALS['error_log'] = array(); + } + + /** + * @covers Monolog\Handler\ErrorLogHandler::__construct + * @expectedException InvalidArgumentException + * @expectedExceptionMessage The given message type "42" is not supported + */ + public function testShouldNotAcceptAnInvalidTypeOnContructor() + { + new ErrorLogHandler(42); + } + + /** + * @covers Monolog\Handler\ErrorLogHandler::write + */ + public function testShouldLogMessagesUsingErrorLogFuncion() + { + $type = ErrorLogHandler::OPERATING_SYSTEM; + $handler = new ErrorLogHandler($type); + $handler->setFormatter(new LineFormatter('%channel%.%level_name%: %message% %context% %extra%', null, true)); + $handler->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz")); + + $this->assertSame("test.ERROR: Foo\nBar\r\n\r\nBaz [] []", $GLOBALS['error_log'][0][0]); + $this->assertSame($GLOBALS['error_log'][0][1], $type); + + $handler = new ErrorLogHandler($type, Logger::DEBUG, true, true); + $handler->setFormatter(new LineFormatter(null, null, true)); + $handler->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz")); + + $this->assertStringMatchesFormat('[%s] test.ERROR: Foo', $GLOBALS['error_log'][1][0]); + $this->assertSame($GLOBALS['error_log'][1][1], $type); + + $this->assertStringMatchesFormat('Bar', $GLOBALS['error_log'][2][0]); + $this->assertSame($GLOBALS['error_log'][2][1], $type); + + $this->assertStringMatchesFormat('Baz [] []', $GLOBALS['error_log'][3][0]); + $this->assertSame($GLOBALS['error_log'][3][1], $type); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php new file mode 100644 index 0000000..31b7686 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php @@ -0,0 +1,170 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\TestCase; + +class FilterHandlerTest extends TestCase +{ + /** + * @covers Monolog\Handler\FilterHandler::isHandling + */ + public function testIsHandling() + { + $test = new TestHandler(); + $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG))); + $this->assertTrue($handler->isHandling($this->getRecord(Logger::INFO))); + $this->assertTrue($handler->isHandling($this->getRecord(Logger::NOTICE))); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::WARNING))); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::ERROR))); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::CRITICAL))); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::ALERT))); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::EMERGENCY))); + } + + /** + * @covers Monolog\Handler\FilterHandler::handle + * @covers Monolog\Handler\FilterHandler::setAcceptedLevels + * @covers Monolog\Handler\FilterHandler::isHandling + */ + public function testHandleProcessOnlyNeededLevels() + { + $test = new TestHandler(); + $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE); + + $handler->handle($this->getRecord(Logger::DEBUG)); + $this->assertFalse($test->hasDebugRecords()); + + $handler->handle($this->getRecord(Logger::INFO)); + $this->assertTrue($test->hasInfoRecords()); + $handler->handle($this->getRecord(Logger::NOTICE)); + $this->assertTrue($test->hasNoticeRecords()); + + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertFalse($test->hasWarningRecords()); + $handler->handle($this->getRecord(Logger::ERROR)); + $this->assertFalse($test->hasErrorRecords()); + $handler->handle($this->getRecord(Logger::CRITICAL)); + $this->assertFalse($test->hasCriticalRecords()); + $handler->handle($this->getRecord(Logger::ALERT)); + $this->assertFalse($test->hasAlertRecords()); + $handler->handle($this->getRecord(Logger::EMERGENCY)); + $this->assertFalse($test->hasEmergencyRecords()); + + $test = new TestHandler(); + $handler = new FilterHandler($test, array(Logger::INFO, Logger::ERROR)); + + $handler->handle($this->getRecord(Logger::DEBUG)); + $this->assertFalse($test->hasDebugRecords()); + $handler->handle($this->getRecord(Logger::INFO)); + $this->assertTrue($test->hasInfoRecords()); + $handler->handle($this->getRecord(Logger::NOTICE)); + $this->assertFalse($test->hasNoticeRecords()); + $handler->handle($this->getRecord(Logger::ERROR)); + $this->assertTrue($test->hasErrorRecords()); + $handler->handle($this->getRecord(Logger::CRITICAL)); + $this->assertFalse($test->hasCriticalRecords()); + } + + /** + * @covers Monolog\Handler\FilterHandler::setAcceptedLevels + * @covers Monolog\Handler\FilterHandler::getAcceptedLevels + */ + public function testAcceptedLevelApi() + { + $test = new TestHandler(); + $handler = new FilterHandler($test); + + $levels = array(Logger::INFO, Logger::ERROR); + $handler->setAcceptedLevels($levels); + $this->assertSame($levels, $handler->getAcceptedLevels()); + + $handler->setAcceptedLevels(array('info', 'error')); + $this->assertSame($levels, $handler->getAcceptedLevels()); + + $levels = array(Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY); + $handler->setAcceptedLevels(Logger::CRITICAL, Logger::EMERGENCY); + $this->assertSame($levels, $handler->getAcceptedLevels()); + + $handler->setAcceptedLevels('critical', 'emergency'); + $this->assertSame($levels, $handler->getAcceptedLevels()); + } + + /** + * @covers Monolog\Handler\FilterHandler::handle + */ + public function testHandleUsesProcessors() + { + $test = new TestHandler(); + $handler = new FilterHandler($test, Logger::DEBUG, Logger::EMERGENCY); + $handler->pushProcessor( + function ($record) { + $record['extra']['foo'] = true; + + return $record; + } + ); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasWarningRecords()); + $records = $test->getRecords(); + $this->assertTrue($records[0]['extra']['foo']); + } + + /** + * @covers Monolog\Handler\FilterHandler::handle + */ + public function testHandleRespectsBubble() + { + $test = new TestHandler(); + + $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE, false); + $this->assertTrue($handler->handle($this->getRecord(Logger::INFO))); + $this->assertFalse($handler->handle($this->getRecord(Logger::WARNING))); + + $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE, true); + $this->assertFalse($handler->handle($this->getRecord(Logger::INFO))); + $this->assertFalse($handler->handle($this->getRecord(Logger::WARNING))); + } + + /** + * @covers Monolog\Handler\FilterHandler::handle + */ + public function testHandleWithCallback() + { + $test = new TestHandler(); + $handler = new FilterHandler( + function ($record, $handler) use ($test) { + return $test; + }, Logger::INFO, Logger::NOTICE, false + ); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $this->assertFalse($test->hasDebugRecords()); + $this->assertTrue($test->hasInfoRecords()); + } + + /** + * @covers Monolog\Handler\FilterHandler::handle + * @expectedException \RuntimeException + */ + public function testHandleWithBadCallbackThrowsException() + { + $handler = new FilterHandler( + function ($record, $handler) { + return 'foo'; + } + ); + $handler->handle($this->getRecord(Logger::WARNING)); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php new file mode 100644 index 0000000..8e31e9b --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php @@ -0,0 +1,255 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; +use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; +use Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy; +use Psr\Log\LogLevel; + +class FingersCrossedHandlerTest extends TestCase +{ + /** + * @covers Monolog\Handler\FingersCrossedHandler::__construct + * @covers Monolog\Handler\FingersCrossedHandler::handle + */ + public function testHandleBuffers() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $this->assertFalse($test->hasDebugRecords()); + $this->assertFalse($test->hasInfoRecords()); + $handler->handle($this->getRecord(Logger::WARNING)); + $handler->close(); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue(count($test->getRecords()) === 3); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::handle + */ + public function testHandleStopsBufferingAfterTrigger() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test); + $handler->handle($this->getRecord(Logger::WARNING)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->close(); + $this->assertTrue($test->hasWarningRecords()); + $this->assertTrue($test->hasDebugRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::handle + * @covers Monolog\Handler\FingersCrossedHandler::reset + */ + public function testHandleRestartBufferingAfterReset() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test); + $handler->handle($this->getRecord(Logger::WARNING)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->reset(); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->close(); + $this->assertTrue($test->hasWarningRecords()); + $this->assertTrue($test->hasDebugRecords()); + $this->assertFalse($test->hasInfoRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::handle + */ + public function testHandleRestartBufferingAfterBeingTriggeredWhenStopBufferingIsDisabled() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, Logger::WARNING, 0, false, false); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::WARNING)); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->close(); + $this->assertTrue($test->hasWarningRecords()); + $this->assertTrue($test->hasDebugRecords()); + $this->assertFalse($test->hasInfoRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::handle + */ + public function testHandleBufferLimit() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, Logger::WARNING, 2); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasWarningRecords()); + $this->assertTrue($test->hasInfoRecords()); + $this->assertFalse($test->hasDebugRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::handle + */ + public function testHandleWithCallback() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler(function ($record, $handler) use ($test) { + return $test; + }); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $this->assertFalse($test->hasDebugRecords()); + $this->assertFalse($test->hasInfoRecords()); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue(count($test->getRecords()) === 3); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::handle + * @expectedException RuntimeException + */ + public function testHandleWithBadCallbackThrowsException() + { + $handler = new FingersCrossedHandler(function ($record, $handler) { + return 'foo'; + }); + $handler->handle($this->getRecord(Logger::WARNING)); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::isHandling + */ + public function testIsHandlingAlways() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, Logger::ERROR); + $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG))); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::__construct + * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct + * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated + */ + public function testErrorLevelActivationStrategy() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $this->assertFalse($test->hasDebugRecords()); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasWarningRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::__construct + * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct + * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated + */ + public function testErrorLevelActivationStrategyWithPsrLevel() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy('warning')); + $handler->handle($this->getRecord(Logger::DEBUG)); + $this->assertFalse($test->hasDebugRecords()); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasWarningRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct + * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated + */ + public function testChannelLevelActivationStrategy() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy(Logger::ERROR, array('othertest' => Logger::DEBUG))); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertFalse($test->hasWarningRecords()); + $record = $this->getRecord(Logger::DEBUG); + $record['channel'] = 'othertest'; + $handler->handle($record); + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasWarningRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct + * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated + */ + public function testChannelLevelActivationStrategyWithPsrLevels() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy('error', array('othertest' => 'debug'))); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertFalse($test->hasWarningRecords()); + $record = $this->getRecord(Logger::DEBUG); + $record['channel'] = 'othertest'; + $handler->handle($record); + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasWarningRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::handle + */ + public function testHandleUsesProcessors() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, Logger::INFO); + $handler->pushProcessor(function ($record) { + $record['extra']['foo'] = true; + + return $record; + }); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasWarningRecords()); + $records = $test->getRecords(); + $this->assertTrue($records[0]['extra']['foo']); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::close + */ + public function testPassthruOnClose() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING), 0, true, true, Logger::INFO); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->close(); + $this->assertFalse($test->hasDebugRecords()); + $this->assertTrue($test->hasInfoRecords()); + } + + /** + * @covers Monolog\Handler\FingersCrossedHandler::close + */ + public function testPsrLevelPassthruOnClose() + { + $test = new TestHandler(); + $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING), 0, true, true, LogLevel::INFO); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->close(); + $this->assertFalse($test->hasDebugRecords()); + $this->assertTrue($test->hasInfoRecords()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php new file mode 100644 index 0000000..0eb10a6 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @covers Monolog\Handler\FirePHPHandler + */ +class FirePHPHandlerTest extends TestCase +{ + public function setUp() + { + TestFirePHPHandler::reset(); + $_SERVER['HTTP_USER_AGENT'] = 'Monolog Test; FirePHP/1.0'; + } + + public function testHeaders() + { + $handler = new TestFirePHPHandler; + $handler->setFormatter($this->getIdentityFormatter()); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::WARNING)); + + $expected = array( + 'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2', + 'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1', + 'X-Wf-1-Plugin-1' => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3', + 'X-Wf-1-1-1-1' => 'test', + 'X-Wf-1-1-1-2' => 'test', + ); + + $this->assertEquals($expected, $handler->getHeaders()); + } + + public function testConcurrentHandlers() + { + $handler = new TestFirePHPHandler; + $handler->setFormatter($this->getIdentityFormatter()); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::WARNING)); + + $handler2 = new TestFirePHPHandler; + $handler2->setFormatter($this->getIdentityFormatter()); + $handler2->handle($this->getRecord(Logger::DEBUG)); + $handler2->handle($this->getRecord(Logger::WARNING)); + + $expected = array( + 'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2', + 'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1', + 'X-Wf-1-Plugin-1' => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3', + 'X-Wf-1-1-1-1' => 'test', + 'X-Wf-1-1-1-2' => 'test', + ); + + $expected2 = array( + 'X-Wf-1-1-1-3' => 'test', + 'X-Wf-1-1-1-4' => 'test', + ); + + $this->assertEquals($expected, $handler->getHeaders()); + $this->assertEquals($expected2, $handler2->getHeaders()); + } +} + +class TestFirePHPHandler extends FirePHPHandler +{ + protected $headers = array(); + + public static function reset() + { + self::$initialized = false; + self::$sendHeaders = true; + self::$messageIndex = 1; + } + + protected function sendHeader($header, $content) + { + $this->headers[$header] = $content; + } + + public function getHeaders() + { + return $this->headers; + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep b/vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php new file mode 100644 index 0000000..91cdd31 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\LineFormatter; +use Monolog\Logger; +use Monolog\TestCase; + +/** + * @coversDefaultClass \Monolog\Handler\FleepHookHandler + */ +class FleepHookHandlerTest extends TestCase +{ + /** + * Default token to use in tests + */ + const TOKEN = '123abc'; + + /** + * @var FleepHookHandler + */ + private $handler; + + public function setUp() + { + parent::setUp(); + + if (!extension_loaded('openssl')) { + $this->markTestSkipped('This test requires openssl extension to run'); + } + + // Create instances of the handler and logger for convenience + $this->handler = new FleepHookHandler(self::TOKEN); + } + + /** + * @covers ::__construct + */ + public function testConstructorSetsExpectedDefaults() + { + $this->assertEquals(Logger::DEBUG, $this->handler->getLevel()); + $this->assertEquals(true, $this->handler->getBubble()); + } + + /** + * @covers ::getDefaultFormatter + */ + public function testHandlerUsesLineFormatterWhichIgnoresEmptyArrays() + { + $record = array( + 'message' => 'msg', + 'context' => array(), + 'level' => Logger::DEBUG, + 'level_name' => Logger::getLevelName(Logger::DEBUG), + 'channel' => 'channel', + 'datetime' => new \DateTime(), + 'extra' => array(), + ); + + $expectedFormatter = new LineFormatter(null, null, true, true); + $expected = $expectedFormatter->format($record); + + $handlerFormatter = $this->handler->getFormatter(); + $actual = $handlerFormatter->format($record); + + $this->assertEquals($expected, $actual, 'Empty context and extra arrays should not be rendered'); + } + + /** + * @covers ::__construct + */ + public function testConnectionStringisConstructedCorrectly() + { + $this->assertEquals('ssl://' . FleepHookHandler::FLEEP_HOST . ':443', $this->handler->getConnectionString()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php new file mode 100644 index 0000000..4b120d5 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Formatter\FlowdockFormatter; +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @author Dominik Liebler + * @see https://www.hipchat.com/docs/api + */ +class FlowdockHandlerTest extends TestCase +{ + /** + * @var resource + */ + private $res; + + /** + * @var FlowdockHandler + */ + private $handler; + + public function setUp() + { + if (!extension_loaded('openssl')) { + $this->markTestSkipped('This test requires openssl to run'); + } + } + + public function testWriteHeader() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/POST \/v1\/messages\/team_inbox\/.* HTTP\/1.1\\r\\nHost: api.flowdock.com\\r\\nContent-Type: application\/json\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); + + return $content; + } + + /** + * @depends testWriteHeader + */ + public function testWriteContent($content) + { + $this->assertRegexp('/"source":"test_source"/', $content); + $this->assertRegexp('/"from_address":"source@test\.com"/', $content); + } + + private function createHandler($token = 'myToken') + { + $constructorArgs = array($token, Logger::DEBUG); + $this->res = fopen('php://memory', 'a'); + $this->handler = $this->getMock( + '\Monolog\Handler\FlowdockHandler', + array('fsockopen', 'streamSetTimeout', 'closeSocket'), + $constructorArgs + ); + + $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->handler, 'localhost:1234'); + + $this->handler->expects($this->any()) + ->method('fsockopen') + ->will($this->returnValue($this->res)); + $this->handler->expects($this->any()) + ->method('streamSetTimeout') + ->will($this->returnValue(true)); + $this->handler->expects($this->any()) + ->method('closeSocket') + ->will($this->returnValue(true)); + + $this->handler->setFormatter(new FlowdockFormatter('test_source', 'source@test.com')); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php new file mode 100644 index 0000000..9d007b1 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Gelf\Message; +use Monolog\TestCase; +use Monolog\Logger; +use Monolog\Formatter\GelfMessageFormatter; + +class GelfHandlerLegacyTest extends TestCase +{ + public function setUp() + { + if (!class_exists('Gelf\MessagePublisher') || !class_exists('Gelf\Message')) { + $this->markTestSkipped("mlehner/gelf-php not installed"); + } + + require_once __DIR__ . '/GelfMockMessagePublisher.php'; + } + + /** + * @covers Monolog\Handler\GelfHandler::__construct + */ + public function testConstruct() + { + $handler = new GelfHandler($this->getMessagePublisher()); + $this->assertInstanceOf('Monolog\Handler\GelfHandler', $handler); + } + + protected function getHandler($messagePublisher) + { + $handler = new GelfHandler($messagePublisher); + + return $handler; + } + + protected function getMessagePublisher() + { + return new GelfMockMessagePublisher('localhost'); + } + + public function testDebug() + { + $messagePublisher = $this->getMessagePublisher(); + $handler = $this->getHandler($messagePublisher); + + $record = $this->getRecord(Logger::DEBUG, "A test debug message"); + $handler->handle($record); + + $this->assertEquals(7, $messagePublisher->lastMessage->getLevel()); + $this->assertEquals('test', $messagePublisher->lastMessage->getFacility()); + $this->assertEquals($record['message'], $messagePublisher->lastMessage->getShortMessage()); + $this->assertEquals(null, $messagePublisher->lastMessage->getFullMessage()); + } + + public function testWarning() + { + $messagePublisher = $this->getMessagePublisher(); + $handler = $this->getHandler($messagePublisher); + + $record = $this->getRecord(Logger::WARNING, "A test warning message"); + $handler->handle($record); + + $this->assertEquals(4, $messagePublisher->lastMessage->getLevel()); + $this->assertEquals('test', $messagePublisher->lastMessage->getFacility()); + $this->assertEquals($record['message'], $messagePublisher->lastMessage->getShortMessage()); + $this->assertEquals(null, $messagePublisher->lastMessage->getFullMessage()); + } + + public function testInjectedGelfMessageFormatter() + { + $messagePublisher = $this->getMessagePublisher(); + $handler = $this->getHandler($messagePublisher); + + $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX')); + + $record = $this->getRecord(Logger::WARNING, "A test warning message"); + $record['extra']['blarg'] = 'yep'; + $record['context']['from'] = 'logger'; + $handler->handle($record); + + $this->assertEquals('mysystem', $messagePublisher->lastMessage->getHost()); + $this->assertArrayHasKey('_EXTblarg', $messagePublisher->lastMessage->toArray()); + $this->assertArrayHasKey('_CTXfrom', $messagePublisher->lastMessage->toArray()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php new file mode 100644 index 0000000..8cdd64f --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Gelf\Message; +use Monolog\TestCase; +use Monolog\Logger; +use Monolog\Formatter\GelfMessageFormatter; + +class GelfHandlerTest extends TestCase +{ + public function setUp() + { + if (!class_exists('Gelf\Publisher') || !class_exists('Gelf\Message')) { + $this->markTestSkipped("graylog2/gelf-php not installed"); + } + } + + /** + * @covers Monolog\Handler\GelfHandler::__construct + */ + public function testConstruct() + { + $handler = new GelfHandler($this->getMessagePublisher()); + $this->assertInstanceOf('Monolog\Handler\GelfHandler', $handler); + } + + protected function getHandler($messagePublisher) + { + $handler = new GelfHandler($messagePublisher); + + return $handler; + } + + protected function getMessagePublisher() + { + return $this->getMock('Gelf\Publisher', array('publish'), array(), '', false); + } + + public function testDebug() + { + $record = $this->getRecord(Logger::DEBUG, "A test debug message"); + $expectedMessage = new Message(); + $expectedMessage + ->setLevel(7) + ->setFacility("test") + ->setShortMessage($record['message']) + ->setTimestamp($record['datetime']) + ; + + $messagePublisher = $this->getMessagePublisher(); + $messagePublisher->expects($this->once()) + ->method('publish') + ->with($expectedMessage); + + $handler = $this->getHandler($messagePublisher); + + $handler->handle($record); + } + + public function testWarning() + { + $record = $this->getRecord(Logger::WARNING, "A test warning message"); + $expectedMessage = new Message(); + $expectedMessage + ->setLevel(4) + ->setFacility("test") + ->setShortMessage($record['message']) + ->setTimestamp($record['datetime']) + ; + + $messagePublisher = $this->getMessagePublisher(); + $messagePublisher->expects($this->once()) + ->method('publish') + ->with($expectedMessage); + + $handler = $this->getHandler($messagePublisher); + + $handler->handle($record); + } + + public function testInjectedGelfMessageFormatter() + { + $record = $this->getRecord(Logger::WARNING, "A test warning message"); + $record['extra']['blarg'] = 'yep'; + $record['context']['from'] = 'logger'; + + $expectedMessage = new Message(); + $expectedMessage + ->setLevel(4) + ->setFacility("test") + ->setHost("mysystem") + ->setShortMessage($record['message']) + ->setTimestamp($record['datetime']) + ->setAdditional("EXTblarg", 'yep') + ->setAdditional("CTXfrom", 'logger') + ; + + $messagePublisher = $this->getMessagePublisher(); + $messagePublisher->expects($this->once()) + ->method('publish') + ->with($expectedMessage); + + $handler = $this->getHandler($messagePublisher); + $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX')); + $handler->handle($record); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php b/vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php new file mode 100644 index 0000000..873d92f --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Gelf\MessagePublisher; +use Gelf\Message; + +class GelfMockMessagePublisher extends MessagePublisher +{ + public function publish(Message $message) + { + $this->lastMessage = $message; + } + + public $lastMessage = null; +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php new file mode 100644 index 0000000..c6298a6 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +class GroupHandlerTest extends TestCase +{ + /** + * @covers Monolog\Handler\GroupHandler::__construct + * @expectedException InvalidArgumentException + */ + public function testConstructorOnlyTakesHandler() + { + new GroupHandler(array(new TestHandler(), "foo")); + } + + /** + * @covers Monolog\Handler\GroupHandler::__construct + * @covers Monolog\Handler\GroupHandler::handle + */ + public function testHandle() + { + $testHandlers = array(new TestHandler(), new TestHandler()); + $handler = new GroupHandler($testHandlers); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + foreach ($testHandlers as $test) { + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue(count($test->getRecords()) === 2); + } + } + + /** + * @covers Monolog\Handler\GroupHandler::handleBatch + */ + public function testHandleBatch() + { + $testHandlers = array(new TestHandler(), new TestHandler()); + $handler = new GroupHandler($testHandlers); + $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO))); + foreach ($testHandlers as $test) { + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue(count($test->getRecords()) === 2); + } + } + + /** + * @covers Monolog\Handler\GroupHandler::isHandling + */ + public function testIsHandling() + { + $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING)); + $handler = new GroupHandler($testHandlers); + $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR))); + $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING))); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG))); + } + + /** + * @covers Monolog\Handler\GroupHandler::handle + */ + public function testHandleUsesProcessors() + { + $test = new TestHandler(); + $handler = new GroupHandler(array($test)); + $handler->pushProcessor(function ($record) { + $record['extra']['foo'] = true; + + return $record; + }); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasWarningRecords()); + $records = $test->getRecords(); + $this->assertTrue($records[0]['extra']['foo']); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php new file mode 100644 index 0000000..462dac8 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php @@ -0,0 +1,244 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @author Rafael Dohms + * @see https://www.hipchat.com/docs/api + */ +class HipChatHandlerTest extends TestCase +{ + private $res; + private $handler; + + public function testWriteHeader() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: api.hipchat.com\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); + + return $content; + } + + public function testWriteCustomHostHeader() + { + $this->createHandler('myToken', 'room1', 'Monolog', true, 'hipchat.foo.bar'); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); + + return $content; + } + + public function testWriteV2() + { + $this->createHandler('myToken', 'room1', 'Monolog', false, 'hipchat.foo.bar', 'v2'); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/POST \/v2\/room\/room1\/notification\?auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); + + return $content; + } + + public function testWriteV2Notify() + { + $this->createHandler('myToken', 'room1', 'Monolog', true, 'hipchat.foo.bar', 'v2'); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/POST \/v2\/room\/room1\/notification\?auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); + + return $content; + } + + public function testRoomSpaces() + { + $this->createHandler('myToken', 'room name', 'Monolog', false, 'hipchat.foo.bar', 'v2'); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/POST \/v2\/room\/room%20name\/notification\?auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); + + return $content; + } + + /** + * @depends testWriteHeader + */ + public function testWriteContent($content) + { + $this->assertRegexp('/notify=0&message=test1&message_format=text&color=red&room_id=room1&from=Monolog$/', $content); + } + + /** + * @depends testWriteCustomHostHeader + */ + public function testWriteContentNotify($content) + { + $this->assertRegexp('/notify=1&message=test1&message_format=text&color=red&room_id=room1&from=Monolog$/', $content); + } + + /** + * @depends testWriteV2 + */ + public function testWriteContentV2($content) + { + $this->assertRegexp('/notify=false&message=test1&message_format=text&color=red$/', $content); + } + + /** + * @depends testWriteV2Notify + */ + public function testWriteContentV2Notify($content) + { + $this->assertRegexp('/notify=true&message=test1&message_format=text&color=red$/', $content); + } + + public function testWriteWithComplexMessage() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content); + } + + /** + * @dataProvider provideLevelColors + */ + public function testWriteWithErrorLevelsAndColors($level, $expectedColor) + { + $this->createHandler(); + $this->handler->handle($this->getRecord($level, 'Backup of database "example" finished in 16 minutes.')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/color='.$expectedColor.'/', $content); + } + + public function provideLevelColors() + { + return array( + array(Logger::DEBUG, 'gray'), + array(Logger::INFO, 'green'), + array(Logger::WARNING, 'yellow'), + array(Logger::ERROR, 'red'), + array(Logger::CRITICAL, 'red'), + array(Logger::ALERT, 'red'), + array(Logger::EMERGENCY,'red'), + array(Logger::NOTICE, 'green'), + ); + } + + /** + * @dataProvider provideBatchRecords + */ + public function testHandleBatch($records, $expectedColor) + { + $this->createHandler(); + + $this->handler->handleBatch($records); + + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/color='.$expectedColor.'/', $content); + } + + public function provideBatchRecords() + { + return array( + array( + array( + array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()), + array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()), + array('level' => Logger::CRITICAL, 'message' => 'Everything is broken!', 'level_name' => 'critical', 'datetime' => new \DateTime()) + ), + 'red', + ), + array( + array( + array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()), + array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()), + ), + 'yellow', + ), + array( + array( + array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()), + array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()), + ), + 'green', + ), + array( + array( + array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()), + ), + 'gray', + ), + ); + } + + private function createHandler($token = 'myToken', $room = 'room1', $name = 'Monolog', $notify = false, $host = 'api.hipchat.com', $version = 'v1') + { + $constructorArgs = array($token, $room, $name, $notify, Logger::DEBUG, true, true, 'text', $host, $version); + $this->res = fopen('php://memory', 'a'); + $this->handler = $this->getMock( + '\Monolog\Handler\HipChatHandler', + array('fsockopen', 'streamSetTimeout', 'closeSocket'), + $constructorArgs + ); + + $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->handler, 'localhost:1234'); + + $this->handler->expects($this->any()) + ->method('fsockopen') + ->will($this->returnValue($this->res)); + $this->handler->expects($this->any()) + ->method('streamSetTimeout') + ->will($this->returnValue(true)); + $this->handler->expects($this->any()) + ->method('closeSocket') + ->will($this->returnValue(true)); + + $this->handler->setFormatter($this->getIdentityFormatter()); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testCreateWithTooLongName() + { + $hipChatHandler = new HipChatHandler('token', 'room', 'SixteenCharsHere'); + } + + public function testCreateWithTooLongNameV2() + { + // creating a handler with too long of a name but using the v2 api doesn't matter. + $hipChatHandler = new HipChatHandler('token', 'room', 'SixteenCharsHere', false, Logger::CRITICAL, true, true, 'test', 'api.hipchat.com', 'v2'); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php new file mode 100644 index 0000000..7af60be --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @author Robert Kaufmann III + */ +class LogEntriesHandlerTest extends TestCase +{ + /** + * @var resource + */ + private $res; + + /** + * @var LogEntriesHandler + */ + private $handler; + + public function testWriteContent() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Critical write test')); + + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] test.CRITICAL: Critical write test/', $content); + } + + public function testWriteBatchContent() + { + $records = array( + $this->getRecord(), + $this->getRecord(), + $this->getRecord() + ); + $this->createHandler(); + $this->handler->handleBatch($records); + + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/(testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] .* \[\] \[\]\n){3}/', $content); + } + + private function createHandler() + { + $useSSL = extension_loaded('openssl'); + $args = array('testToken', $useSSL, Logger::DEBUG, true); + $this->res = fopen('php://memory', 'a'); + $this->handler = $this->getMock( + '\Monolog\Handler\LogEntriesHandler', + array('fsockopen', 'streamSetTimeout', 'closeSocket'), + $args + ); + + $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->handler, 'localhost:1234'); + + $this->handler->expects($this->any()) + ->method('fsockopen') + ->will($this->returnValue($this->res)); + $this->handler->expects($this->any()) + ->method('streamSetTimeout') + ->will($this->returnValue(true)); + $this->handler->expects($this->any()) + ->method('closeSocket') + ->will($this->returnValue(true)); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php new file mode 100644 index 0000000..6754f3d --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\TestCase; + +class MailHandlerTest extends TestCase +{ + /** + * @covers Monolog\Handler\MailHandler::handleBatch + */ + public function testHandleBatch() + { + $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface'); + $formatter->expects($this->once()) + ->method('formatBatch'); // Each record is formatted + + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + $handler->expects($this->once()) + ->method('send'); + $handler->expects($this->never()) + ->method('write'); // write is for individual records + + $handler->setFormatter($formatter); + + $handler->handleBatch($this->getMultipleRecords()); + } + + /** + * @covers Monolog\Handler\MailHandler::handleBatch + */ + public function testHandleBatchNotSendsMailIfMessagesAreBelowLevel() + { + $records = array( + $this->getRecord(Logger::DEBUG, 'debug message 1'), + $this->getRecord(Logger::DEBUG, 'debug message 2'), + $this->getRecord(Logger::INFO, 'information'), + ); + + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + $handler->expects($this->never()) + ->method('send'); + $handler->setLevel(Logger::ERROR); + + $handler->handleBatch($records); + } + + /** + * @covers Monolog\Handler\MailHandler::write + */ + public function testHandle() + { + $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler'); + + $record = $this->getRecord(); + $records = array($record); + $records[0]['formatted'] = '['.$record['datetime']->format('Y-m-d H:i:s').'] test.WARNING: test [] []'."\n"; + + $handler->expects($this->once()) + ->method('send') + ->with($records[0]['formatted'], $records); + + $handler->handle($record); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php b/vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php new file mode 100644 index 0000000..a083322 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Raven_Client; + +class MockRavenClient extends Raven_Client +{ + public function capture($data, $stack, $vars = null) + { + $data = array_merge($this->get_user_data(), $data); + $this->lastData = $data; + $this->lastStack = $stack; + } + + public $lastData; + public $lastStack; +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php new file mode 100644 index 0000000..0fdef63 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +class MongoDBHandlerTest extends TestCase +{ + /** + * @expectedException InvalidArgumentException + */ + public function testConstructorShouldThrowExceptionForInvalidMongo() + { + new MongoDBHandler(new \stdClass(), 'DB', 'Collection'); + } + + public function testHandle() + { + $mongo = $this->getMock('Mongo', array('selectCollection'), array(), '', false); + $collection = $this->getMock('stdClass', array('save')); + + $mongo->expects($this->once()) + ->method('selectCollection') + ->with('DB', 'Collection') + ->will($this->returnValue($collection)); + + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $expected = array( + 'message' => 'test', + 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34), + 'level' => Logger::WARNING, + 'level_name' => 'WARNING', + 'channel' => 'test', + 'datetime' => $record['datetime']->format('Y-m-d H:i:s'), + 'extra' => array(), + ); + + $collection->expects($this->once()) + ->method('save') + ->with($expected); + + $handler = new MongoDBHandler($mongo, 'DB', 'Collection'); + $handler->handle($record); + } +} + +if (!class_exists('Mongo')) { + class Mongo + { + public function selectCollection() + { + } + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php new file mode 100644 index 0000000..c2553ee --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; + +class NativeMailerHandlerTest extends TestCase +{ + /** + * @expectedException InvalidArgumentException + */ + public function testConstructorHeaderInjection() + { + $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', "receiver@example.org\r\nFrom: faked@attacker.org"); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testSetterHeaderInjection() + { + $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org'); + $mailer->addHeader("Content-Type: text/html\r\nFrom: faked@attacker.org"); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testSetterArrayHeaderInjection() + { + $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org'); + $mailer->addHeader(array("Content-Type: text/html\r\nFrom: faked@attacker.org")); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testSetterContentTypeInjection() + { + $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org'); + $mailer->setContentType("text/html\r\nFrom: faked@attacker.org"); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testSetterEncodingInjection() + { + $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org'); + $mailer->setEncoding("utf-8\r\nFrom: faked@attacker.org"); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php new file mode 100644 index 0000000..4eda615 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php @@ -0,0 +1,192 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +class NewRelicHandlerTest extends TestCase +{ + public static $appname; + public static $customParameters; + public static $transactionName; + + public function setUp() + { + self::$appname = null; + self::$customParameters = array(); + self::$transactionName = null; + } + + /** + * @expectedException Monolog\Handler\MissingExtensionException + */ + public function testThehandlerThrowsAnExceptionIfTheNRExtensionIsNotLoaded() + { + $handler = new StubNewRelicHandlerWithoutExtension(); + $handler->handle($this->getRecord(Logger::ERROR)); + } + + public function testThehandlerCanHandleTheRecord() + { + $handler = new StubNewRelicHandler(); + $handler->handle($this->getRecord(Logger::ERROR)); + } + + public function testThehandlerCanAddContextParamsToTheNewRelicTrace() + { + $handler = new StubNewRelicHandler(); + $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('a' => 'b'))); + $this->assertEquals(array('context_a' => 'b'), self::$customParameters); + } + + public function testThehandlerCanAddExplodedContextParamsToTheNewRelicTrace() + { + $handler = new StubNewRelicHandler(Logger::ERROR, true, self::$appname, true); + $handler->handle($this->getRecord( + Logger::ERROR, + 'log message', + array('a' => array('key1' => 'value1', 'key2' => 'value2')) + )); + $this->assertEquals( + array('context_a_key1' => 'value1', 'context_a_key2' => 'value2'), + self::$customParameters + ); + } + + public function testThehandlerCanAddExtraParamsToTheNewRelicTrace() + { + $record = $this->getRecord(Logger::ERROR, 'log message'); + $record['extra'] = array('c' => 'd'); + + $handler = new StubNewRelicHandler(); + $handler->handle($record); + + $this->assertEquals(array('extra_c' => 'd'), self::$customParameters); + } + + public function testThehandlerCanAddExplodedExtraParamsToTheNewRelicTrace() + { + $record = $this->getRecord(Logger::ERROR, 'log message'); + $record['extra'] = array('c' => array('key1' => 'value1', 'key2' => 'value2')); + + $handler = new StubNewRelicHandler(Logger::ERROR, true, self::$appname, true); + $handler->handle($record); + + $this->assertEquals( + array('extra_c_key1' => 'value1', 'extra_c_key2' => 'value2'), + self::$customParameters + ); + } + + public function testThehandlerCanAddExtraContextAndParamsToTheNewRelicTrace() + { + $record = $this->getRecord(Logger::ERROR, 'log message', array('a' => 'b')); + $record['extra'] = array('c' => 'd'); + + $handler = new StubNewRelicHandler(); + $handler->handle($record); + + $expected = array( + 'context_a' => 'b', + 'extra_c' => 'd', + ); + + $this->assertEquals($expected, self::$customParameters); + } + + public function testTheAppNameIsNullByDefault() + { + $handler = new StubNewRelicHandler(); + $handler->handle($this->getRecord(Logger::ERROR, 'log message')); + + $this->assertEquals(null, self::$appname); + } + + public function testTheAppNameCanBeInjectedFromtheConstructor() + { + $handler = new StubNewRelicHandler(Logger::DEBUG, false, 'myAppName'); + $handler->handle($this->getRecord(Logger::ERROR, 'log message')); + + $this->assertEquals('myAppName', self::$appname); + } + + public function testTheAppNameCanBeOverriddenFromEachLog() + { + $handler = new StubNewRelicHandler(Logger::DEBUG, false, 'myAppName'); + $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('appname' => 'logAppName'))); + + $this->assertEquals('logAppName', self::$appname); + } + + public function testTheTransactionNameIsNullByDefault() + { + $handler = new StubNewRelicHandler(); + $handler->handle($this->getRecord(Logger::ERROR, 'log message')); + + $this->assertEquals(null, self::$transactionName); + } + + public function testTheTransactionNameCanBeInjectedFromTheConstructor() + { + $handler = new StubNewRelicHandler(Logger::DEBUG, false, null, false, 'myTransaction'); + $handler->handle($this->getRecord(Logger::ERROR, 'log message')); + + $this->assertEquals('myTransaction', self::$transactionName); + } + + public function testTheTransactionNameCanBeOverriddenFromEachLog() + { + $handler = new StubNewRelicHandler(Logger::DEBUG, false, null, false, 'myTransaction'); + $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('transaction_name' => 'logTransactName'))); + + $this->assertEquals('logTransactName', self::$transactionName); + } +} + +class StubNewRelicHandlerWithoutExtension extends NewRelicHandler +{ + protected function isNewRelicEnabled() + { + return false; + } +} + +class StubNewRelicHandler extends NewRelicHandler +{ + protected function isNewRelicEnabled() + { + return true; + } +} + +function newrelic_notice_error() +{ + return true; +} + +function newrelic_set_appname($appname) +{ + return NewRelicHandlerTest::$appname = $appname; +} + +function newrelic_name_transaction($transactionName) +{ + return NewRelicHandlerTest::$transactionName = $transactionName; +} + +function newrelic_add_custom_parameter($key, $value) +{ + NewRelicHandlerTest::$customParameters[$key] = $value; + + return true; +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php new file mode 100644 index 0000000..292df78 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @covers Monolog\Handler\NullHandler::handle + */ +class NullHandlerTest extends TestCase +{ + public function testHandle() + { + $handler = new NullHandler(); + $this->assertTrue($handler->handle($this->getRecord())); + } + + public function testHandleLowerLevelRecord() + { + $handler = new NullHandler(Logger::WARNING); + $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG))); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php new file mode 100644 index 0000000..ee95172 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php @@ -0,0 +1,274 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Exception; +use Monolog\ErrorHandler; +use Monolog\Logger; +use Monolog\TestCase; +use PhpConsole\Connector; +use PhpConsole\Dispatcher\Debug as DebugDispatcher; +use PhpConsole\Dispatcher\Errors as ErrorDispatcher; +use PhpConsole\Handler; +use PHPUnit_Framework_MockObject_MockObject; + +/** + * @covers Monolog\Handler\PHPConsoleHandler + * @author Sergey Barbushin https://www.linkedin.com/in/barbushin + */ +class PHPConsoleHandlerTest extends TestCase +{ + + /** @var Connector|PHPUnit_Framework_MockObject_MockObject */ + protected $connector; + /** @var DebugDispatcher|PHPUnit_Framework_MockObject_MockObject */ + protected $debugDispatcher; + /** @var ErrorDispatcher|PHPUnit_Framework_MockObject_MockObject */ + protected $errorDispatcher; + + protected function setUp() + { + if (!class_exists('PhpConsole\Connector')) { + $this->markTestSkipped('PHP Console library not found. See https://github.com/barbushin/php-console#installation'); + } + $this->connector = $this->initConnectorMock(); + + $this->debugDispatcher = $this->initDebugDispatcherMock($this->connector); + $this->connector->setDebugDispatcher($this->debugDispatcher); + + $this->errorDispatcher = $this->initErrorDispatcherMock($this->connector); + $this->connector->setErrorsDispatcher($this->errorDispatcher); + } + + protected function initDebugDispatcherMock(Connector $connector) + { + return $this->getMockBuilder('PhpConsole\Dispatcher\Debug') + ->disableOriginalConstructor() + ->setMethods(array('dispatchDebug')) + ->setConstructorArgs(array($connector, $connector->getDumper())) + ->getMock(); + } + + protected function initErrorDispatcherMock(Connector $connector) + { + return $this->getMockBuilder('PhpConsole\Dispatcher\Errors') + ->disableOriginalConstructor() + ->setMethods(array('dispatchError', 'dispatchException')) + ->setConstructorArgs(array($connector, $connector->getDumper())) + ->getMock(); + } + + protected function initConnectorMock() + { + $connector = $this->getMockBuilder('PhpConsole\Connector') + ->disableOriginalConstructor() + ->setMethods(array( + 'sendMessage', + 'onShutDown', + 'isActiveClient', + 'setSourcesBasePath', + 'setServerEncoding', + 'setPassword', + 'enableSslOnlyMode', + 'setAllowedIpMasks', + 'setHeadersLimit', + 'startEvalRequestsListener', + )) + ->getMock(); + + $connector->expects($this->any()) + ->method('isActiveClient') + ->will($this->returnValue(true)); + + return $connector; + } + + protected function getHandlerDefaultOption($name) + { + $handler = new PHPConsoleHandler(array(), $this->connector); + $options = $handler->getOptions(); + + return $options[$name]; + } + + protected function initLogger($handlerOptions = array(), $level = Logger::DEBUG) + { + return new Logger('test', array( + new PHPConsoleHandler($handlerOptions, $this->connector, $level) + )); + } + + public function testInitWithDefaultConnector() + { + $handler = new PHPConsoleHandler(); + $this->assertEquals(spl_object_hash(Connector::getInstance()), spl_object_hash($handler->getConnector())); + } + + public function testInitWithCustomConnector() + { + $handler = new PHPConsoleHandler(array(), $this->connector); + $this->assertEquals(spl_object_hash($this->connector), spl_object_hash($handler->getConnector())); + } + + public function testDebug() + { + $this->debugDispatcher->expects($this->once())->method('dispatchDebug')->with($this->equalTo('test')); + $this->initLogger()->addDebug('test'); + } + + public function testDebugContextInMessage() + { + $message = 'test'; + $tag = 'tag'; + $context = array($tag, 'custom' => mt_rand()); + $expectedMessage = $message . ' ' . json_encode(array_slice($context, 1)); + $this->debugDispatcher->expects($this->once())->method('dispatchDebug')->with( + $this->equalTo($expectedMessage), + $this->equalTo($tag) + ); + $this->initLogger()->addDebug($message, $context); + } + + public function testDebugTags($tagsContextKeys = null) + { + $expectedTags = mt_rand(); + $logger = $this->initLogger($tagsContextKeys ? array('debugTagsKeysInContext' => $tagsContextKeys) : array()); + if (!$tagsContextKeys) { + $tagsContextKeys = $this->getHandlerDefaultOption('debugTagsKeysInContext'); + } + foreach ($tagsContextKeys as $key) { + $debugDispatcher = $this->initDebugDispatcherMock($this->connector); + $debugDispatcher->expects($this->once())->method('dispatchDebug')->with( + $this->anything(), + $this->equalTo($expectedTags) + ); + $this->connector->setDebugDispatcher($debugDispatcher); + $logger->addDebug('test', array($key => $expectedTags)); + } + } + + public function testError($classesPartialsTraceIgnore = null) + { + $code = E_USER_NOTICE; + $message = 'message'; + $file = __FILE__; + $line = __LINE__; + $this->errorDispatcher->expects($this->once())->method('dispatchError')->with( + $this->equalTo($code), + $this->equalTo($message), + $this->equalTo($file), + $this->equalTo($line), + $classesPartialsTraceIgnore ?: $this->equalTo($this->getHandlerDefaultOption('classesPartialsTraceIgnore')) + ); + $errorHandler = ErrorHandler::register($this->initLogger($classesPartialsTraceIgnore ? array('classesPartialsTraceIgnore' => $classesPartialsTraceIgnore) : array()), false); + $errorHandler->registerErrorHandler(array(), false, E_USER_WARNING); + $errorHandler->handleError($code, $message, $file, $line); + } + + public function testException() + { + $e = new Exception(); + $this->errorDispatcher->expects($this->once())->method('dispatchException')->with( + $this->equalTo($e) + ); + $handler = $this->initLogger(); + $handler->log( + \Psr\Log\LogLevel::ERROR, + sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), + array('exception' => $e) + ); + } + + /** + * @expectedException Exception + */ + public function testWrongOptionsThrowsException() + { + new PHPConsoleHandler(array('xxx' => 1)); + } + + public function testOptionEnabled() + { + $this->debugDispatcher->expects($this->never())->method('dispatchDebug'); + $this->initLogger(array('enabled' => false))->addDebug('test'); + } + + public function testOptionClassesPartialsTraceIgnore() + { + $this->testError(array('Class', 'Namespace\\')); + } + + public function testOptionDebugTagsKeysInContext() + { + $this->testDebugTags(array('key1', 'key2')); + } + + public function testOptionUseOwnErrorsAndExceptionsHandler() + { + $this->initLogger(array('useOwnErrorsHandler' => true, 'useOwnExceptionsHandler' => true)); + $this->assertEquals(array(Handler::getInstance(), 'handleError'), set_error_handler(function () { + })); + $this->assertEquals(array(Handler::getInstance(), 'handleException'), set_exception_handler(function () { + })); + } + + public static function provideConnectorMethodsOptionsSets() + { + return array( + array('sourcesBasePath', 'setSourcesBasePath', __DIR__), + array('serverEncoding', 'setServerEncoding', 'cp1251'), + array('password', 'setPassword', '******'), + array('enableSslOnlyMode', 'enableSslOnlyMode', true, false), + array('ipMasks', 'setAllowedIpMasks', array('127.0.0.*')), + array('headersLimit', 'setHeadersLimit', 2500), + array('enableEvalListener', 'startEvalRequestsListener', true, false), + ); + } + + /** + * @dataProvider provideConnectorMethodsOptionsSets + */ + public function testOptionCallsConnectorMethod($option, $method, $value, $isArgument = true) + { + $expectCall = $this->connector->expects($this->once())->method($method); + if ($isArgument) { + $expectCall->with($value); + } + new PHPConsoleHandler(array($option => $value), $this->connector); + } + + public function testOptionDetectDumpTraceAndSource() + { + new PHPConsoleHandler(array('detectDumpTraceAndSource' => true), $this->connector); + $this->assertTrue($this->connector->getDebugDispatcher()->detectTraceAndSource); + } + + public static function provideDumperOptionsValues() + { + return array( + array('dumperLevelLimit', 'levelLimit', 1001), + array('dumperItemsCountLimit', 'itemsCountLimit', 1002), + array('dumperItemSizeLimit', 'itemSizeLimit', 1003), + array('dumperDumpSizeLimit', 'dumpSizeLimit', 1004), + array('dumperDetectCallbacks', 'detectCallbacks', true), + ); + } + + /** + * @dataProvider provideDumperOptionsValues + */ + public function testDumperOptions($option, $dumperProperty, $value) + { + new PHPConsoleHandler(array($option => $value), $this->connector); + $this->assertEquals($value, $this->connector->getDumper()->$dumperProperty); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php new file mode 100644 index 0000000..64eaab1 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @covers Monolog\Handler\PsrHandler::handle + */ +class PsrHandlerTest extends TestCase +{ + public function logLevelProvider() + { + $levels = array(); + $monologLogger = new Logger(''); + + foreach ($monologLogger->getLevels() as $levelName => $level) { + $levels[] = array($levelName, $level); + } + + return $levels; + } + + /** + * @dataProvider logLevelProvider + */ + public function testHandlesAllLevels($levelName, $level) + { + $message = 'Hello, world! ' . $level; + $context = array('foo' => 'bar', 'level' => $level); + + $psrLogger = $this->getMock('Psr\Log\NullLogger'); + $psrLogger->expects($this->once()) + ->method('log') + ->with(strtolower($levelName), $message, $context); + + $handler = new PsrHandler($psrLogger); + $handler->handle(array('level' => $level, 'level_name' => $levelName, 'message' => $message, 'context' => $context)); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php new file mode 100644 index 0000000..8940823 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php @@ -0,0 +1,141 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * Almost all examples (expected header, titles, messages) taken from + * https://www.pushover.net/api + * @author Sebastian Göttschkes + * @see https://www.pushover.net/api + */ +class PushoverHandlerTest extends TestCase +{ + private $res; + private $handler; + + public function testWriteHeader() + { + $this->createHandler(); + $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/POST \/1\/messages.json HTTP\/1.1\\r\\nHost: api.pushover.net\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); + + return $content; + } + + /** + * @depends testWriteHeader + */ + public function testWriteContent($content) + { + $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog×tamp=\d{10}$/', $content); + } + + public function testWriteWithComplexTitle() + { + $this->createHandler('myToken', 'myUser', 'Backup finished - SQL1', Logger::EMERGENCY); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/title=Backup\+finished\+-\+SQL1/', $content); + } + + public function testWriteWithComplexMessage() + { + $this->createHandler(); + $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content); + } + + public function testWriteWithTooLongMessage() + { + $message = str_pad('test', 520, 'a'); + $this->createHandler(); + $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications + $this->handler->handle($this->getRecord(Logger::CRITICAL, $message)); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $expectedMessage = substr($message, 0, 505); + + $this->assertRegexp('/message=' . $expectedMessage . '&title/', $content); + } + + public function testWriteWithHighPriority() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog×tamp=\d{10}&priority=1$/', $content); + } + + public function testWriteWithEmergencyPriority() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog×tamp=\d{10}&priority=2&retry=30&expire=25200$/', $content); + } + + public function testWriteToMultipleUsers() + { + $this->createHandler('myToken', array('userA', 'userB')); + $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/token=myToken&user=userA&message=test1&title=Monolog×tamp=\d{10}&priority=2&retry=30&expire=25200POST/', $content); + $this->assertRegexp('/token=myToken&user=userB&message=test1&title=Monolog×tamp=\d{10}&priority=2&retry=30&expire=25200$/', $content); + } + + private function createHandler($token = 'myToken', $user = 'myUser', $title = 'Monolog') + { + $constructorArgs = array($token, $user, $title); + $this->res = fopen('php://memory', 'a'); + $this->handler = $this->getMock( + '\Monolog\Handler\PushoverHandler', + array('fsockopen', 'streamSetTimeout', 'closeSocket'), + $constructorArgs + ); + + $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->handler, 'localhost:1234'); + + $this->handler->expects($this->any()) + ->method('fsockopen') + ->will($this->returnValue($this->res)); + $this->handler->expects($this->any()) + ->method('streamSetTimeout') + ->will($this->returnValue(true)); + $this->handler->expects($this->any()) + ->method('closeSocket') + ->will($this->returnValue(true)); + + $this->handler->setFormatter($this->getIdentityFormatter()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php new file mode 100644 index 0000000..2ca5c02 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php @@ -0,0 +1,199 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +class RavenHandlerTest extends TestCase +{ + public function setUp() + { + if (!class_exists('Raven_Client')) { + $this->markTestSkipped('raven/raven not installed'); + } + + require_once __DIR__ . '/MockRavenClient.php'; + } + + /** + * @covers Monolog\Handler\RavenHandler::__construct + */ + public function testConstruct() + { + $handler = new RavenHandler($this->getRavenClient()); + $this->assertInstanceOf('Monolog\Handler\RavenHandler', $handler); + } + + protected function getHandler($ravenClient) + { + $handler = new RavenHandler($ravenClient); + + return $handler; + } + + protected function getRavenClient() + { + $dsn = 'http://43f6017361224d098402974103bfc53d:a6a0538fc2934ba2bed32e08741b2cd3@marca.python.live.cheggnet.com:9000/1'; + + return new MockRavenClient($dsn); + } + + public function testDebug() + { + $ravenClient = $this->getRavenClient(); + $handler = $this->getHandler($ravenClient); + + $record = $this->getRecord(Logger::DEBUG, 'A test debug message'); + $handler->handle($record); + + $this->assertEquals($ravenClient::DEBUG, $ravenClient->lastData['level']); + $this->assertContains($record['message'], $ravenClient->lastData['message']); + } + + public function testWarning() + { + $ravenClient = $this->getRavenClient(); + $handler = $this->getHandler($ravenClient); + + $record = $this->getRecord(Logger::WARNING, 'A test warning message'); + $handler->handle($record); + + $this->assertEquals($ravenClient::WARNING, $ravenClient->lastData['level']); + $this->assertContains($record['message'], $ravenClient->lastData['message']); + } + + public function testTag() + { + $ravenClient = $this->getRavenClient(); + $handler = $this->getHandler($ravenClient); + + $tags = array(1, 2, 'foo'); + $record = $this->getRecord(Logger::INFO, 'test', array('tags' => $tags)); + $handler->handle($record); + + $this->assertEquals($tags, $ravenClient->lastData['tags']); + } + + public function testExtraParameters() + { + $ravenClient = $this->getRavenClient(); + $handler = $this->getHandler($ravenClient); + + $checksum = '098f6bcd4621d373cade4e832627b4f6'; + $release = '05a671c66aefea124cc08b76ea6d30bb'; + $record = $this->getRecord(Logger::INFO, 'test', array('checksum' => $checksum, 'release' => $release)); + $handler->handle($record); + + $this->assertEquals($checksum, $ravenClient->lastData['checksum']); + $this->assertEquals($release, $ravenClient->lastData['release']); + } + + public function testUserContext() + { + $ravenClient = $this->getRavenClient(); + $handler = $this->getHandler($ravenClient); + + $recordWithNoContext = $this->getRecord(Logger::INFO, 'test with default user context'); + // set user context 'externally' + + $user = array( + 'id' => '123', + 'email' => 'test@test.com' + ); + + $recordWithContext = $this->getRecord(Logger::INFO, 'test', array('user' => $user)); + + $ravenClient->user_context(array('id' => 'test_user_id')); + // handle context + $handler->handle($recordWithContext); + $this->assertEquals($user, $ravenClient->lastData['user']); + + // check to see if its reset + $handler->handle($recordWithNoContext); + $this->assertInternalType('array', $ravenClient->context->user); + $this->assertSame('test_user_id', $ravenClient->context->user['id']); + + // handle with null context + $ravenClient->user_context(null); + $handler->handle($recordWithContext); + $this->assertEquals($user, $ravenClient->lastData['user']); + + // check to see if its reset + $handler->handle($recordWithNoContext); + $this->assertNull($ravenClient->context->user); + } + + public function testException() + { + $ravenClient = $this->getRavenClient(); + $handler = $this->getHandler($ravenClient); + + try { + $this->methodThatThrowsAnException(); + } catch (\Exception $e) { + $record = $this->getRecord(Logger::ERROR, $e->getMessage(), array('exception' => $e)); + $handler->handle($record); + } + + $this->assertEquals($record['message'], $ravenClient->lastData['message']); + } + + public function testHandleBatch() + { + $records = $this->getMultipleRecords(); + $records[] = $this->getRecord(Logger::WARNING, 'warning'); + $records[] = $this->getRecord(Logger::WARNING, 'warning'); + + $logFormatter = $this->getMock('Monolog\\Formatter\\FormatterInterface'); + $logFormatter->expects($this->once())->method('formatBatch'); + + $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface'); + $formatter->expects($this->once())->method('format')->with($this->callback(function ($record) { + return $record['level'] == 400; + })); + + $handler = $this->getHandler($this->getRavenClient()); + $handler->setBatchFormatter($logFormatter); + $handler->setFormatter($formatter); + $handler->handleBatch($records); + } + + public function testHandleBatchDoNothingIfRecordsAreBelowLevel() + { + $records = array( + $this->getRecord(Logger::DEBUG, 'debug message 1'), + $this->getRecord(Logger::DEBUG, 'debug message 2'), + $this->getRecord(Logger::INFO, 'information'), + ); + + $handler = $this->getMock('Monolog\Handler\RavenHandler', null, array($this->getRavenClient())); + $handler->expects($this->never())->method('handle'); + $handler->setLevel(Logger::ERROR); + $handler->handleBatch($records); + } + + public function testGetSetBatchFormatter() + { + $ravenClient = $this->getRavenClient(); + $handler = $this->getHandler($ravenClient); + + $handler->setBatchFormatter($formatter = new LineFormatter()); + $this->assertSame($formatter, $handler->getBatchFormatter()); + } + + private function methodThatThrowsAnException() + { + throw new \Exception('This is an exception'); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php new file mode 100644 index 0000000..97e0d94 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +class RedisHandlerTest extends TestCase +{ + /** + * @expectedException InvalidArgumentException + */ + public function testConstructorShouldThrowExceptionForInvalidRedis() + { + new RedisHandler(new \stdClass(), 'key'); + } + + public function testConstructorShouldWorkWithPredis() + { + $redis = $this->getMock('Predis\Client'); + $this->assertInstanceof('Monolog\Handler\RedisHandler', new RedisHandler($redis, 'key')); + } + + public function testConstructorShouldWorkWithRedis() + { + $redis = $this->getMock('Redis'); + $this->assertInstanceof('Monolog\Handler\RedisHandler', new RedisHandler($redis, 'key')); + } + + public function testPredisHandle() + { + $redis = $this->getMock('Predis\Client', array('rpush')); + + // Predis\Client uses rpush + $redis->expects($this->once()) + ->method('rpush') + ->with('key', 'test'); + + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $handler = new RedisHandler($redis, 'key'); + $handler->setFormatter(new LineFormatter("%message%")); + $handler->handle($record); + } + + public function testRedisHandle() + { + $redis = $this->getMock('Redis', array('rpush')); + + // Redis uses rPush + $redis->expects($this->once()) + ->method('rPush') + ->with('key', 'test'); + + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $handler = new RedisHandler($redis, 'key'); + $handler->setFormatter(new LineFormatter("%message%")); + $handler->handle($record); + } + + public function testRedisHandleCapped() + { + $redis = $this->getMock('Redis', array('multi', 'rpush', 'ltrim', 'execute')); + + // Redis uses multi + $redis->expects($this->once()) + ->method('multi') + ->will($this->returnSelf()); + + $redis->expects($this->once()) + ->method('rpush') + ->will($this->returnSelf()); + + $redis->expects($this->once()) + ->method('ltrim') + ->will($this->returnSelf()); + + $redis->expects($this->once()) + ->method('execute') + ->will($this->returnSelf()); + + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $handler = new RedisHandler($redis, 'key', Logger::DEBUG, true, 10); + $handler->setFormatter(new LineFormatter("%message%")); + $handler->handle($record); + } + + public function testPredisHandleCapped() + { + $redis = $this->getMock('Predis\Client', array('transaction')); + + $redisTransaction = $this->getMock('Predis\Client', array('rpush', 'ltrim')); + + $redisTransaction->expects($this->once()) + ->method('rpush') + ->will($this->returnSelf()); + + $redisTransaction->expects($this->once()) + ->method('ltrim') + ->will($this->returnSelf()); + + // Redis uses multi + $redis->expects($this->once()) + ->method('transaction') + ->will($this->returnCallback(function ($cb) use ($redisTransaction) { + $cb($redisTransaction); + })); + + $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34)); + + $handler = new RedisHandler($redis, 'key', Logger::DEBUG, true, 10); + $handler->setFormatter(new LineFormatter("%message%")); + $handler->handle($record); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php new file mode 100644 index 0000000..f4cefda --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; + +/** + * @covers Monolog\Handler\RotatingFileHandler + */ +class RotatingFileHandlerTest extends TestCase +{ + public function setUp() + { + $dir = __DIR__.'/Fixtures'; + chmod($dir, 0777); + if (!is_writable($dir)) { + $this->markTestSkipped($dir.' must be writeable to test the RotatingFileHandler.'); + } + } + + public function testRotationCreatesNewFile() + { + touch(__DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400).'.rot'); + + $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot'); + $handler->setFormatter($this->getIdentityFormatter()); + $handler->handle($this->getRecord()); + + $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot'; + $this->assertTrue(file_exists($log)); + $this->assertEquals('test', file_get_contents($log)); + } + + /** + * @dataProvider rotationTests + */ + public function testRotation($createFile) + { + touch($old1 = __DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400).'.rot'); + touch($old2 = __DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400 * 2).'.rot'); + touch($old3 = __DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400 * 3).'.rot'); + touch($old4 = __DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400 * 4).'.rot'); + + $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot'; + + if ($createFile) { + touch($log); + } + + $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2); + $handler->setFormatter($this->getIdentityFormatter()); + $handler->handle($this->getRecord()); + + $handler->close(); + + $this->assertTrue(file_exists($log)); + $this->assertTrue(file_exists($old1)); + $this->assertEquals($createFile, file_exists($old2)); + $this->assertEquals($createFile, file_exists($old3)); + $this->assertEquals($createFile, file_exists($old4)); + $this->assertEquals('test', file_get_contents($log)); + } + + public function rotationTests() + { + return array( + 'Rotation is triggered when the file of the current day is not present' + => array(true), + 'Rotation is not triggered when the file is already present' + => array(false), + ); + } + + public function testReuseCurrentFile() + { + $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot'; + file_put_contents($log, "foo"); + $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot'); + $handler->setFormatter($this->getIdentityFormatter()); + $handler->handle($this->getRecord()); + $this->assertEquals('footest', file_get_contents($log)); + } + + public function tearDown() + { + foreach (glob(__DIR__.'/Fixtures/*.rot') as $file) { + unlink($file); + } + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php new file mode 100644 index 0000000..b354cee --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; + +/** + * @covers Monolog\Handler\SamplingHandler::handle + */ +class SamplingHandlerTest extends TestCase +{ + public function testHandle() + { + $testHandler = new TestHandler(); + $handler = new SamplingHandler($testHandler, 2); + for ($i = 0; $i < 10000; $i++) { + $handler->handle($this->getRecord()); + } + $count = count($testHandler->getRecords()); + // $count should be half of 10k, so between 4k and 6k + $this->assertLessThan(6000, $count); + $this->assertGreaterThan(4000, $count); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php new file mode 100644 index 0000000..d657fae --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php @@ -0,0 +1,133 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @author Greg Kedzierski + * @see https://api.slack.com/ + */ +class SlackHandlerTest extends TestCase +{ + /** + * @var resource + */ + private $res; + + /** + * @var SlackHandler + */ + private $handler; + + public function setUp() + { + if (!extension_loaded('openssl')) { + $this->markTestSkipped('This test requires openssl to run'); + } + } + + public function testWriteHeader() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/POST \/api\/chat.postMessage HTTP\/1.1\\r\\nHost: slack.com\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content); + } + + public function testWriteContent() + { + $this->createHandler(); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/token=myToken&channel=channel1&username=Monolog&text=&attachments=.*$/', $content); + } + + public function testWriteContentWithEmoji() + { + $this->createHandler('myToken', 'channel1', 'Monolog', true, 'alien'); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/icon_emoji=%3Aalien%3A$/', $content); + } + + /** + * @dataProvider provideLevelColors + */ + public function testWriteContentWithColors($level, $expectedColor) + { + $this->createHandler(); + $this->handler->handle($this->getRecord($level, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/color%22%3A%22'.$expectedColor.'/', $content); + } + + public function testWriteContentWithPlainTextMessage() + { + $this->createHandler('myToken', 'channel1', 'Monolog', false); + $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1')); + fseek($this->res, 0); + $content = fread($this->res, 1024); + + $this->assertRegexp('/text=test1/', $content); + } + + public function provideLevelColors() + { + return array( + array(Logger::DEBUG, '%23e3e4e6'), // escaped #e3e4e6 + array(Logger::INFO, 'good'), + array(Logger::NOTICE, 'good'), + array(Logger::WARNING, 'warning'), + array(Logger::ERROR, 'danger'), + array(Logger::CRITICAL, 'danger'), + array(Logger::ALERT, 'danger'), + array(Logger::EMERGENCY,'danger'), + ); + } + + private function createHandler($token = 'myToken', $channel = 'channel1', $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $useShortAttachment = false, $includeExtra = false) + { + $constructorArgs = array($token, $channel, $username, $useAttachment, $iconEmoji, Logger::DEBUG, true, $useShortAttachment, $includeExtra); + $this->res = fopen('php://memory', 'a'); + $this->handler = $this->getMock( + '\Monolog\Handler\SlackHandler', + array('fsockopen', 'streamSetTimeout', 'closeSocket'), + $constructorArgs + ); + + $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->handler, 'localhost:1234'); + + $this->handler->expects($this->any()) + ->method('fsockopen') + ->will($this->returnValue($this->res)); + $this->handler->expects($this->any()) + ->method('streamSetTimeout') + ->will($this->returnValue(true)); + $this->handler->expects($this->any()) + ->method('closeSocket') + ->will($this->returnValue(true)); + + $this->handler->setFormatter($this->getIdentityFormatter()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php new file mode 100644 index 0000000..2e3d504 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php @@ -0,0 +1,282 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @author Pablo de Leon Belloc + */ +class SocketHandlerTest extends TestCase +{ + /** + * @var Monolog\Handler\SocketHandler + */ + private $handler; + + /** + * @var resource + */ + private $res; + + /** + * @expectedException UnexpectedValueException + */ + public function testInvalidHostname() + { + $this->createHandler('garbage://here'); + $this->writeRecord('data'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testBadConnectionTimeout() + { + $this->createHandler('localhost:1234'); + $this->handler->setConnectionTimeout(-1); + } + + public function testSetConnectionTimeout() + { + $this->createHandler('localhost:1234'); + $this->handler->setConnectionTimeout(10.1); + $this->assertEquals(10.1, $this->handler->getConnectionTimeout()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testBadTimeout() + { + $this->createHandler('localhost:1234'); + $this->handler->setTimeout(-1); + } + + public function testSetTimeout() + { + $this->createHandler('localhost:1234'); + $this->handler->setTimeout(10.25); + $this->assertEquals(10.25, $this->handler->getTimeout()); + } + + public function testSetConnectionString() + { + $this->createHandler('tcp://localhost:9090'); + $this->assertEquals('tcp://localhost:9090', $this->handler->getConnectionString()); + } + + /** + * @expectedException UnexpectedValueException + */ + public function testExceptionIsThrownOnFsockopenError() + { + $this->setMockHandler(array('fsockopen')); + $this->handler->expects($this->once()) + ->method('fsockopen') + ->will($this->returnValue(false)); + $this->writeRecord('Hello world'); + } + + /** + * @expectedException UnexpectedValueException + */ + public function testExceptionIsThrownOnPfsockopenError() + { + $this->setMockHandler(array('pfsockopen')); + $this->handler->expects($this->once()) + ->method('pfsockopen') + ->will($this->returnValue(false)); + $this->handler->setPersistent(true); + $this->writeRecord('Hello world'); + } + + /** + * @expectedException UnexpectedValueException + */ + public function testExceptionIsThrownIfCannotSetTimeout() + { + $this->setMockHandler(array('streamSetTimeout')); + $this->handler->expects($this->once()) + ->method('streamSetTimeout') + ->will($this->returnValue(false)); + $this->writeRecord('Hello world'); + } + + /** + * @expectedException RuntimeException + */ + public function testWriteFailsOnIfFwriteReturnsFalse() + { + $this->setMockHandler(array('fwrite')); + + $callback = function ($arg) { + $map = array( + 'Hello world' => 6, + 'world' => false, + ); + + return $map[$arg]; + }; + + $this->handler->expects($this->exactly(2)) + ->method('fwrite') + ->will($this->returnCallback($callback)); + + $this->writeRecord('Hello world'); + } + + /** + * @expectedException RuntimeException + */ + public function testWriteFailsIfStreamTimesOut() + { + $this->setMockHandler(array('fwrite', 'streamGetMetadata')); + + $callback = function ($arg) { + $map = array( + 'Hello world' => 6, + 'world' => 5, + ); + + return $map[$arg]; + }; + + $this->handler->expects($this->exactly(1)) + ->method('fwrite') + ->will($this->returnCallback($callback)); + $this->handler->expects($this->exactly(1)) + ->method('streamGetMetadata') + ->will($this->returnValue(array('timed_out' => true))); + + $this->writeRecord('Hello world'); + } + + /** + * @expectedException RuntimeException + */ + public function testWriteFailsOnIncompleteWrite() + { + $this->setMockHandler(array('fwrite', 'streamGetMetadata')); + + $res = $this->res; + $callback = function ($string) use ($res) { + fclose($res); + + return strlen('Hello'); + }; + + $this->handler->expects($this->exactly(1)) + ->method('fwrite') + ->will($this->returnCallback($callback)); + $this->handler->expects($this->exactly(1)) + ->method('streamGetMetadata') + ->will($this->returnValue(array('timed_out' => false))); + + $this->writeRecord('Hello world'); + } + + public function testWriteWithMemoryFile() + { + $this->setMockHandler(); + $this->writeRecord('test1'); + $this->writeRecord('test2'); + $this->writeRecord('test3'); + fseek($this->res, 0); + $this->assertEquals('test1test2test3', fread($this->res, 1024)); + } + + public function testWriteWithMock() + { + $this->setMockHandler(array('fwrite')); + + $callback = function ($arg) { + $map = array( + 'Hello world' => 6, + 'world' => 5, + ); + + return $map[$arg]; + }; + + $this->handler->expects($this->exactly(2)) + ->method('fwrite') + ->will($this->returnCallback($callback)); + + $this->writeRecord('Hello world'); + } + + public function testClose() + { + $this->setMockHandler(); + $this->writeRecord('Hello world'); + $this->assertInternalType('resource', $this->res); + $this->handler->close(); + $this->assertFalse(is_resource($this->res), "Expected resource to be closed after closing handler"); + } + + public function testCloseDoesNotClosePersistentSocket() + { + $this->setMockHandler(); + $this->handler->setPersistent(true); + $this->writeRecord('Hello world'); + $this->assertTrue(is_resource($this->res)); + $this->handler->close(); + $this->assertTrue(is_resource($this->res)); + } + + private function createHandler($connectionString) + { + $this->handler = new SocketHandler($connectionString); + $this->handler->setFormatter($this->getIdentityFormatter()); + } + + private function writeRecord($string) + { + $this->handler->handle($this->getRecord(Logger::WARNING, $string)); + } + + private function setMockHandler(array $methods = array()) + { + $this->res = fopen('php://memory', 'a'); + + $defaultMethods = array('fsockopen', 'pfsockopen', 'streamSetTimeout'); + $newMethods = array_diff($methods, $defaultMethods); + + $finalMethods = array_merge($defaultMethods, $newMethods); + + $this->handler = $this->getMock( + '\Monolog\Handler\SocketHandler', $finalMethods, array('localhost:1234') + ); + + if (!in_array('fsockopen', $methods)) { + $this->handler->expects($this->any()) + ->method('fsockopen') + ->will($this->returnValue($this->res)); + } + + if (!in_array('pfsockopen', $methods)) { + $this->handler->expects($this->any()) + ->method('pfsockopen') + ->will($this->returnValue($this->res)); + } + + if (!in_array('streamSetTimeout', $methods)) { + $this->handler->expects($this->any()) + ->method('streamSetTimeout') + ->will($this->returnValue(true)); + } + + $this->handler->setFormatter($this->getIdentityFormatter()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php new file mode 100644 index 0000000..b1e22fb --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php @@ -0,0 +1,168 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +class StreamHandlerTest extends TestCase +{ + /** + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWrite() + { + $handle = fopen('php://memory', 'a+'); + $handler = new StreamHandler($handle); + $handler->setFormatter($this->getIdentityFormatter()); + $handler->handle($this->getRecord(Logger::WARNING, 'test')); + $handler->handle($this->getRecord(Logger::WARNING, 'test2')); + $handler->handle($this->getRecord(Logger::WARNING, 'test3')); + fseek($handle, 0); + $this->assertEquals('testtest2test3', fread($handle, 100)); + } + + /** + * @covers Monolog\Handler\StreamHandler::close + */ + public function testClose() + { + $handle = fopen('php://memory', 'a+'); + $handler = new StreamHandler($handle); + $this->assertTrue(is_resource($handle)); + $handler->close(); + $this->assertFalse(is_resource($handle)); + } + + /** + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteCreatesTheStreamResource() + { + $handler = new StreamHandler('php://memory'); + $handler->handle($this->getRecord()); + } + + /** + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteLocking() + { + $temp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'monolog_locked_log'; + $handler = new StreamHandler($temp, Logger::DEBUG, true, null, true); + $handler->handle($this->getRecord()); + } + + /** + * @expectedException LogicException + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteMissingResource() + { + $handler = new StreamHandler(null); + $handler->handle($this->getRecord()); + } + + public function invalidArgumentProvider() + { + return array( + array(1), + array(array()), + array(array('bogus://url')), + ); + } + + /** + * @dataProvider invalidArgumentProvider + * @expectedException InvalidArgumentException + * @covers Monolog\Handler\StreamHandler::__construct + */ + public function testWriteInvalidArgument($invalidArgument) + { + $handler = new StreamHandler($invalidArgument); + } + + /** + * @expectedException UnexpectedValueException + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteInvalidResource() + { + $handler = new StreamHandler('bogus://url'); + $handler->handle($this->getRecord()); + } + + /** + * @expectedException UnexpectedValueException + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteNonExistingResource() + { + $handler = new StreamHandler('ftp://foo/bar/baz/'.rand(0, 10000)); + $handler->handle($this->getRecord()); + } + + /** + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteNonExistingPath() + { + $handler = new StreamHandler(sys_get_temp_dir().'/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000)); + $handler->handle($this->getRecord()); + } + + /** + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteNonExistingFileResource() + { + $handler = new StreamHandler('file://'.sys_get_temp_dir().'/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000)); + $handler->handle($this->getRecord()); + } + + /** + * @expectedException Exception + * @expectedExceptionMessageRegExp /There is no existing directory at/ + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteNonExistingAndNotCreatablePath() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Permissions checks can not run on windows'); + } + $handler = new StreamHandler('/foo/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000)); + $handler->handle($this->getRecord()); + } + + /** + * @expectedException Exception + * @expectedExceptionMessageRegExp /There is no existing directory at/ + * @covers Monolog\Handler\StreamHandler::__construct + * @covers Monolog\Handler\StreamHandler::write + */ + public function testWriteNonExistingAndNotCreatableFileResource() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Permissions checks can not run on windows'); + } + $handler = new StreamHandler('file:///foo/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000)); + $handler->handle($this->getRecord()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php new file mode 100644 index 0000000..55e69c2 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php @@ -0,0 +1,79 @@ +mailer = $this + ->getMockBuilder('Swift_Mailer') + ->disableOriginalConstructor() + ->getMock(); + } + + public function testMessageCreationIsLazyWhenUsingCallback() + { + $this->mailer->expects($this->never()) + ->method('send'); + + $callback = function () { + throw new \RuntimeException('Swift_Message creation callback should not have been called in this test'); + }; + $handler = new SwiftMailerHandler($this->mailer, $callback); + + $records = array( + $this->getRecord(Logger::DEBUG), + $this->getRecord(Logger::INFO), + ); + $handler->handleBatch($records); + } + + public function testMessageCanBeCustomizedGivenLoggedData() + { + // Wire Mailer to expect a specific Swift_Message with a customized Subject + $expectedMessage = new \Swift_Message(); + $this->mailer->expects($this->once()) + ->method('send') + ->with($this->callback(function ($value) use ($expectedMessage) { + return $value instanceof \Swift_Message + && $value->getSubject() === 'Emergency' + && $value === $expectedMessage; + })); + + // Callback dynamically changes subject based on number of logged records + $callback = function ($content, array $records) use ($expectedMessage) { + $subject = count($records) > 0 ? 'Emergency' : 'Normal'; + $expectedMessage->setSubject($subject); + + return $expectedMessage; + }; + $handler = new SwiftMailerHandler($this->mailer, $callback); + + // Logging 1 record makes this an Emergency + $records = array( + $this->getRecord(Logger::EMERGENCY), + ); + $handler->handleBatch($records); + } + + public function testMessageHaveUniqueId() { + $messageTemplate = \Swift_Message::newInstance(); + $handler = new SwiftMailerHandler($this->mailer, $messageTemplate); + + $method = new \ReflectionMethod('Monolog\Handler\SwiftMailerHandler', 'buildMessage'); + $method->setAccessible(true); + $method->invokeArgs($handler, array($messageTemplate, array())); + + $builtMessage1 = $method->invoke($handler, $messageTemplate, array()); + $builtMessage2 = $method->invoke($handler, $messageTemplate, array()); + + $this->assertFalse($builtMessage1->getId() === $builtMessage2->getId(), 'Two different messages have the same id'); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php new file mode 100644 index 0000000..8f9e46b --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +class SyslogHandlerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Monolog\Handler\SyslogHandler::__construct + */ + public function testConstruct() + { + $handler = new SyslogHandler('test'); + $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler); + + $handler = new SyslogHandler('test', LOG_USER); + $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler); + + $handler = new SyslogHandler('test', 'user'); + $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler); + + $handler = new SyslogHandler('test', LOG_USER, Logger::DEBUG, true, LOG_PERROR); + $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler); + } + + /** + * @covers Monolog\Handler\SyslogHandler::__construct + */ + public function testConstructInvalidFacility() + { + $this->setExpectedException('UnexpectedValueException'); + $handler = new SyslogHandler('test', 'unknown'); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php new file mode 100644 index 0000000..497812b --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +/** + * @requires extension sockets + */ +class SyslogUdpHandlerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException UnexpectedValueException + */ + public function testWeValidateFacilities() + { + $handler = new SyslogUdpHandler("ip", null, "invalidFacility"); + } + + public function testWeSplitIntoLines() + { + $handler = new SyslogUdpHandler("127.0.0.1", 514, "authpriv"); + $handler->setFormatter(new \Monolog\Formatter\ChromePHPFormatter()); + + $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('write'), array('lol', 'lol')); + $socket->expects($this->at(0)) + ->method('write') + ->with("lol", "<".(LOG_AUTHPRIV + LOG_WARNING).">1 "); + $socket->expects($this->at(1)) + ->method('write') + ->with("hej", "<".(LOG_AUTHPRIV + LOG_WARNING).">1 "); + + $handler->setSocket($socket); + + $handler->handle($this->getRecordWithMessage("hej\nlol")); + } + + protected function getRecordWithMessage($msg) + { + return array('message' => $msg, 'level' => \Monolog\Logger::WARNING, 'context' => null, 'extra' => array(), 'channel' => 'lol'); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php new file mode 100644 index 0000000..75cc4a8 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +/** + * @covers Monolog\Handler\TestHandler + */ +class TestHandlerTest extends TestCase +{ + /** + * @dataProvider methodProvider + */ + public function testHandler($method, $level) + { + $handler = new TestHandler; + $record = $this->getRecord($level, 'test'.$method); + $this->assertFalse($handler->{'has'.$method}($record), 'has'.$method); + $this->assertFalse($handler->{'has'.$method.'ThatContains'}('test'), 'has'.$method.'ThatContains'); + $this->assertFalse($handler->{'has'.$method.'ThatPasses'}(function ($rec) { + return true; + }), 'has'.$method.'ThatPasses'); + $this->assertFalse($handler->{'has'.$method.'ThatMatches'}('/test\w+/')); + $this->assertFalse($handler->{'has'.$method.'Records'}(), 'has'.$method.'Records'); + $handler->handle($record); + + $this->assertFalse($handler->{'has'.$method}('bar'), 'has'.$method); + $this->assertTrue($handler->{'has'.$method}($record), 'has'.$method); + $this->assertTrue($handler->{'has'.$method}('test'.$method), 'has'.$method); + $this->assertTrue($handler->{'has'.$method.'ThatContains'}('test'), 'has'.$method.'ThatContains'); + $this->assertTrue($handler->{'has'.$method.'ThatPasses'}(function ($rec) { + return true; + }), 'has'.$method.'ThatPasses'); + $this->assertTrue($handler->{'has'.$method.'ThatMatches'}('/test\w+/')); + $this->assertTrue($handler->{'has'.$method.'Records'}(), 'has'.$method.'Records'); + + $records = $handler->getRecords(); + unset($records[0]['formatted']); + $this->assertEquals(array($record), $records); + } + + public function methodProvider() + { + return array( + array('Emergency', Logger::EMERGENCY), + array('Alert' , Logger::ALERT), + array('Critical' , Logger::CRITICAL), + array('Error' , Logger::ERROR), + array('Warning' , Logger::WARNING), + array('Info' , Logger::INFO), + array('Notice' , Logger::NOTICE), + array('Debug' , Logger::DEBUG), + ); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php new file mode 100644 index 0000000..fa524d0 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Handler\SyslogUdp\UdpSocket; + +/** + * @requires extension sockets + */ +class UdpSocketTest extends TestCase +{ + public function testWeDoNotTruncateShortMessages() + { + $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol')); + + $socket->expects($this->at(0)) + ->method('send') + ->with("HEADER: The quick brown fox jumps over the lazy dog"); + + $socket->write("The quick brown fox jumps over the lazy dog", "HEADER: "); + } + + public function testLongMessagesAreTruncated() + { + $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol')); + + $truncatedString = str_repeat("derp", 16254).'d'; + + $socket->expects($this->exactly(1)) + ->method('send') + ->with("HEADER" . $truncatedString); + + $longString = str_repeat("derp", 20000); + + $socket->write($longString, "HEADER"); + } + + public function testDoubleCloseDoesNotError() + { + $socket = new UdpSocket('127.0.0.1', 514); + $socket->close(); + $socket->close(); + } + + /** + * @expectedException LogicException + */ + public function testWriteAfterCloseErrors() + { + $socket = new UdpSocket('127.0.0.1', 514); + $socket->close(); + $socket->write('foo', "HEADER"); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php new file mode 100644 index 0000000..8d37a1f --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; +use Monolog\Logger; + +class WhatFailureGroupHandlerTest extends TestCase +{ + /** + * @covers Monolog\Handler\WhatFailureGroupHandler::__construct + * @expectedException InvalidArgumentException + */ + public function testConstructorOnlyTakesHandler() + { + new WhatFailureGroupHandler(array(new TestHandler(), "foo")); + } + + /** + * @covers Monolog\Handler\WhatFailureGroupHandler::__construct + * @covers Monolog\Handler\WhatFailureGroupHandler::handle + */ + public function testHandle() + { + $testHandlers = array(new TestHandler(), new TestHandler()); + $handler = new WhatFailureGroupHandler($testHandlers); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + foreach ($testHandlers as $test) { + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue(count($test->getRecords()) === 2); + } + } + + /** + * @covers Monolog\Handler\WhatFailureGroupHandler::handleBatch + */ + public function testHandleBatch() + { + $testHandlers = array(new TestHandler(), new TestHandler()); + $handler = new WhatFailureGroupHandler($testHandlers); + $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO))); + foreach ($testHandlers as $test) { + $this->assertTrue($test->hasDebugRecords()); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue(count($test->getRecords()) === 2); + } + } + + /** + * @covers Monolog\Handler\WhatFailureGroupHandler::isHandling + */ + public function testIsHandling() + { + $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING)); + $handler = new WhatFailureGroupHandler($testHandlers); + $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR))); + $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING))); + $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG))); + } + + /** + * @covers Monolog\Handler\WhatFailureGroupHandler::handle + */ + public function testHandleUsesProcessors() + { + $test = new TestHandler(); + $handler = new WhatFailureGroupHandler(array($test)); + $handler->pushProcessor(function ($record) { + $record['extra']['foo'] = true; + + return $record; + }); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasWarningRecords()); + $records = $test->getRecords(); + $this->assertTrue($records[0]['extra']['foo']); + } + + /** + * @covers Monolog\Handler\WhatFailureGroupHandler::handle + */ + public function testHandleException() + { + $test = new TestHandler(); + $exception = new ExceptionTestHandler(); + $handler = new WhatFailureGroupHandler(array($exception, $test, $exception)); + $handler->pushProcessor(function ($record) { + $record['extra']['foo'] = true; + + return $record; + }); + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertTrue($test->hasWarningRecords()); + $records = $test->getRecords(); + $this->assertTrue($records[0]['extra']['foo']); + } +} + +class ExceptionTestHandler extends TestHandler +{ + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + parent::handle($record); + + throw new \Exception("ExceptionTestHandler::handle"); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php new file mode 100644 index 0000000..416039e --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\TestCase; + +class ZendMonitorHandlerTest extends TestCase +{ + protected $zendMonitorHandler; + + public function setUp() + { + if (!function_exists('zend_monitor_custom_event')) { + $this->markTestSkipped('ZendServer is not installed'); + } + } + + /** + * @covers Monolog\Handler\ZendMonitorHandler::write + */ + public function testWrite() + { + $record = $this->getRecord(); + $formatterResult = array( + 'message' => $record['message'] + ); + + $zendMonitor = $this->getMockBuilder('Monolog\Handler\ZendMonitorHandler') + ->setMethods(array('writeZendMonitorCustomEvent', 'getDefaultFormatter')) + ->getMock(); + + $formatterMock = $this->getMockBuilder('Monolog\Formatter\NormalizerFormatter') + ->disableOriginalConstructor() + ->getMock(); + + $formatterMock->expects($this->once()) + ->method('format') + ->will($this->returnValue($formatterResult)); + + $zendMonitor->expects($this->once()) + ->method('getDefaultFormatter') + ->will($this->returnValue($formatterMock)); + + $levelMap = $zendMonitor->getLevelMap(); + + $zendMonitor->expects($this->once()) + ->method('writeZendMonitorCustomEvent') + ->with($levelMap[$record['level']], $record['message'], $formatterResult); + + $zendMonitor->handle($record); + } + + /** + * @covers Monolog\Handler\ZendMonitorHandler::getDefaultFormatter + */ + public function testGetDefaultFormatterReturnsNormalizerFormatter() + { + $zendMonitor = new ZendMonitorHandler(); + $this->assertInstanceOf('Monolog\Formatter\NormalizerFormatter', $zendMonitor->getDefaultFormatter()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/LoggerTest.php b/vendor/monolog/monolog/tests/Monolog/LoggerTest.php new file mode 100644 index 0000000..b9ba6e9 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/LoggerTest.php @@ -0,0 +1,471 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use Monolog\Processor\WebProcessor; +use Monolog\Handler\TestHandler; + +class LoggerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Monolog\Logger::getName + */ + public function testGetName() + { + $logger = new Logger('foo'); + $this->assertEquals('foo', $logger->getName()); + } + + /** + * @covers Monolog\Logger::getLevelName + */ + public function testGetLevelName() + { + $this->assertEquals('ERROR', Logger::getLevelName(Logger::ERROR)); + } + + /** + * @covers Monolog\Logger::toMonologLevel + */ + public function testConvertPSR3ToMonologLevel() + { + $this->assertEquals(Logger::toMonologLevel('debug'), 100); + $this->assertEquals(Logger::toMonologLevel('info'), 200); + $this->assertEquals(Logger::toMonologLevel('notice'), 250); + $this->assertEquals(Logger::toMonologLevel('warning'), 300); + $this->assertEquals(Logger::toMonologLevel('error'), 400); + $this->assertEquals(Logger::toMonologLevel('critical'), 500); + $this->assertEquals(Logger::toMonologLevel('alert'), 550); + $this->assertEquals(Logger::toMonologLevel('emergency'), 600); + } + + /** + * @covers Monolog\Logger::getLevelName + * @expectedException InvalidArgumentException + */ + public function testGetLevelNameThrows() + { + Logger::getLevelName(5); + } + + /** + * @covers Monolog\Logger::__construct + */ + public function testChannel() + { + $logger = new Logger('foo'); + $handler = new TestHandler; + $logger->pushHandler($handler); + $logger->addWarning('test'); + list($record) = $handler->getRecords(); + $this->assertEquals('foo', $record['channel']); + } + + /** + * @covers Monolog\Logger::addRecord + */ + public function testLog() + { + $logger = new Logger(__METHOD__); + + $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle')); + $handler->expects($this->once()) + ->method('handle'); + $logger->pushHandler($handler); + + $this->assertTrue($logger->addWarning('test')); + } + + /** + * @covers Monolog\Logger::addRecord + */ + public function testLogNotHandled() + { + $logger = new Logger(__METHOD__); + + $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'), array(Logger::ERROR)); + $handler->expects($this->never()) + ->method('handle'); + $logger->pushHandler($handler); + + $this->assertFalse($logger->addWarning('test')); + } + + public function testHandlersInCtor() + { + $handler1 = new TestHandler; + $handler2 = new TestHandler; + $logger = new Logger(__METHOD__, array($handler1, $handler2)); + + $this->assertEquals($handler1, $logger->popHandler()); + $this->assertEquals($handler2, $logger->popHandler()); + } + + public function testProcessorsInCtor() + { + $processor1 = new WebProcessor; + $processor2 = new WebProcessor; + $logger = new Logger(__METHOD__, array(), array($processor1, $processor2)); + + $this->assertEquals($processor1, $logger->popProcessor()); + $this->assertEquals($processor2, $logger->popProcessor()); + } + + /** + * @covers Monolog\Logger::pushHandler + * @covers Monolog\Logger::popHandler + * @expectedException LogicException + */ + public function testPushPopHandler() + { + $logger = new Logger(__METHOD__); + $handler1 = new TestHandler; + $handler2 = new TestHandler; + + $logger->pushHandler($handler1); + $logger->pushHandler($handler2); + + $this->assertEquals($handler2, $logger->popHandler()); + $this->assertEquals($handler1, $logger->popHandler()); + $logger->popHandler(); + } + + /** + * @covers Monolog\Logger::setHandlers + */ + public function testSetHandlers() + { + $logger = new Logger(__METHOD__); + $handler1 = new TestHandler; + $handler2 = new TestHandler; + + $logger->pushHandler($handler1); + $logger->setHandlers(array($handler2)); + + // handler1 has been removed + $this->assertEquals(array($handler2), $logger->getHandlers()); + + $logger->setHandlers(array( + "AMapKey" => $handler1, + "Woop" => $handler2, + )); + + // Keys have been scrubbed + $this->assertEquals(array($handler1, $handler2), $logger->getHandlers()); + } + + /** + * @covers Monolog\Logger::pushProcessor + * @covers Monolog\Logger::popProcessor + * @expectedException LogicException + */ + public function testPushPopProcessor() + { + $logger = new Logger(__METHOD__); + $processor1 = new WebProcessor; + $processor2 = new WebProcessor; + + $logger->pushProcessor($processor1); + $logger->pushProcessor($processor2); + + $this->assertEquals($processor2, $logger->popProcessor()); + $this->assertEquals($processor1, $logger->popProcessor()); + $logger->popProcessor(); + } + + /** + * @covers Monolog\Logger::pushProcessor + * @expectedException InvalidArgumentException + */ + public function testPushProcessorWithNonCallable() + { + $logger = new Logger(__METHOD__); + + $logger->pushProcessor(new \stdClass()); + } + + /** + * @covers Monolog\Logger::addRecord + */ + public function testProcessorsAreExecuted() + { + $logger = new Logger(__METHOD__); + $handler = new TestHandler; + $logger->pushHandler($handler); + $logger->pushProcessor(function ($record) { + $record['extra']['win'] = true; + + return $record; + }); + $logger->addError('test'); + list($record) = $handler->getRecords(); + $this->assertTrue($record['extra']['win']); + } + + /** + * @covers Monolog\Logger::addRecord + */ + public function testProcessorsAreCalledOnlyOnce() + { + $logger = new Logger(__METHOD__); + $handler = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler->expects($this->any()) + ->method('handle') + ->will($this->returnValue(true)) + ; + $logger->pushHandler($handler); + + $processor = $this->getMockBuilder('Monolog\Processor\WebProcessor') + ->disableOriginalConstructor() + ->setMethods(array('__invoke')) + ->getMock() + ; + $processor->expects($this->once()) + ->method('__invoke') + ->will($this->returnArgument(0)) + ; + $logger->pushProcessor($processor); + + $logger->addError('test'); + } + + /** + * @covers Monolog\Logger::addRecord + */ + public function testProcessorsNotCalledWhenNotHandled() + { + $logger = new Logger(__METHOD__); + $handler = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler->expects($this->once()) + ->method('isHandling') + ->will($this->returnValue(false)) + ; + $logger->pushHandler($handler); + $that = $this; + $logger->pushProcessor(function ($record) use ($that) { + $that->fail('The processor should not be called'); + }); + $logger->addAlert('test'); + } + + /** + * @covers Monolog\Logger::addRecord + */ + public function testHandlersNotCalledBeforeFirstHandling() + { + $logger = new Logger(__METHOD__); + + $handler1 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler1->expects($this->never()) + ->method('isHandling') + ->will($this->returnValue(false)) + ; + $handler1->expects($this->once()) + ->method('handle') + ->will($this->returnValue(false)) + ; + $logger->pushHandler($handler1); + + $handler2 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler2->expects($this->once()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler2->expects($this->once()) + ->method('handle') + ->will($this->returnValue(false)) + ; + $logger->pushHandler($handler2); + + $handler3 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler3->expects($this->once()) + ->method('isHandling') + ->will($this->returnValue(false)) + ; + $handler3->expects($this->never()) + ->method('handle') + ; + $logger->pushHandler($handler3); + + $logger->debug('test'); + } + + /** + * @covers Monolog\Logger::addRecord + */ + public function testBubblingWhenTheHandlerReturnsFalse() + { + $logger = new Logger(__METHOD__); + + $handler1 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler1->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler1->expects($this->once()) + ->method('handle') + ->will($this->returnValue(false)) + ; + $logger->pushHandler($handler1); + + $handler2 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler2->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler2->expects($this->once()) + ->method('handle') + ->will($this->returnValue(false)) + ; + $logger->pushHandler($handler2); + + $logger->debug('test'); + } + + /** + * @covers Monolog\Logger::addRecord + */ + public function testNotBubblingWhenTheHandlerReturnsTrue() + { + $logger = new Logger(__METHOD__); + + $handler1 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler1->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler1->expects($this->never()) + ->method('handle') + ; + $logger->pushHandler($handler1); + + $handler2 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler2->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + $handler2->expects($this->once()) + ->method('handle') + ->will($this->returnValue(true)) + ; + $logger->pushHandler($handler2); + + $logger->debug('test'); + } + + /** + * @covers Monolog\Logger::isHandling + */ + public function testIsHandling() + { + $logger = new Logger(__METHOD__); + + $handler1 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler1->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(false)) + ; + + $logger->pushHandler($handler1); + $this->assertFalse($logger->isHandling(Logger::DEBUG)); + + $handler2 = $this->getMock('Monolog\Handler\HandlerInterface'); + $handler2->expects($this->any()) + ->method('isHandling') + ->will($this->returnValue(true)) + ; + + $logger->pushHandler($handler2); + $this->assertTrue($logger->isHandling(Logger::DEBUG)); + } + + /** + * @dataProvider logMethodProvider + * @covers Monolog\Logger::addDebug + * @covers Monolog\Logger::addInfo + * @covers Monolog\Logger::addNotice + * @covers Monolog\Logger::addWarning + * @covers Monolog\Logger::addError + * @covers Monolog\Logger::addCritical + * @covers Monolog\Logger::addAlert + * @covers Monolog\Logger::addEmergency + * @covers Monolog\Logger::debug + * @covers Monolog\Logger::info + * @covers Monolog\Logger::notice + * @covers Monolog\Logger::warn + * @covers Monolog\Logger::err + * @covers Monolog\Logger::crit + * @covers Monolog\Logger::alert + * @covers Monolog\Logger::emerg + */ + public function testLogMethods($method, $expectedLevel) + { + $logger = new Logger('foo'); + $handler = new TestHandler; + $logger->pushHandler($handler); + $logger->{$method}('test'); + list($record) = $handler->getRecords(); + $this->assertEquals($expectedLevel, $record['level']); + } + + public function logMethodProvider() + { + return array( + // monolog methods + array('addDebug', Logger::DEBUG), + array('addInfo', Logger::INFO), + array('addNotice', Logger::NOTICE), + array('addWarning', Logger::WARNING), + array('addError', Logger::ERROR), + array('addCritical', Logger::CRITICAL), + array('addAlert', Logger::ALERT), + array('addEmergency', Logger::EMERGENCY), + + // ZF/Sf2 compat methods + array('debug', Logger::DEBUG), + array('info', Logger::INFO), + array('notice', Logger::NOTICE), + array('warn', Logger::WARNING), + array('err', Logger::ERROR), + array('crit', Logger::CRITICAL), + array('alert', Logger::ALERT), + array('emerg', Logger::EMERGENCY), + ); + } + + /** + * @dataProvider setTimezoneProvider + * @covers Monolog\Logger::setTimezone + */ + public function testSetTimezone($tz) + { + Logger::setTimezone($tz); + $logger = new Logger('foo'); + $handler = new TestHandler; + $logger->pushHandler($handler); + $logger->info('test'); + list($record) = $handler->getRecords(); + $this->assertEquals($tz, $record['datetime']->getTimezone()); + } + + public function setTimezoneProvider() + { + return array_map( + function ($tz) { return array(new \DateTimeZone($tz)); }, + \DateTimeZone::listIdentifiers() + ); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php new file mode 100644 index 0000000..5adb505 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\TestCase; + +class GitProcessorTest extends TestCase +{ + /** + * @covers Monolog\Processor\GitProcessor::__invoke + */ + public function testProcessor() + { + $processor = new GitProcessor(); + $record = $processor($this->getRecord()); + + $this->assertArrayHasKey('git', $record['extra']); + $this->assertTrue(!is_array($record['extra']['git']['branch'])); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php new file mode 100644 index 0000000..0dd411d --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Acme; + +class Tester +{ + public function test($handler, $record) + { + $handler->handle($record); + } +} + +function tester($handler, $record) +{ + $handler->handle($record); +} + +namespace Monolog\Processor; + +use Monolog\Logger; +use Monolog\TestCase; +use Monolog\Handler\TestHandler; + +class IntrospectionProcessorTest extends TestCase +{ + public function getHandler() + { + $processor = new IntrospectionProcessor(); + $handler = new TestHandler(); + $handler->pushProcessor($processor); + + return $handler; + } + + public function testProcessorFromClass() + { + $handler = $this->getHandler(); + $tester = new \Acme\Tester; + $tester->test($handler, $this->getRecord()); + list($record) = $handler->getRecords(); + $this->assertEquals(__FILE__, $record['extra']['file']); + $this->assertEquals(18, $record['extra']['line']); + $this->assertEquals('Acme\Tester', $record['extra']['class']); + $this->assertEquals('test', $record['extra']['function']); + } + + public function testProcessorFromFunc() + { + $handler = $this->getHandler(); + \Acme\tester($handler, $this->getRecord()); + list($record) = $handler->getRecords(); + $this->assertEquals(__FILE__, $record['extra']['file']); + $this->assertEquals(24, $record['extra']['line']); + $this->assertEquals(null, $record['extra']['class']); + $this->assertEquals('Acme\tester', $record['extra']['function']); + } + + public function testLevelTooLow() + { + $input = array( + 'level' => Logger::DEBUG, + 'extra' => array(), + ); + + $expected = $input; + + $processor = new IntrospectionProcessor(Logger::CRITICAL); + $actual = $processor($input); + + $this->assertEquals($expected, $actual); + } + + public function testLevelEqual() + { + $input = array( + 'level' => Logger::CRITICAL, + 'extra' => array(), + ); + + $expected = $input; + $expected['extra'] = array( + 'file' => null, + 'line' => null, + 'class' => 'ReflectionMethod', + 'function' => 'invokeArgs', + ); + + $processor = new IntrospectionProcessor(Logger::CRITICAL); + $actual = $processor($input); + + $this->assertEquals($expected, $actual); + } + + public function testLevelHigher() + { + $input = array( + 'level' => Logger::EMERGENCY, + 'extra' => array(), + ); + + $expected = $input; + $expected['extra'] = array( + 'file' => null, + 'line' => null, + 'class' => 'ReflectionMethod', + 'function' => 'invokeArgs', + ); + + $processor = new IntrospectionProcessor(Logger::CRITICAL); + $actual = $processor($input); + + $this->assertEquals($expected, $actual); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php new file mode 100644 index 0000000..eb66614 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/MemoryPeakUsageProcessorTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\TestCase; + +class MemoryPeakUsageProcessorTest extends TestCase +{ + /** + * @covers Monolog\Processor\MemoryPeakUsageProcessor::__invoke + * @covers Monolog\Processor\MemoryProcessor::formatBytes + */ + public function testProcessor() + { + $processor = new MemoryPeakUsageProcessor(); + $record = $processor($this->getRecord()); + $this->assertArrayHasKey('memory_peak_usage', $record['extra']); + $this->assertRegExp('#[0-9.]+ (M|K)?B$#', $record['extra']['memory_peak_usage']); + } + + /** + * @covers Monolog\Processor\MemoryPeakUsageProcessor::__invoke + * @covers Monolog\Processor\MemoryProcessor::formatBytes + */ + public function testProcessorWithoutFormatting() + { + $processor = new MemoryPeakUsageProcessor(true, false); + $record = $processor($this->getRecord()); + $this->assertArrayHasKey('memory_peak_usage', $record['extra']); + $this->assertInternalType('int', $record['extra']['memory_peak_usage']); + $this->assertGreaterThan(0, $record['extra']['memory_peak_usage']); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/MemoryUsageProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/MemoryUsageProcessorTest.php new file mode 100644 index 0000000..4692dbf --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/MemoryUsageProcessorTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\TestCase; + +class MemoryUsageProcessorTest extends TestCase +{ + /** + * @covers Monolog\Processor\MemoryUsageProcessor::__invoke + * @covers Monolog\Processor\MemoryProcessor::formatBytes + */ + public function testProcessor() + { + $processor = new MemoryUsageProcessor(); + $record = $processor($this->getRecord()); + $this->assertArrayHasKey('memory_usage', $record['extra']); + $this->assertRegExp('#[0-9.]+ (M|K)?B$#', $record['extra']['memory_usage']); + } + + /** + * @covers Monolog\Processor\MemoryUsageProcessor::__invoke + * @covers Monolog\Processor\MemoryProcessor::formatBytes + */ + public function testProcessorWithoutFormatting() + { + $processor = new MemoryUsageProcessor(true, false); + $record = $processor($this->getRecord()); + $this->assertArrayHasKey('memory_usage', $record['extra']); + $this->assertInternalType('int', $record['extra']['memory_usage']); + $this->assertGreaterThan(0, $record['extra']['memory_usage']); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/ProcessIdProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/ProcessIdProcessorTest.php new file mode 100644 index 0000000..458d2a3 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/ProcessIdProcessorTest.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\TestCase; + +class ProcessIdProcessorTest extends TestCase +{ + /** + * @covers Monolog\Processor\ProcessIdProcessor::__invoke + */ + public function testProcessor() + { + $processor = new ProcessIdProcessor(); + $record = $processor($this->getRecord()); + $this->assertArrayHasKey('process_id', $record['extra']); + $this->assertInternalType('int', $record['extra']['process_id']); + $this->assertGreaterThan(0, $record['extra']['process_id']); + $this->assertEquals(getmypid(), $record['extra']['process_id']); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/PsrLogMessageProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/PsrLogMessageProcessorTest.php new file mode 100644 index 0000000..81bfbdc --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/PsrLogMessageProcessorTest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +class PsrLogMessageProcessorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getPairs + */ + public function testReplacement($val, $expected) + { + $proc = new PsrLogMessageProcessor; + + $message = $proc(array( + 'message' => '{foo}', + 'context' => array('foo' => $val) + )); + $this->assertEquals($expected, $message['message']); + } + + public function getPairs() + { + return array( + array('foo', 'foo'), + array('3', '3'), + array(3, '3'), + array(null, ''), + array(true, '1'), + array(false, ''), + array(new \stdClass, '[object stdClass]'), + array(array(), '[array]'), + ); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/TagProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/TagProcessorTest.php new file mode 100644 index 0000000..0d860c6 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/TagProcessorTest.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\TestCase; + +class TagProcessorTest extends TestCase +{ + /** + * @covers Monolog\Processor\TagProcessor::__invoke + */ + public function testProcessor() + { + $tags = array(1, 2, 3); + $processor = new TagProcessor($tags); + $record = $processor($this->getRecord()); + + $this->assertEquals($tags, $record['extra']['tags']); + } + + /** + * @covers Monolog\Processor\TagProcessor::__invoke + */ + public function testProcessorTagModification() + { + $tags = array(1, 2, 3); + $processor = new TagProcessor($tags); + + $record = $processor($this->getRecord()); + $this->assertEquals($tags, $record['extra']['tags']); + + $processor->setTags(array('a', 'b')); + $record = $processor($this->getRecord()); + $this->assertEquals(array('a', 'b'), $record['extra']['tags']); + + $processor->addTags(array('a', 'c', 'foo' => 'bar')); + $record = $processor($this->getRecord()); + $this->assertEquals(array('a', 'b', 'a', 'c', 'foo' => 'bar'), $record['extra']['tags']); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/UidProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/UidProcessorTest.php new file mode 100644 index 0000000..befad95 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/UidProcessorTest.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\TestCase; + +class UidProcessorTest extends TestCase +{ + /** + * @covers Monolog\Processor\UidProcessor::__invoke + */ + public function testProcessor() + { + $processor = new UidProcessor(); + $record = $processor($this->getRecord()); + $this->assertArrayHasKey('uid', $record['extra']); + } + public function testGetUid() + { + $processor = new UidProcessor(10); + $this->assertEquals(10, strlen($processor->getUid())); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/Processor/WebProcessorTest.php b/vendor/monolog/monolog/tests/Monolog/Processor/WebProcessorTest.php new file mode 100644 index 0000000..dba8941 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/WebProcessorTest.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Processor; + +use Monolog\TestCase; + +class WebProcessorTest extends TestCase +{ + public function testProcessor() + { + $server = array( + 'REQUEST_URI' => 'A', + 'REMOTE_ADDR' => 'B', + 'REQUEST_METHOD' => 'C', + 'HTTP_REFERER' => 'D', + 'SERVER_NAME' => 'F', + 'UNIQUE_ID' => 'G', + ); + + $processor = new WebProcessor($server); + $record = $processor($this->getRecord()); + $this->assertEquals($server['REQUEST_URI'], $record['extra']['url']); + $this->assertEquals($server['REMOTE_ADDR'], $record['extra']['ip']); + $this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']); + $this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']); + $this->assertEquals($server['SERVER_NAME'], $record['extra']['server']); + $this->assertEquals($server['UNIQUE_ID'], $record['extra']['unique_id']); + } + + public function testProcessorDoNothingIfNoRequestUri() + { + $server = array( + 'REMOTE_ADDR' => 'B', + 'REQUEST_METHOD' => 'C', + ); + $processor = new WebProcessor($server); + $record = $processor($this->getRecord()); + $this->assertEmpty($record['extra']); + } + + public function testProcessorReturnNullIfNoHttpReferer() + { + $server = array( + 'REQUEST_URI' => 'A', + 'REMOTE_ADDR' => 'B', + 'REQUEST_METHOD' => 'C', + 'SERVER_NAME' => 'F', + ); + $processor = new WebProcessor($server); + $record = $processor($this->getRecord()); + $this->assertNull($record['extra']['referrer']); + } + + public function testProcessorDoesNotAddUniqueIdIfNotPresent() + { + $server = array( + 'REQUEST_URI' => 'A', + 'REMOTE_ADDR' => 'B', + 'REQUEST_METHOD' => 'C', + 'SERVER_NAME' => 'F', + ); + $processor = new WebProcessor($server); + $record = $processor($this->getRecord()); + $this->assertFalse(isset($record['extra']['unique_id'])); + } + + public function testProcessorAddsOnlyRequestedExtraFields() + { + $server = array( + 'REQUEST_URI' => 'A', + 'REMOTE_ADDR' => 'B', + 'REQUEST_METHOD' => 'C', + 'SERVER_NAME' => 'F', + ); + + $processor = new WebProcessor($server, array('url', 'http_method')); + $record = $processor($this->getRecord()); + + $this->assertSame(array('url' => 'A', 'http_method' => 'C'), $record['extra']); + } + + /** + * @expectedException UnexpectedValueException + */ + public function testInvalidData() + { + new WebProcessor(new \stdClass); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/PsrLogCompatTest.php b/vendor/monolog/monolog/tests/Monolog/PsrLogCompatTest.php new file mode 100644 index 0000000..ab89944 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/PsrLogCompatTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +use Monolog\Handler\TestHandler; +use Monolog\Formatter\LineFormatter; +use Monolog\Processor\PsrLogMessageProcessor; +use Psr\Log\Test\LoggerInterfaceTest; + +class PsrLogCompatTest extends LoggerInterfaceTest +{ + private $handler; + + public function getLogger() + { + $logger = new Logger('foo'); + $logger->pushHandler($handler = new TestHandler); + $logger->pushProcessor(new PsrLogMessageProcessor); + $handler->setFormatter(new LineFormatter('%level_name% %message%')); + + $this->handler = $handler; + + return $logger; + } + + public function getLogs() + { + $convert = function ($record) { + $lower = function ($match) { + return strtolower($match[0]); + }; + + return preg_replace_callback('{^[A-Z]+}', $lower, $record['formatted']); + }; + + return array_map($convert, $this->handler->getRecords()); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/RegistryTest.php b/vendor/monolog/monolog/tests/Monolog/RegistryTest.php new file mode 100644 index 0000000..15fdfbd --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/RegistryTest.php @@ -0,0 +1,153 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +class RegistryTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + Registry::clear(); + } + + /** + * @dataProvider hasLoggerProvider + * @covers Monolog\Registry::hasLogger + */ + public function testHasLogger(array $loggersToAdd, array $loggersToCheck, array $expectedResult) + { + foreach ($loggersToAdd as $loggerToAdd) { + Registry::addLogger($loggerToAdd); + } + foreach ($loggersToCheck as $index => $loggerToCheck) { + $this->assertSame($expectedResult[$index], Registry::hasLogger($loggerToCheck)); + } + } + + public function hasLoggerProvider() + { + $logger1 = new Logger('test1'); + $logger2 = new Logger('test2'); + $logger3 = new Logger('test3'); + + return array( + // only instances + array( + array($logger1), + array($logger1, $logger2), + array(true, false), + ), + // only names + array( + array($logger1), + array('test1', 'test2'), + array(true, false), + ), + // mixed case + array( + array($logger1, $logger2), + array('test1', $logger2, 'test3', $logger3), + array(true, true, false, false), + ), + ); + } + + /** + * @covers Monolog\Registry::clear + */ + public function testClearClears() + { + Registry::addLogger(new Logger('test1'), 'log'); + Registry::clear(); + + $this->setExpectedException('\InvalidArgumentException'); + Registry::getInstance('log'); + } + + /** + * @dataProvider removedLoggerProvider + * @covers Monolog\Registry::addLogger + * @covers Monolog\Registry::removeLogger + */ + public function testRemovesLogger($loggerToAdd, $remove) + { + Registry::addLogger($loggerToAdd); + Registry::removeLogger($remove); + + $this->setExpectedException('\InvalidArgumentException'); + Registry::getInstance($loggerToAdd->getName()); + } + + public function removedLoggerProvider() + { + $logger1 = new Logger('test1'); + + return array( + array($logger1, $logger1), + array($logger1, 'test1'), + ); + } + + /** + * @covers Monolog\Registry::addLogger + * @covers Monolog\Registry::getInstance + * @covers Monolog\Registry::__callStatic + */ + public function testGetsSameLogger() + { + $logger1 = new Logger('test1'); + $logger2 = new Logger('test2'); + + Registry::addLogger($logger1, 'test1'); + Registry::addLogger($logger2); + + $this->assertSame($logger1, Registry::getInstance('test1')); + $this->assertSame($logger2, Registry::test2()); + } + + /** + * @expectedException \InvalidArgumentException + * @covers Monolog\Registry::getInstance + */ + public function testFailsOnNonExistantLogger() + { + Registry::getInstance('test1'); + } + + /** + * @covers Monolog\Registry::addLogger + */ + public function testReplacesLogger() + { + $log1 = new Logger('test1'); + $log2 = new Logger('test2'); + + Registry::addLogger($log1, 'log'); + + Registry::addLogger($log2, 'log', true); + + $this->assertSame($log2, Registry::getInstance('log')); + } + + /** + * @expectedException \InvalidArgumentException + * @covers Monolog\Registry::addLogger + */ + public function testFailsOnUnspecifiedReplacement() + { + $log1 = new Logger('test1'); + $log2 = new Logger('test2'); + + Registry::addLogger($log1, 'log'); + + Registry::addLogger($log2, 'log'); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/TestCase.php b/vendor/monolog/monolog/tests/Monolog/TestCase.php new file mode 100644 index 0000000..cae7934 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/TestCase.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog; + +class TestCase extends \PHPUnit_Framework_TestCase +{ + /** + * @return array Record + */ + protected function getRecord($level = Logger::WARNING, $message = 'test', $context = array()) + { + return array( + 'message' => $message, + 'context' => $context, + 'level' => $level, + 'level_name' => Logger::getLevelName($level), + 'channel' => 'test', + 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true))), + 'extra' => array(), + ); + } + + /** + * @return array + */ + protected function getMultipleRecords() + { + return array( + $this->getRecord(Logger::DEBUG, 'debug message 1'), + $this->getRecord(Logger::DEBUG, 'debug message 2'), + $this->getRecord(Logger::INFO, 'information'), + $this->getRecord(Logger::WARNING, 'warning'), + $this->getRecord(Logger::ERROR, 'error') + ); + } + + /** + * @return Monolog\Formatter\FormatterInterface + */ + protected function getIdentityFormatter() + { + $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface'); + $formatter->expects($this->any()) + ->method('format') + ->will($this->returnCallback(function ($record) { return $record['message']; })); + + return $formatter; + } +} diff --git a/vendor/mtdowling/cron-expression/LICENSE b/vendor/mtdowling/cron-expression/LICENSE new file mode 100644 index 0000000..c6d88ac --- /dev/null +++ b/vendor/mtdowling/cron-expression/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Michael Dowling and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/mtdowling/cron-expression/README.md b/vendor/mtdowling/cron-expression/README.md new file mode 100644 index 0000000..1571e5d --- /dev/null +++ b/vendor/mtdowling/cron-expression/README.md @@ -0,0 +1,82 @@ +PHP Cron Expression Parser +========================== + +[![Latest Stable Version](https://poser.pugx.org/mtdowling/cron-expression/v/stable.png)](https://packagist.org/packages/mtdowling/cron-expression) [![Total Downloads](https://poser.pugx.org/mtdowling/cron-expression/downloads.png)](https://packagist.org/packages/mtdowling/cron-expression) [![Build Status](https://secure.travis-ci.org/mtdowling/cron-expression.png)](http://travis-ci.org/mtdowling/cron-expression) + +The PHP cron expression parser can parse a CRON expression, determine if it is +due to run, calculate the next run date of the expression, and calculate the previous +run date of the expression. You can calculate dates far into the future or past by +skipping n number of matching dates. + +The parser can handle increments of ranges (e.g. */12, 2-59/3), intervals (e.g. 0-9), +lists (e.g. 1,2,3), W to find the nearest weekday for a given day of the month, L to +find the last day of the month, L to find the last given weekday of a month, and hash +(#) to find the nth weekday of a given month. + +Installing +========== + +Add the dependency to your project: + +```bash +composer require mtdowling/cron-expression +``` + +Usage +===== +```php +isDue(); +echo $cron->getNextRunDate()->format('Y-m-d H:i:s'); +echo $cron->getPreviousRunDate()->format('Y-m-d H:i:s'); + +// Works with complex expressions +$cron = Cron\CronExpression::factory('3-59/15 2,6-12 */15 1 2-5'); +echo $cron->getNextRunDate()->format('Y-m-d H:i:s'); + +// Calculate a run date two iterations into the future +$cron = Cron\CronExpression::factory('@daily'); +echo $cron->getNextRunDate(null, 2)->format('Y-m-d H:i:s'); + +// Calculate a run date relative to a specific time +$cron = Cron\CronExpression::factory('@monthly'); +echo $cron->getNextRunDate('2010-01-12 00:00:00')->format('Y-m-d H:i:s'); +``` + +CRON Expressions +================ + +A CRON expression is a string representing the schedule for a particular command to execute. The parts of a CRON schedule are as follows: + + * * * * * * + - - - - - - + | | | | | | + | | | | | + year [optional] + | | | | +----- day of week (0 - 7) (Sunday=0 or 7) + | | | +---------- month (1 - 12) + | | +--------------- day of month (1 - 31) + | +-------------------- hour (0 - 23) + +------------------------- min (0 - 59) + +Requirements +============ + +- PHP 5.3+ +- PHPUnit is required to run the unit tests +- Composer is required to run the unit tests + +CHANGELOG +========= + +1.0.3 (2013-11-23) +------------------ + +* Only set default timezone if the given $currentTime is not a DateTime instance ([#34](https://github.com/mtdowling/cron-expression/issues/34)) +* Fixes issue [#28](https://github.com/mtdowling/cron-expression/issues/28) where PHP increments of ranges were failing due to PHP casting hyphens to 0 +* Now supports expressions with any number of extra spaces, tabs, or newlines +* Using static instead of self in `CronExpression::factory` diff --git a/vendor/mtdowling/cron-expression/composer.json b/vendor/mtdowling/cron-expression/composer.json new file mode 100644 index 0000000..62c0d89 --- /dev/null +++ b/vendor/mtdowling/cron-expression/composer.json @@ -0,0 +1,23 @@ +{ + "name": "mtdowling/cron-expression", + "type": "library", + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": ["cron", "schedule"], + "license": "MIT", + "authors": [{ + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }], + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "autoload": { + "psr-0": { + "Cron": "src/" + } + } +} \ No newline at end of file diff --git a/vendor/mtdowling/cron-expression/phpunit.xml.dist b/vendor/mtdowling/cron-expression/phpunit.xml.dist new file mode 100644 index 0000000..fb8a552 --- /dev/null +++ b/vendor/mtdowling/cron-expression/phpunit.xml.dist @@ -0,0 +1,17 @@ + + + + + + ./tests + + + + + + ./src/Cron + + + + diff --git a/vendor/mtdowling/cron-expression/src/Cron/AbstractField.php b/vendor/mtdowling/cron-expression/src/Cron/AbstractField.php new file mode 100644 index 0000000..c0616a2 --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/AbstractField.php @@ -0,0 +1,104 @@ +isIncrementsOfRanges($value)) { + return $this->isInIncrementsOfRanges($dateValue, $value); + } elseif ($this->isRange($value)) { + return $this->isInRange($dateValue, $value); + } + + return $value == '*' || $dateValue == $value; + } + + /** + * Check if a value is a range + * + * @param string $value Value to test + * + * @return bool + */ + public function isRange($value) + { + return strpos($value, '-') !== false; + } + + /** + * Check if a value is an increments of ranges + * + * @param string $value Value to test + * + * @return bool + */ + public function isIncrementsOfRanges($value) + { + return strpos($value, '/') !== false; + } + + /** + * Test if a value is within a range + * + * @param string $dateValue Set date value + * @param string $value Value to test + * + * @return bool + */ + public function isInRange($dateValue, $value) + { + $parts = array_map('trim', explode('-', $value, 2)); + + return $dateValue >= $parts[0] && $dateValue <= $parts[1]; + } + + /** + * Test if a value is within an increments of ranges (offset[-to]/step size) + * + * @param string $dateValue Set date value + * @param string $value Value to test + * + * @return bool + */ + public function isInIncrementsOfRanges($dateValue, $value) + { + $parts = array_map('trim', explode('/', $value, 2)); + $stepSize = isset($parts[1]) ? $parts[1] : 0; + if (($parts[0] == '*' || $parts[0] === '0') && 0 !== $stepSize) { + return (int) $dateValue % $stepSize == 0; + } + + $range = explode('-', $parts[0], 2); + $offset = $range[0]; + $to = isset($range[1]) ? $range[1] : $dateValue; + // Ensure that the date value is within the range + if ($dateValue < $offset || $dateValue > $to) { + return false; + } + + if ($dateValue > $offset && 0 === $stepSize) { + return false; + } + + for ($i = $offset; $i <= $to; $i+= $stepSize) { + if ($i == $dateValue) { + return true; + } + } + + return false; + } +} diff --git a/vendor/mtdowling/cron-expression/src/Cron/CronExpression.php b/vendor/mtdowling/cron-expression/src/Cron/CronExpression.php new file mode 100644 index 0000000..ce90f29 --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/CronExpression.php @@ -0,0 +1,332 @@ + '0 0 1 1 *', + '@annually' => '0 0 1 1 *', + '@monthly' => '0 0 1 * *', + '@weekly' => '0 0 * * 0', + '@daily' => '0 0 * * *', + '@hourly' => '0 * * * *' + ); + + if (isset($mappings[$expression])) { + $expression = $mappings[$expression]; + } + + return new static($expression, $fieldFactory ?: new FieldFactory()); + } + + /** + * Parse a CRON expression + * + * @param string $expression CRON expression (e.g. '8 * * * *') + * @param FieldFactory $fieldFactory Factory to create cron fields + */ + public function __construct($expression, FieldFactory $fieldFactory) + { + $this->fieldFactory = $fieldFactory; + $this->setExpression($expression); + } + + /** + * Set or change the CRON expression + * + * @param string $value CRON expression (e.g. 8 * * * *) + * + * @return CronExpression + * @throws \InvalidArgumentException if not a valid CRON expression + */ + public function setExpression($value) + { + $this->cronParts = preg_split('/\s/', $value, -1, PREG_SPLIT_NO_EMPTY); + if (count($this->cronParts) < 5) { + throw new \InvalidArgumentException( + $value . ' is not a valid CRON expression' + ); + } + + foreach ($this->cronParts as $position => $part) { + $this->setPart($position, $part); + } + + return $this; + } + + /** + * Set part of the CRON expression + * + * @param int $position The position of the CRON expression to set + * @param string $value The value to set + * + * @return CronExpression + * @throws \InvalidArgumentException if the value is not valid for the part + */ + public function setPart($position, $value) + { + if (!$this->fieldFactory->getField($position)->validate($value)) { + throw new \InvalidArgumentException( + 'Invalid CRON field value ' . $value . ' as position ' . $position + ); + } + + $this->cronParts[$position] = $value; + + return $this; + } + + /** + * Get a next run date relative to the current date or a specific date + * + * @param string|\DateTime $currentTime Relative calculation date + * @param int $nth Number of matches to skip before returning a + * matching next run date. 0, the default, will return the current + * date and time if the next run date falls on the current date and + * time. Setting this value to 1 will skip the first match and go to + * the second match. Setting this value to 2 will skip the first 2 + * matches and so on. + * @param bool $allowCurrentDate Set to TRUE to return the current date if + * it matches the cron expression. + * + * @return \DateTime + * @throws \RuntimeException on too many iterations + */ + public function getNextRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false) + { + return $this->getRunDate($currentTime, $nth, false, $allowCurrentDate); + } + + /** + * Get a previous run date relative to the current date or a specific date + * + * @param string|\DateTime $currentTime Relative calculation date + * @param int $nth Number of matches to skip before returning + * @param bool $allowCurrentDate Set to TRUE to return the + * current date if it matches the cron expression + * + * @return \DateTime + * @throws \RuntimeException on too many iterations + * @see Cron\CronExpression::getNextRunDate + */ + public function getPreviousRunDate($currentTime = 'now', $nth = 0, $allowCurrentDate = false) + { + return $this->getRunDate($currentTime, $nth, true, $allowCurrentDate); + } + + /** + * Get multiple run dates starting at the current date or a specific date + * + * @param int $total Set the total number of dates to calculate + * @param string|\DateTime $currentTime Relative calculation date + * @param bool $invert Set to TRUE to retrieve previous dates + * @param bool $allowCurrentDate Set to TRUE to return the + * current date if it matches the cron expression + * + * @return array Returns an array of run dates + */ + public function getMultipleRunDates($total, $currentTime = 'now', $invert = false, $allowCurrentDate = false) + { + $matches = array(); + for ($i = 0; $i < max(0, $total); $i++) { + $matches[] = $this->getRunDate($currentTime, $i, $invert, $allowCurrentDate); + } + + return $matches; + } + + /** + * Get all or part of the CRON expression + * + * @param string $part Specify the part to retrieve or NULL to get the full + * cron schedule string. + * + * @return string|null Returns the CRON expression, a part of the + * CRON expression, or NULL if the part was specified but not found + */ + public function getExpression($part = null) + { + if (null === $part) { + return implode(' ', $this->cronParts); + } elseif (array_key_exists($part, $this->cronParts)) { + return $this->cronParts[$part]; + } + + return null; + } + + /** + * Helper method to output the full expression. + * + * @return string Full CRON expression + */ + public function __toString() + { + return $this->getExpression(); + } + + /** + * Determine if the cron is due to run based on the current date or a + * specific date. This method assumes that the current number of + * seconds are irrelevant, and should be called once per minute. + * + * @param string|\DateTime $currentTime Relative calculation date + * + * @return bool Returns TRUE if the cron is due to run or FALSE if not + */ + public function isDue($currentTime = 'now') + { + if ('now' === $currentTime) { + $currentDate = date('Y-m-d H:i'); + $currentTime = strtotime($currentDate); + } elseif ($currentTime instanceof \DateTime) { + $currentDate = clone $currentTime; + // Ensure time in 'current' timezone is used + $currentDate->setTimezone(new \DateTimeZone(date_default_timezone_get())); + $currentDate = $currentDate->format('Y-m-d H:i'); + $currentTime = strtotime($currentDate); + } else { + $currentTime = new \DateTime($currentTime); + $currentTime->setTime($currentTime->format('H'), $currentTime->format('i'), 0); + $currentDate = $currentTime->format('Y-m-d H:i'); + $currentTime = $currentTime->getTimeStamp(); + } + + try { + return $this->getNextRunDate($currentDate, 0, true)->getTimestamp() == $currentTime; + } catch (\Exception $e) { + return false; + } + } + + /** + * Get the next or previous run date of the expression relative to a date + * + * @param string|\DateTime $currentTime Relative calculation date + * @param int $nth Number of matches to skip before returning + * @param bool $invert Set to TRUE to go backwards in time + * @param bool $allowCurrentDate Set to TRUE to return the + * current date if it matches the cron expression + * + * @return \DateTime + * @throws \RuntimeException on too many iterations + */ + protected function getRunDate($currentTime = null, $nth = 0, $invert = false, $allowCurrentDate = false) + { + if ($currentTime instanceof \DateTime) { + $currentDate = clone $currentTime; + } else { + $currentDate = new \DateTime($currentTime ?: 'now'); + $currentDate->setTimezone(new \DateTimeZone(date_default_timezone_get())); + } + + $currentDate->setTime($currentDate->format('H'), $currentDate->format('i'), 0); + $nextRun = clone $currentDate; + $nth = (int) $nth; + + // We don't have to satisfy * or null fields + $parts = array(); + $fields = array(); + foreach (self::$order as $position) { + $part = $this->getExpression($position); + if (null === $part || '*' === $part) { + continue; + } + $parts[$position] = $part; + $fields[$position] = $this->fieldFactory->getField($position); + } + + // Set a hard limit to bail on an impossible date + for ($i = 0; $i < 1000; $i++) { + + foreach ($parts as $position => $part) { + $satisfied = false; + // Get the field object used to validate this part + $field = $fields[$position]; + // Check if this is singular or a list + if (strpos($part, ',') === false) { + $satisfied = $field->isSatisfiedBy($nextRun, $part); + } else { + foreach (array_map('trim', explode(',', $part)) as $listPart) { + if ($field->isSatisfiedBy($nextRun, $listPart)) { + $satisfied = true; + break; + } + } + } + + // If the field is not satisfied, then start over + if (!$satisfied) { + $field->increment($nextRun, $invert); + continue 2; + } + } + + // Skip this match if needed + if ((!$allowCurrentDate && $nextRun == $currentDate) || --$nth > -1) { + $this->fieldFactory->getField(0)->increment($nextRun, $invert); + continue; + } + + return $nextRun; + } + + // @codeCoverageIgnoreStart + throw new \RuntimeException('Impossible CRON expression'); + // @codeCoverageIgnoreEnd + } +} diff --git a/vendor/mtdowling/cron-expression/src/Cron/DayOfMonthField.php b/vendor/mtdowling/cron-expression/src/Cron/DayOfMonthField.php new file mode 100644 index 0000000..86129c9 --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/DayOfMonthField.php @@ -0,0 +1,103 @@ + + */ +class DayOfMonthField extends AbstractField +{ + /** + * Get the nearest day of the week for a given day in a month + * + * @param int $currentYear Current year + * @param int $currentMonth Current month + * @param int $targetDay Target day of the month + * + * @return \DateTime Returns the nearest date + */ + private static function getNearestWeekday($currentYear, $currentMonth, $targetDay) + { + $tday = str_pad($targetDay, 2, '0', STR_PAD_LEFT); + $target = \DateTime::createFromFormat('Y-m-d', "$currentYear-$currentMonth-$tday"); + $currentWeekday = (int) $target->format('N'); + + if ($currentWeekday < 6) { + return $target; + } + + $lastDayOfMonth = $target->format('t'); + + foreach (array(-1, 1, -2, 2) as $i) { + $adjusted = $targetDay + $i; + if ($adjusted > 0 && $adjusted <= $lastDayOfMonth) { + $target->setDate($currentYear, $currentMonth, $adjusted); + if ($target->format('N') < 6 && $target->format('m') == $currentMonth) { + return $target; + } + } + } + } + + public function isSatisfiedBy(\DateTime $date, $value) + { + // ? states that the field value is to be skipped + if ($value == '?') { + return true; + } + + $fieldValue = $date->format('d'); + + // Check to see if this is the last day of the month + if ($value == 'L') { + return $fieldValue == $date->format('t'); + } + + // Check to see if this is the nearest weekday to a particular value + if (strpos($value, 'W')) { + // Parse the target day + $targetDay = substr($value, 0, strpos($value, 'W')); + // Find out if the current day is the nearest day of the week + return $date->format('j') == self::getNearestWeekday( + $date->format('Y'), + $date->format('m'), + $targetDay + )->format('j'); + } + + return $this->isSatisfied($date->format('d'), $value); + } + + public function increment(\DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('previous day'); + $date->setTime(23, 59); + } else { + $date->modify('next day'); + $date->setTime(0, 0); + } + + return $this; + } + + public function validate($value) + { + return (bool) preg_match('/^[\*,\/\-\?LW0-9A-Za-z]+$/', $value); + } +} diff --git a/vendor/mtdowling/cron-expression/src/Cron/DayOfWeekField.php b/vendor/mtdowling/cron-expression/src/Cron/DayOfWeekField.php new file mode 100644 index 0000000..8e33b19 --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/DayOfWeekField.php @@ -0,0 +1,134 @@ +convertLiterals($value); + + $currentYear = $date->format('Y'); + $currentMonth = $date->format('m'); + $lastDayOfMonth = $date->format('t'); + + // Find out if this is the last specific weekday of the month + if (strpos($value, 'L')) { + $weekday = str_replace('7', '0', substr($value, 0, strpos($value, 'L'))); + $tdate = clone $date; + $tdate->setDate($currentYear, $currentMonth, $lastDayOfMonth); + while ($tdate->format('w') != $weekday) { + $tdate->setDate($currentYear, $currentMonth, --$lastDayOfMonth); + } + + return $date->format('j') == $lastDayOfMonth; + } + + // Handle # hash tokens + if (strpos($value, '#')) { + list($weekday, $nth) = explode('#', $value); + + // 0 and 7 are both Sunday, however 7 matches date('N') format ISO-8601 + if ($weekday === '0') { + $weekday = 7; + } + + // Validate the hash fields + if ($weekday < 0 || $weekday > 7) { + throw new \InvalidArgumentException("Weekday must be a value between 0 and 7. {$weekday} given"); + } + if ($nth > 5) { + throw new \InvalidArgumentException('There are never more than 5 of a given weekday in a month'); + } + // The current weekday must match the targeted weekday to proceed + if ($date->format('N') != $weekday) { + return false; + } + + $tdate = clone $date; + $tdate->setDate($currentYear, $currentMonth, 1); + $dayCount = 0; + $currentDay = 1; + while ($currentDay < $lastDayOfMonth + 1) { + if ($tdate->format('N') == $weekday) { + if (++$dayCount >= $nth) { + break; + } + } + $tdate->setDate($currentYear, $currentMonth, ++$currentDay); + } + + return $date->format('j') == $currentDay; + } + + // Handle day of the week values + if (strpos($value, '-')) { + $parts = explode('-', $value); + if ($parts[0] == '7') { + $parts[0] = '0'; + } elseif ($parts[1] == '0') { + $parts[1] = '7'; + } + $value = implode('-', $parts); + } + + // Test to see which Sunday to use -- 0 == 7 == Sunday + $format = in_array(7, str_split($value)) ? 'N' : 'w'; + $fieldValue = $date->format($format); + + return $this->isSatisfied($fieldValue, $value); + } + + public function increment(\DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('-1 day'); + $date->setTime(23, 59, 0); + } else { + $date->modify('+1 day'); + $date->setTime(0, 0, 0); + } + + return $this; + } + + public function validate($value) + { + $value = $this->convertLiterals($value); + + foreach (explode(',', $value) as $expr) { + if (!preg_match('/^(\*|[0-7](L?|#[1-5]))([\/\,\-][0-7]+)*$/', $expr)) { + return false; + } + } + + return true; + } + + private function convertLiterals($string) + { + return str_ireplace( + array('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'), + range(0, 6), + $string + ); + } +} diff --git a/vendor/mtdowling/cron-expression/src/Cron/FieldFactory.php b/vendor/mtdowling/cron-expression/src/Cron/FieldFactory.php new file mode 100644 index 0000000..5aa86f6 --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/FieldFactory.php @@ -0,0 +1,55 @@ +fields[$position])) { + switch ($position) { + case 0: + $this->fields[$position] = new MinutesField(); + break; + case 1: + $this->fields[$position] = new HoursField(); + break; + case 2: + $this->fields[$position] = new DayOfMonthField(); + break; + case 3: + $this->fields[$position] = new MonthField(); + break; + case 4: + $this->fields[$position] = new DayOfWeekField(); + break; + case 5: + $this->fields[$position] = new YearField(); + break; + default: + throw new \InvalidArgumentException( + $position . ' is not a valid position' + ); + } + } + + return $this->fields[$position]; + } +} diff --git a/vendor/mtdowling/cron-expression/src/Cron/FieldInterface.php b/vendor/mtdowling/cron-expression/src/Cron/FieldInterface.php new file mode 100644 index 0000000..3823fbf --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/FieldInterface.php @@ -0,0 +1,39 @@ +isSatisfied($date->format('H'), $value); + } + + public function increment(\DateTime $date, $invert = false) + { + // Change timezone to UTC temporarily. This will + // allow us to go back or forwards and hour even + // if DST will be changed between the hours. + $timezone = $date->getTimezone(); + $date->setTimezone(new \DateTimeZone('UTC')); + if ($invert) { + $date->modify('-1 hour'); + $date->setTime($date->format('H'), 59); + } else { + $date->modify('+1 hour'); + $date->setTime($date->format('H'), 0); + } + $date->setTimezone($timezone); + + return $this; + } + + public function validate($value) + { + return (bool) preg_match('/^[\*,\/\-0-9]+$/', $value); + } +} diff --git a/vendor/mtdowling/cron-expression/src/Cron/MinutesField.php b/vendor/mtdowling/cron-expression/src/Cron/MinutesField.php new file mode 100644 index 0000000..cfa2b09 --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/MinutesField.php @@ -0,0 +1,30 @@ +isSatisfied($date->format('i'), $value); + } + + public function increment(\DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('-1 minute'); + } else { + $date->modify('+1 minute'); + } + + return $this; + } + + public function validate($value) + { + return (bool) preg_match('/^[\*,\/\-0-9]+$/', $value); + } +} diff --git a/vendor/mtdowling/cron-expression/src/Cron/MonthField.php b/vendor/mtdowling/cron-expression/src/Cron/MonthField.php new file mode 100644 index 0000000..0205c17 --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/MonthField.php @@ -0,0 +1,44 @@ +isSatisfied($date->format('m'), $value); + } + + public function increment(DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('last day of previous month'); + $date->setTime(23, 59); + } else { + $date->modify('first day of next month'); + $date->setTime(0, 0); + } + + return $this; + } + + public function validate($value) + { + return (bool) preg_match('/^[\*,\/\-0-9A-Z]+$/', $value); + } +} diff --git a/vendor/mtdowling/cron-expression/src/Cron/YearField.php b/vendor/mtdowling/cron-expression/src/Cron/YearField.php new file mode 100644 index 0000000..b526dde --- /dev/null +++ b/vendor/mtdowling/cron-expression/src/Cron/YearField.php @@ -0,0 +1,34 @@ +isSatisfied($date->format('Y'), $value); + } + + public function increment(\DateTime $date, $invert = false) + { + if ($invert) { + $date->modify('-1 year'); + $date->setDate($date->format('Y'), 12, 31); + $date->setTime(23, 59, 0); + } else { + $date->modify('+1 year'); + $date->setDate($date->format('Y'), 1, 1); + $date->setTime(0, 0, 0); + } + + return $this; + } + + public function validate($value) + { + return (bool) preg_match('/^[\*,\/\-0-9]+$/', $value); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/AbstractFieldTest.php b/vendor/mtdowling/cron-expression/tests/Cron/AbstractFieldTest.php new file mode 100644 index 0000000..5272106 --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/AbstractFieldTest.php @@ -0,0 +1,84 @@ + + */ +class AbstractFieldTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\AbstractField::isRange + */ + public function testTestsIfRange() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->isRange('1-2')); + $this->assertFalse($f->isRange('2')); + } + + /** + * @covers Cron\AbstractField::isIncrementsOfRanges + */ + public function testTestsIfIncrementsOfRanges() + { + $f = new DayOfWeekField(); + $this->assertFalse($f->isIncrementsOfRanges('1-2')); + $this->assertFalse($f->isIncrementsOfRanges('1-2')); + $this->assertTrue($f->isIncrementsOfRanges('1/2')); + $this->assertTrue($f->isIncrementsOfRanges('*/2')); + $this->assertTrue($f->isIncrementsOfRanges('3-12/2')); + } + + /** + * @covers Cron\AbstractField::isInRange + */ + public function testTestsIfInRange() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->isInRange(1, '1-2')); + $this->assertTrue($f->isInRange(2, '1-2')); + $this->assertTrue($f->isInRange(5, '4-12')); + $this->assertFalse($f->isInRange(3, '4-12')); + $this->assertFalse($f->isInRange(13, '4-12')); + } + + /** + * @covers Cron\AbstractField::isInIncrementsOfRanges + */ + public function testTestsIfInIncrementsOfRanges() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->isInIncrementsOfRanges(3, '3-59/2')); + $this->assertTrue($f->isInIncrementsOfRanges(13, '3-59/2')); + $this->assertTrue($f->isInIncrementsOfRanges(15, '3-59/2')); + $this->assertTrue($f->isInIncrementsOfRanges(14, '*/2')); + $this->assertFalse($f->isInIncrementsOfRanges(2, '3-59/13')); + $this->assertFalse($f->isInIncrementsOfRanges(14, '*/13')); + $this->assertFalse($f->isInIncrementsOfRanges(14, '3-59/2')); + $this->assertFalse($f->isInIncrementsOfRanges(3, '2-59')); + $this->assertFalse($f->isInIncrementsOfRanges(3, '2')); + $this->assertFalse($f->isInIncrementsOfRanges(3, '*')); + + $this->assertTrue($f->isInIncrementsOfRanges(4, '4/10')); + $this->assertTrue($f->isInIncrementsOfRanges(14, '4/10')); + $this->assertTrue($f->isInIncrementsOfRanges(34, '4/10')); + } + + /** + * @covers Cron\AbstractField::isSatisfied + */ + public function testTestsIfSatisfied() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->isSatisfied('12', '3-13')); + $this->assertTrue($f->isSatisfied('15', '3-59/12')); + $this->assertTrue($f->isSatisfied('12', '*')); + $this->assertTrue($f->isSatisfied('12', '12')); + $this->assertFalse($f->isSatisfied('12', '3-11')); + $this->assertFalse($f->isSatisfied('12', '3-59/13')); + $this->assertFalse($f->isSatisfied('12', '11')); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/CronExpressionTest.php b/vendor/mtdowling/cron-expression/tests/Cron/CronExpressionTest.php new file mode 100644 index 0000000..013b701 --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/CronExpressionTest.php @@ -0,0 +1,376 @@ + + */ +class CronExpressionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\CronExpression::factory + */ + public function testFactoryRecognizesTemplates() + { + $this->assertEquals('0 0 1 1 *', CronExpression::factory('@annually')->getExpression()); + $this->assertEquals('0 0 1 1 *', CronExpression::factory('@yearly')->getExpression()); + $this->assertEquals('0 0 * * 0', CronExpression::factory('@weekly')->getExpression()); + } + + /** + * @covers Cron\CronExpression::__construct + * @covers Cron\CronExpression::getExpression + * @covers Cron\CronExpression::__toString + */ + public function testParsesCronSchedule() + { + // '2010-09-10 12:00:00' + $cron = CronExpression::factory('1 2-4 * 4,5,6 */3'); + $this->assertEquals('1', $cron->getExpression(CronExpression::MINUTE)); + $this->assertEquals('2-4', $cron->getExpression(CronExpression::HOUR)); + $this->assertEquals('*', $cron->getExpression(CronExpression::DAY)); + $this->assertEquals('4,5,6', $cron->getExpression(CronExpression::MONTH)); + $this->assertEquals('*/3', $cron->getExpression(CronExpression::WEEKDAY)); + $this->assertEquals('1 2-4 * 4,5,6 */3', $cron->getExpression()); + $this->assertEquals('1 2-4 * 4,5,6 */3', (string) $cron); + $this->assertNull($cron->getExpression('foo')); + + try { + $cron = CronExpression::factory('A 1 2 3 4'); + $this->fail('Validation exception not thrown'); + } catch (InvalidArgumentException $e) { + } + } + + /** + * @covers Cron\CronExpression::__construct + * @covers Cron\CronExpression::getExpression + * @dataProvider scheduleWithDifferentSeparatorsProvider + */ + public function testParsesCronScheduleWithAnySpaceCharsAsSeparators($schedule, array $expected) + { + $cron = CronExpression::factory($schedule); + $this->assertEquals($expected[0], $cron->getExpression(CronExpression::MINUTE)); + $this->assertEquals($expected[1], $cron->getExpression(CronExpression::HOUR)); + $this->assertEquals($expected[2], $cron->getExpression(CronExpression::DAY)); + $this->assertEquals($expected[3], $cron->getExpression(CronExpression::MONTH)); + $this->assertEquals($expected[4], $cron->getExpression(CronExpression::WEEKDAY)); + $this->assertEquals($expected[5], $cron->getExpression(CronExpression::YEAR)); + } + + /** + * Data provider for testParsesCronScheduleWithAnySpaceCharsAsSeparators + * + * @return array + */ + public static function scheduleWithDifferentSeparatorsProvider() + { + return array( + array("*\t*\t*\t*\t*\t*", array('*', '*', '*', '*', '*', '*')), + array("* * * * * *", array('*', '*', '*', '*', '*', '*')), + array("* \t * \t * \t * \t * \t *", array('*', '*', '*', '*', '*', '*')), + array("*\t \t*\t \t*\t \t*\t \t*\t \t*", array('*', '*', '*', '*', '*', '*')), + ); + } + + /** + * @covers Cron\CronExpression::__construct + * @covers Cron\CronExpression::setExpression + * @covers Cron\CronExpression::setPart + * @expectedException InvalidArgumentException + */ + public function testInvalidCronsWillFail() + { + // Only four values + $cron = CronExpression::factory('* * * 1'); + } + + /** + * @covers Cron\CronExpression::setPart + * @expectedException InvalidArgumentException + */ + public function testInvalidPartsWillFail() + { + // Only four values + $cron = CronExpression::factory('* * * * *'); + $cron->setPart(1, 'abc'); + } + + /** + * Data provider for cron schedule + * + * @return array + */ + public function scheduleProvider() + { + return array( + array('*/2 */2 * * *', '2015-08-10 21:47:27', '2015-08-10 22:00:00', false), + array('* * * * *', '2015-08-10 21:50:37', '2015-08-10 21:50:00', true), + array('* 20,21,22 * * *', '2015-08-10 21:50:00', '2015-08-10 21:50:00', true), + // Handles CSV values + array('* 20,22 * * *', '2015-08-10 21:50:00', '2015-08-10 22:00:00', false), + // CSV values can be complex + array('* 5,21-22 * * *', '2015-08-10 21:50:00', '2015-08-10 21:50:00', true), + array('7-9 * */9 * *', '2015-08-10 22:02:33', '2015-08-18 00:07:00', false), + // 15th minute, of the second hour, every 15 days, in January, every Friday + array('1 * * * 7', '2015-08-10 21:47:27', '2015-08-16 00:01:00', false), + // Test with exact times + array('47 21 * * *', strtotime('2015-08-10 21:47:30'), '2015-08-10 21:47:00', true), + // Test Day of the week (issue #1) + // According cron implementation, 0|7 = sunday, 1 => monday, etc + array('* * * * 0', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), + array('* * * * 7', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), + array('* * * * 1', strtotime('2011-06-15 23:09:00'), '2011-06-20 00:00:00', false), + // Should return the sunday date as 7 equals 0 + array('0 0 * * MON,SUN', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), + array('0 0 * * 1,7', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), + array('0 0 * * 0-4', strtotime('2011-06-15 23:09:00'), '2011-06-16 00:00:00', false), + array('0 0 * * 7-4', strtotime('2011-06-15 23:09:00'), '2011-06-16 00:00:00', false), + array('0 0 * * 4-7', strtotime('2011-06-15 23:09:00'), '2011-06-16 00:00:00', false), + array('0 0 * * 7-3', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), + array('0 0 * * 3-7', strtotime('2011-06-15 23:09:00'), '2011-06-16 00:00:00', false), + array('0 0 * * 3-7', strtotime('2011-06-18 23:09:00'), '2011-06-19 00:00:00', false), + // Test lists of values and ranges (Abhoryo) + array('0 0 * * 2-7', strtotime('2011-06-20 23:09:00'), '2011-06-21 00:00:00', false), + array('0 0 * * 0,2-6', strtotime('2011-06-20 23:09:00'), '2011-06-21 00:00:00', false), + array('0 0 * * 2-7', strtotime('2011-06-18 23:09:00'), '2011-06-19 00:00:00', false), + array('0 0 * * 4-7', strtotime('2011-07-19 00:00:00'), '2011-07-21 00:00:00', false), + // Test increments of ranges + array('0-12/4 * * * *', strtotime('2011-06-20 12:04:00'), '2011-06-20 12:04:00', true), + array('4-59/2 * * * *', strtotime('2011-06-20 12:04:00'), '2011-06-20 12:04:00', true), + array('4-59/2 * * * *', strtotime('2011-06-20 12:06:00'), '2011-06-20 12:06:00', true), + array('4-59/3 * * * *', strtotime('2011-06-20 12:06:00'), '2011-06-20 12:07:00', false), + //array('0 0 * * 0,2-6', strtotime('2011-06-20 23:09:00'), '2011-06-21 00:00:00', false), + // Test Day of the Week and the Day of the Month (issue #1) + array('0 0 1 1 0', strtotime('2011-06-15 23:09:00'), '2012-01-01 00:00:00', false), + array('0 0 1 JAN 0', strtotime('2011-06-15 23:09:00'), '2012-01-01 00:00:00', false), + array('0 0 1 * 0', strtotime('2011-06-15 23:09:00'), '2012-01-01 00:00:00', false), + array('0 0 L * *', strtotime('2011-07-15 00:00:00'), '2011-07-31 00:00:00', false), + // Test the W day of the week modifier for day of the month field + array('0 0 2W * *', strtotime('2011-07-01 00:00:00'), '2011-07-01 00:00:00', true), + array('0 0 1W * *', strtotime('2011-05-01 00:00:00'), '2011-05-02 00:00:00', false), + array('0 0 1W * *', strtotime('2011-07-01 00:00:00'), '2011-07-01 00:00:00', true), + array('0 0 3W * *', strtotime('2011-07-01 00:00:00'), '2011-07-04 00:00:00', false), + array('0 0 16W * *', strtotime('2011-07-01 00:00:00'), '2011-07-15 00:00:00', false), + array('0 0 28W * *', strtotime('2011-07-01 00:00:00'), '2011-07-28 00:00:00', false), + array('0 0 30W * *', strtotime('2011-07-01 00:00:00'), '2011-07-29 00:00:00', false), + array('0 0 31W * *', strtotime('2011-07-01 00:00:00'), '2011-07-29 00:00:00', false), + // Test the year field + array('* * * * * 2012', strtotime('2011-05-01 00:00:00'), '2012-01-01 00:00:00', false), + // Test the last weekday of a month + array('* * * * 5L', strtotime('2011-07-01 00:00:00'), '2011-07-29 00:00:00', false), + array('* * * * 6L', strtotime('2011-07-01 00:00:00'), '2011-07-30 00:00:00', false), + array('* * * * 7L', strtotime('2011-07-01 00:00:00'), '2011-07-31 00:00:00', false), + array('* * * * 1L', strtotime('2011-07-24 00:00:00'), '2011-07-25 00:00:00', false), + array('* * * * TUEL', strtotime('2011-07-24 00:00:00'), '2011-07-26 00:00:00', false), + array('* * * 1 5L', strtotime('2011-12-25 00:00:00'), '2012-01-27 00:00:00', false), + // Test the hash symbol for the nth weekday of a given month + array('* * * * 5#2', strtotime('2011-07-01 00:00:00'), '2011-07-08 00:00:00', false), + array('* * * * 5#1', strtotime('2011-07-01 00:00:00'), '2011-07-01 00:00:00', true), + array('* * * * 3#4', strtotime('2011-07-01 00:00:00'), '2011-07-27 00:00:00', false), + ); + } + + /** + * @covers Cron\CronExpression::isDue + * @covers Cron\CronExpression::getNextRunDate + * @covers Cron\DayOfMonthField + * @covers Cron\DayOfWeekField + * @covers Cron\MinutesField + * @covers Cron\HoursField + * @covers Cron\MonthField + * @covers Cron\YearField + * @covers Cron\CronExpression::getRunDate + * @dataProvider scheduleProvider + */ + public function testDeterminesIfCronIsDue($schedule, $relativeTime, $nextRun, $isDue) + { + $relativeTimeString = is_int($relativeTime) ? date('Y-m-d H:i:s', $relativeTime) : $relativeTime; + + // Test next run date + $cron = CronExpression::factory($schedule); + if (is_string($relativeTime)) { + $relativeTime = new DateTime($relativeTime); + } elseif (is_int($relativeTime)) { + $relativeTime = date('Y-m-d H:i:s', $relativeTime); + } + $this->assertEquals($isDue, $cron->isDue($relativeTime)); + $next = $cron->getNextRunDate($relativeTime, 0, true); + $this->assertEquals(new DateTime($nextRun), $next); + } + + /** + * @covers Cron\CronExpression::isDue + */ + public function testIsDueHandlesDifferentDates() + { + $cron = CronExpression::factory('* * * * *'); + $this->assertTrue($cron->isDue()); + $this->assertTrue($cron->isDue('now')); + $this->assertTrue($cron->isDue(new DateTime('now'))); + $this->assertTrue($cron->isDue(date('Y-m-d H:i'))); + } + + /** + * @covers Cron\CronExpression::isDue + */ + public function testIsDueHandlesDifferentTimezones() + { + $cron = CronExpression::factory('0 15 * * 3'); //Wednesday at 15:00 + $date = '2014-01-01 15:00'; //Wednesday + $utc = new \DateTimeZone('UTC'); + $amsterdam = new \DateTimeZone('Europe/Amsterdam'); + $tokyo = new \DateTimeZone('Asia/Tokyo'); + + date_default_timezone_set('UTC'); + $this->assertTrue($cron->isDue(new DateTime($date, $utc))); + $this->assertFalse($cron->isDue(new DateTime($date, $amsterdam))); + $this->assertFalse($cron->isDue(new DateTime($date, $tokyo))); + + date_default_timezone_set('Europe/Amsterdam'); + $this->assertFalse($cron->isDue(new DateTime($date, $utc))); + $this->assertTrue($cron->isDue(new DateTime($date, $amsterdam))); + $this->assertFalse($cron->isDue(new DateTime($date, $tokyo))); + + date_default_timezone_set('Asia/Tokyo'); + $this->assertFalse($cron->isDue(new DateTime($date, $utc))); + $this->assertFalse($cron->isDue(new DateTime($date, $amsterdam))); + $this->assertTrue($cron->isDue(new DateTime($date, $tokyo))); + } + + /** + * @covers Cron\CronExpression::getPreviousRunDate + */ + public function testCanGetPreviousRunDates() + { + $cron = CronExpression::factory('* * * * *'); + $next = $cron->getNextRunDate('now'); + $two = $cron->getNextRunDate('now', 1); + $this->assertEquals($next, $cron->getPreviousRunDate($two)); + + $cron = CronExpression::factory('* */2 * * *'); + $next = $cron->getNextRunDate('now'); + $two = $cron->getNextRunDate('now', 1); + $this->assertEquals($next, $cron->getPreviousRunDate($two)); + + $cron = CronExpression::factory('* * * */2 *'); + $next = $cron->getNextRunDate('now'); + $two = $cron->getNextRunDate('now', 1); + $this->assertEquals($next, $cron->getPreviousRunDate($two)); + } + + /** + * @covers Cron\CronExpression::getMultipleRunDates + */ + public function testProvidesMultipleRunDates() + { + $cron = CronExpression::factory('*/2 * * * *'); + $this->assertEquals(array( + new DateTime('2008-11-09 00:00:00'), + new DateTime('2008-11-09 00:02:00'), + new DateTime('2008-11-09 00:04:00'), + new DateTime('2008-11-09 00:06:00') + ), $cron->getMultipleRunDates(4, '2008-11-09 00:00:00', false, true)); + } + + /** + * @covers Cron\CronExpression + */ + public function testCanIterateOverNextRuns() + { + $cron = CronExpression::factory('@weekly'); + $nextRun = $cron->getNextRunDate("2008-11-09 08:00:00"); + $this->assertEquals($nextRun, new DateTime("2008-11-16 00:00:00")); + + // true is cast to 1 + $nextRun = $cron->getNextRunDate("2008-11-09 00:00:00", true, true); + $this->assertEquals($nextRun, new DateTime("2008-11-16 00:00:00")); + + // You can iterate over them + $nextRun = $cron->getNextRunDate($cron->getNextRunDate("2008-11-09 00:00:00", 1, true), 1, true); + $this->assertEquals($nextRun, new DateTime("2008-11-23 00:00:00")); + + // You can skip more than one + $nextRun = $cron->getNextRunDate("2008-11-09 00:00:00", 2, true); + $this->assertEquals($nextRun, new DateTime("2008-11-23 00:00:00")); + $nextRun = $cron->getNextRunDate("2008-11-09 00:00:00", 3, true); + $this->assertEquals($nextRun, new DateTime("2008-11-30 00:00:00")); + } + + /** + * @covers Cron\CronExpression::getRunDate + */ + public function testSkipsCurrentDateByDefault() + { + $cron = CronExpression::factory('* * * * *'); + $current = new DateTime('now'); + $next = $cron->getNextRunDate($current); + $nextPrev = $cron->getPreviousRunDate($next); + $this->assertEquals($current->format('Y-m-d H:i:00'), $nextPrev->format('Y-m-d H:i:s')); + } + + /** + * @covers Cron\CronExpression::getRunDate + * @ticket 7 + */ + public function testStripsForSeconds() + { + $cron = CronExpression::factory('* * * * *'); + $current = new DateTime('2011-09-27 10:10:54'); + $this->assertEquals('2011-09-27 10:11:00', $cron->getNextRunDate($current)->format('Y-m-d H:i:s')); + } + + /** + * @covers Cron\CronExpression::getRunDate + */ + public function testFixesPhpBugInDateIntervalMonth() + { + $cron = CronExpression::factory('0 0 27 JAN *'); + $this->assertEquals('2011-01-27 00:00:00', $cron->getPreviousRunDate('2011-08-22 00:00:00')->format('Y-m-d H:i:s')); + } + + public function testIssue29() + { + $cron = CronExpression::factory('@weekly'); + $this->assertEquals( + '2013-03-10 00:00:00', + $cron->getPreviousRunDate('2013-03-17 00:00:00')->format('Y-m-d H:i:s') + ); + } + + /** + * @see https://github.com/mtdowling/cron-expression/issues/20 + */ + public function testIssue20() { + $e = CronExpression::factory('* * * * MON#1'); + $this->assertTrue($e->isDue(new DateTime('2014-04-07 00:00:00'))); + $this->assertFalse($e->isDue(new DateTime('2014-04-14 00:00:00'))); + $this->assertFalse($e->isDue(new DateTime('2014-04-21 00:00:00'))); + + $e = CronExpression::factory('* * * * SAT#2'); + $this->assertFalse($e->isDue(new DateTime('2014-04-05 00:00:00'))); + $this->assertTrue($e->isDue(new DateTime('2014-04-12 00:00:00'))); + $this->assertFalse($e->isDue(new DateTime('2014-04-19 00:00:00'))); + + $e = CronExpression::factory('* * * * SUN#3'); + $this->assertFalse($e->isDue(new DateTime('2014-04-13 00:00:00'))); + $this->assertTrue($e->isDue(new DateTime('2014-04-20 00:00:00'))); + $this->assertFalse($e->isDue(new DateTime('2014-04-27 00:00:00'))); + } + + /** + * @covers Cron\CronExpression::getRunDate + */ + public function testKeepOriginalTime() + { + $now = new \DateTime; + $strNow = $now->format(\DateTime::ISO8601); + $cron = CronExpression::factory('0 0 * * *'); + $cron->getPreviousRunDate($now); + $this->assertEquals($strNow, $now->format(\DateTime::ISO8601)); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/DayOfMonthFieldTest.php b/vendor/mtdowling/cron-expression/tests/Cron/DayOfMonthFieldTest.php new file mode 100644 index 0000000..94afbb0 --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/DayOfMonthFieldTest.php @@ -0,0 +1,50 @@ + + */ +class DayOfMonthFieldTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\DayOfMonthField::validate + */ + public function testValdatesField() + { + $f = new DayOfMonthField(); + $this->assertTrue($f->validate('1')); + $this->assertTrue($f->validate('*')); + $this->assertTrue($f->validate('*/3,1,1-12')); + $this->assertTrue($f->validate('5W,L')); + $this->assertFalse($f->validate('1.')); + } + + /** + * @covers Cron\DayOfMonthField::isSatisfiedBy + */ + public function testChecksIfSatisfied() + { + $f = new DayOfMonthField(); + $this->assertTrue($f->isSatisfiedBy(new DateTime(), '?')); + } + + /** + * @covers Cron\DayOfMonthField::increment + */ + public function testIncrementsDate() + { + $d = new DateTime('2011-03-15 11:15:00'); + $f = new DayOfMonthField(); + $f->increment($d); + $this->assertEquals('2011-03-16 00:00:00', $d->format('Y-m-d H:i:s')); + + $d = new DateTime('2011-03-15 11:15:00'); + $f->increment($d, true); + $this->assertEquals('2011-03-14 23:59:00', $d->format('Y-m-d H:i:s')); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/DayOfWeekFieldTest.php b/vendor/mtdowling/cron-expression/tests/Cron/DayOfWeekFieldTest.php new file mode 100644 index 0000000..703a517 --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/DayOfWeekFieldTest.php @@ -0,0 +1,116 @@ + + */ +class DayOfWeekFieldTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\DayOfWeekField::validate + */ + public function testValidatesField() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->validate('1')); + $this->assertTrue($f->validate('*')); + $this->assertTrue($f->validate('*/3,1,1-12')); + $this->assertTrue($f->validate('SUN-2')); + $this->assertFalse($f->validate('1.')); + } + + /** + * @covers Cron\DayOfWeekField::isSatisfiedBy + */ + public function testChecksIfSatisfied() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->isSatisfiedBy(new DateTime(), '?')); + } + + /** + * @covers Cron\DayOfWeekField::increment + */ + public function testIncrementsDate() + { + $d = new DateTime('2011-03-15 11:15:00'); + $f = new DayOfWeekField(); + $f->increment($d); + $this->assertEquals('2011-03-16 00:00:00', $d->format('Y-m-d H:i:s')); + + $d = new DateTime('2011-03-15 11:15:00'); + $f->increment($d, true); + $this->assertEquals('2011-03-14 23:59:00', $d->format('Y-m-d H:i:s')); + } + + /** + * @covers Cron\DayOfWeekField::isSatisfiedBy + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Weekday must be a value between 0 and 7. 12 given + */ + public function testValidatesHashValueWeekday() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->isSatisfiedBy(new DateTime(), '12#1')); + } + + /** + * @covers Cron\DayOfWeekField::isSatisfiedBy + * @expectedException InvalidArgumentException + * @expectedExceptionMessage There are never more than 5 of a given weekday in a month + */ + public function testValidatesHashValueNth() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->isSatisfiedBy(new DateTime(), '3#6')); + } + + /** + * @covers Cron\DayOfWeekField::validate + */ + public function testValidateWeekendHash() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->validate('MON#1')); + $this->assertTrue($f->validate('TUE#2')); + $this->assertTrue($f->validate('WED#3')); + $this->assertTrue($f->validate('THU#4')); + $this->assertTrue($f->validate('FRI#5')); + $this->assertTrue($f->validate('SAT#1')); + $this->assertTrue($f->validate('SUN#3')); + $this->assertTrue($f->validate('MON#1,MON#3')); + } + + /** + * @covers Cron\DayOfWeekField::isSatisfiedBy + */ + public function testHandlesZeroAndSevenDayOfTheWeekValues() + { + $f = new DayOfWeekField(); + $this->assertTrue($f->isSatisfiedBy(new DateTime('2011-09-04 00:00:00'), '0-2')); + $this->assertTrue($f->isSatisfiedBy(new DateTime('2011-09-04 00:00:00'), '6-0')); + + $this->assertTrue($f->isSatisfiedBy(new DateTime('2014-04-20 00:00:00'), 'SUN')); + $this->assertTrue($f->isSatisfiedBy(new DateTime('2014-04-20 00:00:00'), 'SUN#3')); + $this->assertTrue($f->isSatisfiedBy(new DateTime('2014-04-20 00:00:00'), '0#3')); + $this->assertTrue($f->isSatisfiedBy(new DateTime('2014-04-20 00:00:00'), '7#3')); + } + + /** + * @see https://github.com/mtdowling/cron-expression/issues/47 + */ + public function testIssue47() { + $f = new DayOfWeekField(); + $this->assertFalse($f->validate('mon,')); + $this->assertFalse($f->validate('mon-')); + $this->assertFalse($f->validate('*/2,')); + $this->assertFalse($f->validate('-mon')); + $this->assertFalse($f->validate(',1')); + $this->assertFalse($f->validate('*-')); + $this->assertFalse($f->validate(',-')); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/FieldFactoryTest.php b/vendor/mtdowling/cron-expression/tests/Cron/FieldFactoryTest.php new file mode 100644 index 0000000..ec087b1 --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/FieldFactoryTest.php @@ -0,0 +1,42 @@ + + */ +class FieldFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\FieldFactory::getField + */ + public function testRetrievesFieldInstances() + { + $mappings = array( + 0 => 'Cron\MinutesField', + 1 => 'Cron\HoursField', + 2 => 'Cron\DayOfMonthField', + 3 => 'Cron\MonthField', + 4 => 'Cron\DayOfWeekField', + 5 => 'Cron\YearField' + ); + + $f = new FieldFactory(); + + foreach ($mappings as $position => $class) { + $this->assertEquals($class, get_class($f->getField($position))); + } + } + + /** + * @covers Cron\FieldFactory::getField + * @expectedException InvalidArgumentException + */ + public function testValidatesFieldPosition() + { + $f = new FieldFactory(); + $f->getField(-1); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/HoursFieldTest.php b/vendor/mtdowling/cron-expression/tests/Cron/HoursFieldTest.php new file mode 100644 index 0000000..48bd135 --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/HoursFieldTest.php @@ -0,0 +1,38 @@ + + */ +class HoursFieldTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\HoursField::validate + */ + public function testValdatesField() + { + $f = new HoursField(); + $this->assertTrue($f->validate('1')); + $this->assertTrue($f->validate('*')); + $this->assertTrue($f->validate('*/3,1,1-12')); + } + + /** + * @covers Cron\HoursField::increment + */ + public function testIncrementsDate() + { + $d = new DateTime('2011-03-15 11:15:00'); + $f = new HoursField(); + $f->increment($d); + $this->assertEquals('2011-03-15 12:00:00', $d->format('Y-m-d H:i:s')); + + $d->setTime(11, 15, 0); + $f->increment($d, true); + $this->assertEquals('2011-03-15 10:59:00', $d->format('Y-m-d H:i:s')); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/MinutesFieldTest.php b/vendor/mtdowling/cron-expression/tests/Cron/MinutesFieldTest.php new file mode 100644 index 0000000..82ce966 --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/MinutesFieldTest.php @@ -0,0 +1,36 @@ + + */ +class MinutesFieldTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\MinutesField::validate + */ + public function testValdatesField() + { + $f = new MinutesField(); + $this->assertTrue($f->validate('1')); + $this->assertTrue($f->validate('*')); + $this->assertTrue($f->validate('*/3,1,1-12')); + } + + /** + * @covers Cron\MinutesField::increment + */ + public function testIncrementsDate() + { + $d = new DateTime('2011-03-15 11:15:00'); + $f = new MinutesField(); + $f->increment($d); + $this->assertEquals('2011-03-15 11:16:00', $d->format('Y-m-d H:i:s')); + $f->increment($d, true); + $this->assertEquals('2011-03-15 11:15:00', $d->format('Y-m-d H:i:s')); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/MonthFieldTest.php b/vendor/mtdowling/cron-expression/tests/Cron/MonthFieldTest.php new file mode 100644 index 0000000..82878f8 --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/MonthFieldTest.php @@ -0,0 +1,61 @@ + + */ +class MonthFieldTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\MonthField::validate + */ + public function testValdatesField() + { + $f = new MonthField(); + $this->assertTrue($f->validate('12')); + $this->assertTrue($f->validate('*')); + $this->assertTrue($f->validate('*/10,2,1-12')); + $this->assertFalse($f->validate('1.fix-regexp')); + } + + /** + * @covers Cron\MonthField::increment + */ + public function testIncrementsDate() + { + $d = new DateTime('2011-03-15 11:15:00'); + $f = new MonthField(); + $f->increment($d); + $this->assertEquals('2011-04-01 00:00:00', $d->format('Y-m-d H:i:s')); + + $d = new DateTime('2011-03-15 11:15:00'); + $f->increment($d, true); + $this->assertEquals('2011-02-28 23:59:00', $d->format('Y-m-d H:i:s')); + } + + /** + * @covers Cron\MonthField::increment + */ + public function testIncrementsYearAsNeeded() + { + $f = new MonthField(); + $d = new DateTime('2011-12-15 00:00:00'); + $f->increment($d); + $this->assertEquals('2012-01-01 00:00:00', $d->format('Y-m-d H:i:s')); + } + + /** + * @covers Cron\MonthField::increment + */ + public function testDecrementsYearAsNeeded() + { + $f = new MonthField(); + $d = new DateTime('2011-01-15 00:00:00'); + $f->increment($d, true); + $this->assertEquals('2010-12-31 23:59:00', $d->format('Y-m-d H:i:s')); + } +} diff --git a/vendor/mtdowling/cron-expression/tests/Cron/YearFieldTest.php b/vendor/mtdowling/cron-expression/tests/Cron/YearFieldTest.php new file mode 100644 index 0000000..e7bcacb --- /dev/null +++ b/vendor/mtdowling/cron-expression/tests/Cron/YearFieldTest.php @@ -0,0 +1,36 @@ + + */ +class YearFieldTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers Cron\YearField::validate + */ + public function testValdatesField() + { + $f = new YearField(); + $this->assertTrue($f->validate('2011')); + $this->assertTrue($f->validate('*')); + $this->assertTrue($f->validate('*/10,2012,1-12')); + } + + /** + * @covers Cron\YearField::increment + */ + public function testIncrementsDate() + { + $d = new DateTime('2011-03-15 11:15:00'); + $f = new YearField(); + $f->increment($d); + $this->assertEquals('2012-01-01 00:00:00', $d->format('Y-m-d H:i:s')); + $f->increment($d, true); + $this->assertEquals('2011-12-31 23:59:00', $d->format('Y-m-d H:i:s')); + } +} diff --git a/vendor/nesbot/carbon/.editorconfig b/vendor/nesbot/carbon/.editorconfig new file mode 100644 index 0000000..1533dae --- /dev/null +++ b/vendor/nesbot/carbon/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +trim_trailing_whitespace = true +insert_final_newline = true + +[*.php] +charset = utf-8 +indent_style = space +indent_size = 4 + +[composer.json] +indent_style = space +indent_size = 2 diff --git a/vendor/nesbot/carbon/LICENSE b/vendor/nesbot/carbon/LICENSE new file mode 100644 index 0000000..6de45eb --- /dev/null +++ b/vendor/nesbot/carbon/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) Brian Nesbitt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/nesbot/carbon/composer.json b/vendor/nesbot/carbon/composer.json new file mode 100644 index 0000000..e44aa8d --- /dev/null +++ b/vendor/nesbot/carbon/composer.json @@ -0,0 +1,31 @@ +{ + "name": "nesbot/carbon", + "type": "library", + "description": "A simple API extension for DateTime.", + "keywords": [ + "date", + "time", + "DateTime" + ], + "homepage": "http://carbon.nesbot.com", + "license": "MIT", + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "http://nesbot.com" + } + ], + "require": { + "php": ">=5.3.0", + "symfony/translation": "~2.6|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "autoload": { + "psr-0": { + "Carbon": "src" + } + } +} diff --git a/vendor/nesbot/carbon/readme.md b/vendor/nesbot/carbon/readme.md new file mode 100644 index 0000000..e705936 --- /dev/null +++ b/vendor/nesbot/carbon/readme.md @@ -0,0 +1,81 @@ +# Carbon + +[![Latest Stable Version](https://poser.pugx.org/nesbot/carbon/v/stable.png)](https://packagist.org/packages/nesbot/carbon) [![Total Downloads](https://poser.pugx.org/nesbot/carbon/downloads.png)](https://packagist.org/packages/nesbot/carbon) [![Build Status](https://travis-ci.org/briannesbitt/Carbon.svg?branch=master)](https://travis-ci.org/briannesbitt/Carbon) + +A simple PHP API extension for DateTime. [http://carbon.nesbot.com](http://carbon.nesbot.com) + +```php +printf("Right now is %s", Carbon::now()->toDateTimeString()); +printf("Right now in Vancouver is %s", Carbon::now('America/Vancouver')); //implicit __toString() +$tomorrow = Carbon::now()->addDay(); +$lastWeek = Carbon::now()->subWeek(); +$nextSummerOlympics = Carbon::createFromDate(2012)->addYears(4); + +$officialDate = Carbon::now()->toRfc2822String(); + +$howOldAmI = Carbon::createFromDate(1975, 5, 21)->age; + +$noonTodayLondonTime = Carbon::createFromTime(12, 0, 0, 'Europe/London'); + +$worldWillEnd = Carbon::createFromDate(2012, 12, 21, 'GMT'); + +// Don't really want to die so mock now +Carbon::setTestNow(Carbon::createFromDate(2000, 1, 1)); + +// comparisons are always done in UTC +if (Carbon::now()->gte($worldWillEnd)) { + die(); +} + +// Phew! Return to normal behaviour +Carbon::setTestNow(); + +if (Carbon::now()->isWeekend()) { + echo 'Party!'; +} +echo Carbon::now()->subMinutes(2)->diffForHumans(); // '2 minutes ago' + +// ... but also does 'from now', 'after' and 'before' +// rolling up to seconds, minutes, hours, days, months, years + +$daysSinceEpoch = Carbon::createFromTimeStamp(0)->diffInDays(); +``` + +## Installation + +### With Composer + +``` +$ composer require nesbot/carbon +``` + +```json +{ + "require": { + "nesbot/carbon": "~1.14" + } +} +``` + +```php + +### Without Composer + +Why are you not using [composer](http://getcomposer.org/)? Download [Carbon.php](https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Carbon.php) from the repo and save the file into your project path somewhere. + +```php + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Carbon; + +use Closure; +use DateTime; +use DateTimeZone; +use DatePeriod; +use InvalidArgumentException; +use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\TranslatorInterface; +use Symfony\Component\Translation\Loader\ArrayLoader; + +/** + * A simple API extension for DateTime + * + * @property integer $year + * @property integer $yearIso + * @property integer $month + * @property integer $day + * @property integer $hour + * @property integer $minute + * @property integer $second + * @property integer $timestamp seconds since the Unix Epoch + * @property DateTimeZone $timezone the current timezone + * @property DateTimeZone $tz alias of timezone + * @property-read integer $micro + * @property-read integer $dayOfWeek 0 (for Sunday) through 6 (for Saturday) + * @property-read integer $dayOfYear 0 through 365 + * @property-read integer $weekOfMonth 1 through 5 + * @property-read integer $weekOfYear ISO-8601 week number of year, weeks starting on Monday + * @property-read integer $daysInMonth number of days in the given month + * @property-read integer $age does a diffInYears() with default parameters + * @property-read integer $quarter the quarter of this instance, 1 - 4 + * @property-read integer $offset the timezone offset in seconds from UTC + * @property-read integer $offsetHours the timezone offset in hours from UTC + * @property-read boolean $dst daylight savings time indicator, true if DST, false otherwise + * @property-read boolean $local checks if the timezone is local, true if local, false otherwise + * @property-read boolean $utc checks if the timezone is UTC, true if UTC, false otherwise + * @property-read string $timezoneName + * @property-read string $tzName + */ +class Carbon extends DateTime +{ + /** + * The day constants + */ + const SUNDAY = 0; + const MONDAY = 1; + const TUESDAY = 2; + const WEDNESDAY = 3; + const THURSDAY = 4; + const FRIDAY = 5; + const SATURDAY = 6; + + /** + * Names of days of the week. + * + * @var array + */ + protected static $days = array( + self::SUNDAY => 'Sunday', + self::MONDAY => 'Monday', + self::TUESDAY => 'Tuesday', + self::WEDNESDAY => 'Wednesday', + self::THURSDAY => 'Thursday', + self::FRIDAY => 'Friday', + self::SATURDAY => 'Saturday', + ); + + /** + * Terms used to detect if a time passed is a relative date for testing purposes + * + * @var array + */ + protected static $relativeKeywords = array( + 'this', + 'next', + 'last', + 'tomorrow', + 'yesterday', + '+', + '-', + 'first', + 'last', + 'ago', + ); + + /** + * Number of X in Y + */ + const YEARS_PER_CENTURY = 100; + const YEARS_PER_DECADE = 10; + const MONTHS_PER_YEAR = 12; + const WEEKS_PER_YEAR = 52; + const DAYS_PER_WEEK = 7; + const HOURS_PER_DAY = 24; + const MINUTES_PER_HOUR = 60; + const SECONDS_PER_MINUTE = 60; + + /** + * Default format to use for __toString method when type juggling occurs. + * + * @var string + */ + const DEFAULT_TO_STRING_FORMAT = 'Y-m-d H:i:s'; + + /** + * Format to use for __toString method when type juggling occurs. + * + * @var string + */ + protected static $toStringFormat = self::DEFAULT_TO_STRING_FORMAT; + + + /** + * First day of week + * + * @var int + */ + protected static $weekStartsAt = self::MONDAY; + + /** + * Last day of week + * + * @var int + */ + protected static $weekEndsAt = self::SUNDAY; + + /** + * Days of weekend + * + * @var array + */ + protected static $weekendDays = array(self::SATURDAY, self::SUNDAY); + + /** + * A test Carbon instance to be returned when now instances are created + * + * @var Carbon + */ + protected static $testNow; + + /** + * A translator to ... er ... translate stuff + * + * @var TranslatorInterface + */ + protected static $translator; + + /** + * Creates a DateTimeZone from a string or a DateTimeZone + * + * @param DateTimeZone|string|null $object + * + * @return DateTimeZone + * + * @throws InvalidArgumentException + */ + protected static function safeCreateDateTimeZone($object) + { + if ($object === null) { + // Don't return null... avoid Bug #52063 in PHP <5.3.6 + return new DateTimeZone(date_default_timezone_get()); + } + + if ($object instanceof DateTimeZone) { + return $object; + } + + $tz = @timezone_open((string) $object); + + if ($tz === false) { + throw new InvalidArgumentException('Unknown or bad timezone ('.$object.')'); + } + + return $tz; + } + + /////////////////////////////////////////////////////////////////// + //////////////////////////// CONSTRUCTORS ///////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Create a new Carbon instance. + * + * Please see the testing aids section (specifically static::setTestNow()) + * for more on the possibility of this constructor returning a test instance. + * + * @param string $time + * @param DateTimeZone|string $tz + */ + public function __construct($time = null, $tz = null) + { + // If the class has a test now set and we are trying to create a now() + // instance then override as required + if (static::hasTestNow() && (empty($time) || $time === 'now' || static::hasRelativeKeywords($time))) { + $testInstance = clone static::getTestNow(); + if (static::hasRelativeKeywords($time)) { + $testInstance->modify($time); + } + + //shift the time according to the given time zone + if ($tz !== NULL && $tz != static::getTestNow()->tz) { + $testInstance->setTimezone($tz); + } else { + $tz = $testInstance->tz; + } + + $time = $testInstance->toDateTimeString(); + } + + parent::__construct($time, static::safeCreateDateTimeZone($tz)); + } + + /** + * Create a Carbon instance from a DateTime one + * + * @param DateTime $dt + * + * @return static + */ + public static function instance(DateTime $dt) + { + return new static($dt->format('Y-m-d H:i:s.u'), $dt->getTimeZone()); + } + + /** + * Create a carbon instance from a string. This is an alias for the + * constructor that allows better fluent syntax as it allows you to do + * Carbon::parse('Monday next week')->fn() rather than + * (new Carbon('Monday next week'))->fn() + * + * @param string $time + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function parse($time = null, $tz = null) + { + return new static($time, $tz); + } + + /** + * Get a Carbon instance for the current date and time + * + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function now($tz = null) + { + return new static(null, $tz); + } + + /** + * Create a Carbon instance for today + * + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function today($tz = null) + { + return static::now($tz)->startOfDay(); + } + + /** + * Create a Carbon instance for tomorrow + * + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function tomorrow($tz = null) + { + return static::today($tz)->addDay(); + } + + /** + * Create a Carbon instance for yesterday + * + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function yesterday($tz = null) + { + return static::today($tz)->subDay(); + } + + /** + * Create a Carbon instance for the greatest supported date. + * + * @return Carbon + */ + public static function maxValue() + { + return static::createFromTimestamp(PHP_INT_MAX); + } + + /** + * Create a Carbon instance for the lowest supported date. + * + * @return Carbon + */ + public static function minValue() + { + return static::createFromTimestamp(~PHP_INT_MAX); + } + + /** + * Create a new Carbon instance from a specific date and time. + * + * If any of $year, $month or $day are set to null their now() values + * will be used. + * + * If $hour is null it will be set to its now() value and the default values + * for $minute and $second will be their now() values. + * If $hour is not null then the default values for $minute and $second + * will be 0. + * + * @param integer $year + * @param integer $month + * @param integer $day + * @param integer $hour + * @param integer $minute + * @param integer $second + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function create($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null) + { + $year = ($year === null) ? date('Y') : $year; + $month = ($month === null) ? date('n') : $month; + $day = ($day === null) ? date('j') : $day; + + if ($hour === null) { + $hour = date('G'); + $minute = ($minute === null) ? date('i') : $minute; + $second = ($second === null) ? date('s') : $second; + } else { + $minute = ($minute === null) ? 0 : $minute; + $second = ($second === null) ? 0 : $second; + } + + return static::createFromFormat('Y-n-j G:i:s', sprintf('%s-%s-%s %s:%02s:%02s', $year, $month, $day, $hour, $minute, $second), $tz); + } + + /** + * Create a Carbon instance from just a date. The time portion is set to now. + * + * @param integer $year + * @param integer $month + * @param integer $day + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function createFromDate($year = null, $month = null, $day = null, $tz = null) + { + return static::create($year, $month, $day, null, null, null, $tz); + } + + /** + * Create a Carbon instance from just a time. The date portion is set to today. + * + * @param integer $hour + * @param integer $minute + * @param integer $second + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function createFromTime($hour = null, $minute = null, $second = null, $tz = null) + { + return static::create(null, null, null, $hour, $minute, $second, $tz); + } + + /** + * Create a Carbon instance from a specific format + * + * @param string $format + * @param string $time + * @param DateTimeZone|string $tz + * + * @return static + * + * @throws InvalidArgumentException + */ + public static function createFromFormat($format, $time, $tz = null) + { + if ($tz !== null) { + $dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz)); + } else { + $dt = parent::createFromFormat($format, $time); + } + + if ($dt instanceof DateTime) { + return static::instance($dt); + } + + $errors = static::getLastErrors(); + throw new InvalidArgumentException(implode(PHP_EOL, $errors['errors'])); + } + + /** + * Create a Carbon instance from a timestamp + * + * @param integer $timestamp + * @param DateTimeZone|string $tz + * + * @return static + */ + public static function createFromTimestamp($timestamp, $tz = null) + { + return static::now($tz)->setTimestamp($timestamp); + } + + /** + * Create a Carbon instance from an UTC timestamp + * + * @param integer $timestamp + * + * @return static + */ + public static function createFromTimestampUTC($timestamp) + { + return new static('@'.$timestamp); + } + + /** + * Get a copy of the instance + * + * @return static + */ + public function copy() + { + return static::instance($this); + } + + /////////////////////////////////////////////////////////////////// + ///////////////////////// GETTERS AND SETTERS ///////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Get a part of the Carbon object + * + * @param string $name + * + * @throws InvalidArgumentException + * + * @return string|integer|DateTimeZone + */ + public function __get($name) + { + switch (true) { + case array_key_exists($name, $formats = array( + 'year' => 'Y', + 'yearIso' => 'o', + 'month' => 'n', + 'day' => 'j', + 'hour' => 'G', + 'minute' => 'i', + 'second' => 's', + 'micro' => 'u', + 'dayOfWeek' => 'w', + 'dayOfYear' => 'z', + 'weekOfYear' => 'W', + 'daysInMonth' => 't', + 'timestamp' => 'U', + )): + return (int) $this->format($formats[$name]); + + case $name === 'weekOfMonth': + return (int) ceil($this->day / static::DAYS_PER_WEEK); + + case $name === 'age': + return (int) $this->diffInYears(); + + case $name === 'quarter': + return (int) ceil($this->month / 3); + + case $name === 'offset': + return $this->getOffset(); + + case $name === 'offsetHours': + return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR; + + case $name === 'dst': + return $this->format('I') == '1'; + + case $name === 'local': + return $this->offset == $this->copy()->setTimezone(date_default_timezone_get())->offset; + + case $name === 'utc': + return $this->offset == 0; + + case $name === 'timezone' || $name === 'tz': + return $this->getTimezone(); + + case $name === 'timezoneName' || $name === 'tzName': + return $this->getTimezone()->getName(); + + default: + throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name)); + } + } + + /** + * Check if an attribute exists on the object + * + * @param string $name + * + * @return boolean + */ + public function __isset($name) + { + try { + $this->__get($name); + } catch (InvalidArgumentException $e) { + return false; + } + + return true; + } + + /** + * Set a part of the Carbon object + * + * @param string $name + * @param string|integer|DateTimeZone $value + * + * @throws InvalidArgumentException + */ + public function __set($name, $value) + { + switch ($name) { + case 'year': + $this->setDate($value, $this->month, $this->day); + break; + + case 'month': + $this->setDate($this->year, $value, $this->day); + break; + + case 'day': + $this->setDate($this->year, $this->month, $value); + break; + + case 'hour': + $this->setTime($value, $this->minute, $this->second); + break; + + case 'minute': + $this->setTime($this->hour, $value, $this->second); + break; + + case 'second': + $this->setTime($this->hour, $this->minute, $value); + break; + + case 'timestamp': + parent::setTimestamp($value); + break; + + case 'timezone': + case 'tz': + $this->setTimezone($value); + break; + + default: + throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name)); + } + } + + /** + * Set the instance's year + * + * @param integer $value + * + * @return static + */ + public function year($value) + { + $this->year = $value; + + return $this; + } + + /** + * Set the instance's month + * + * @param integer $value + * + * @return static + */ + public function month($value) + { + $this->month = $value; + + return $this; + } + + /** + * Set the instance's day + * + * @param integer $value + * + * @return static + */ + public function day($value) + { + $this->day = $value; + + return $this; + } + + /** + * Set the instance's hour + * + * @param integer $value + * + * @return static + */ + public function hour($value) + { + $this->hour = $value; + + return $this; + } + + /** + * Set the instance's minute + * + * @param integer $value + * + * @return static + */ + public function minute($value) + { + $this->minute = $value; + + return $this; + } + + /** + * Set the instance's second + * + * @param integer $value + * + * @return static + */ + public function second($value) + { + $this->second = $value; + + return $this; + } + + /** + * Set the date and time all together + * + * @param integer $year + * @param integer $month + * @param integer $day + * @param integer $hour + * @param integer $minute + * @param integer $second + * + * @return static + */ + public function setDateTime($year, $month, $day, $hour, $minute, $second = 0) + { + return $this->setDate($year, $month, $day)->setTime($hour, $minute, $second); + } + + /** + * Set the instance's timestamp + * + * @param integer $value + * + * @return static + */ + public function timestamp($value) + { + $this->timestamp = $value; + + return $this; + } + + /** + * Alias for setTimezone() + * + * @param DateTimeZone|string $value + * + * @return static + */ + public function timezone($value) + { + return $this->setTimezone($value); + } + + /** + * Alias for setTimezone() + * + * @param DateTimeZone|string $value + * + * @return static + */ + public function tz($value) + { + return $this->setTimezone($value); + } + + /** + * Set the instance's timezone from a string or object + * + * @param DateTimeZone|string $value + * + * @return static + */ + public function setTimezone($value) + { + parent::setTimezone(static::safeCreateDateTimeZone($value)); + + return $this; + } + + + + /////////////////////////////////////////////////////////////////// + /////////////////////// WEEK SPECIAL DAYS ///////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Get the first day of week + * + * @return int + */ + public static function getWeekStartsAt() + { + return static::$weekStartsAt; + } + + /** + * Set the first day of week + * + * @param int + */ + public static function setWeekStartsAt($day) + { + static::$weekStartsAt = $day; + } + + /** + * Get the last day of week + * + * @return int + */ + public static function getWeekEndsAt() + { + return static::$weekEndsAt; + } + + /** + * Set the first day of week + * + * @param int + */ + public static function setWeekEndsAt($day) + { + static::$weekEndsAt = $day; + } + + /** + * Get weekend days + * + * @return array + */ + public static function getWeekendDays() + { + return static::$weekendDays; + } + + /** + * Set weekend days + * + * @param array + */ + public static function setWeekendDays($days) + { + static::$weekendDays = $days; + } + + + /////////////////////////////////////////////////////////////////// + ///////////////////////// TESTING AIDS //////////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Set a Carbon instance (real or mock) to be returned when a "now" + * instance is created. The provided instance will be returned + * specifically under the following conditions: + * - A call to the static now() method, ex. Carbon::now() + * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null) + * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now') + * + * Note the timezone parameter was left out of the examples above and + * has no affect as the mock value will be returned regardless of its value. + * + * To clear the test instance call this method using the default + * parameter of null. + * + * @param Carbon $testNow + */ + public static function setTestNow(Carbon $testNow = null) + { + static::$testNow = $testNow; + } + + /** + * Get the Carbon instance (real or mock) to be returned when a "now" + * instance is created. + * + * @return static the current instance used for testing + */ + public static function getTestNow() + { + return static::$testNow; + } + + /** + * Determine if there is a valid test instance set. A valid test instance + * is anything that is not null. + * + * @return boolean true if there is a test instance, otherwise false + */ + public static function hasTestNow() + { + return static::getTestNow() !== null; + } + + /** + * Determine if there is a relative keyword in the time string, this is to + * create dates relative to now for test instances. e.g.: next tuesday + * + * @param string $time + * + * @return boolean true if there is a keyword, otherwise false + */ + public static function hasRelativeKeywords($time) + { + // skip common format with a '-' in it + if (preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1) { + foreach (static::$relativeKeywords as $keyword) { + if (stripos($time, $keyword) !== false) { + return true; + } + } + } + + return false; + } + + /////////////////////////////////////////////////////////////////// + /////////////////////// LOCALIZATION ////////////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Intialize the translator instance if necessary. + * + * @return TranslatorInterface + */ + protected static function translator() + { + if (static::$translator == null) { + static::$translator = new Translator('en'); + static::$translator->addLoader('array', new ArrayLoader()); + static::setLocale('en'); + } + + return static::$translator; + } + + /** + * Get the translator instance in use + * + * @return TranslatorInterface + */ + public static function getTranslator() + { + return static::translator(); + } + + /** + * Set the translator instance to use + * + * @param TranslatorInterface $translator + */ + public static function setTranslator(TranslatorInterface $translator) + { + static::$translator = $translator; + } + + /** + * Get the current translator locale + * + * @return string + */ + public static function getLocale() + { + return static::translator()->getLocale(); + } + + /** + * Set the current translator locale + * + * @param string $locale + */ + public static function setLocale($locale) + { + static::translator()->setLocale($locale); + + // Ensure the locale has been loaded. + static::translator()->addResource('array', require __DIR__.'/Lang/'.$locale.'.php', $locale); + } + + /////////////////////////////////////////////////////////////////// + /////////////////////// STRING FORMATTING ///////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Format the instance with the current locale. You can set the current + * locale using setlocale() http://php.net/setlocale. + * + * @param string $format + * + * @return string + */ + public function formatLocalized($format) + { + // Check for Windows to find and replace the %e + // modifier correctly + if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { + $format = preg_replace('#(?format(static::$toStringFormat); + } + + /** + * Format the instance as date + * + * @return string + */ + public function toDateString() + { + return $this->format('Y-m-d'); + } + + /** + * Format the instance as a readable date + * + * @return string + */ + public function toFormattedDateString() + { + return $this->format('M j, Y'); + } + + /** + * Format the instance as time + * + * @return string + */ + public function toTimeString() + { + return $this->format('H:i:s'); + } + + /** + * Format the instance as date and time + * + * @return string + */ + public function toDateTimeString() + { + return $this->format('Y-m-d H:i:s'); + } + + /** + * Format the instance with day, date and time + * + * @return string + */ + public function toDayDateTimeString() + { + return $this->format('D, M j, Y g:i A'); + } + + /** + * Format the instance as ATOM + * + * @return string + */ + public function toAtomString() + { + return $this->format(static::ATOM); + } + + /** + * Format the instance as COOKIE + * + * @return string + */ + public function toCookieString() + { + return $this->format(static::COOKIE); + } + + /** + * Format the instance as ISO8601 + * + * @return string + */ + public function toIso8601String() + { + return $this->format(static::ISO8601); + } + + /** + * Format the instance as RFC822 + * + * @return string + */ + public function toRfc822String() + { + return $this->format(static::RFC822); + } + + /** + * Format the instance as RFC850 + * + * @return string + */ + public function toRfc850String() + { + return $this->format(static::RFC850); + } + + /** + * Format the instance as RFC1036 + * + * @return string + */ + public function toRfc1036String() + { + return $this->format(static::RFC1036); + } + + /** + * Format the instance as RFC1123 + * + * @return string + */ + public function toRfc1123String() + { + return $this->format(static::RFC1123); + } + + /** + * Format the instance as RFC2822 + * + * @return string + */ + public function toRfc2822String() + { + return $this->format(static::RFC2822); + } + + /** + * Format the instance as RFC3339 + * + * @return string + */ + public function toRfc3339String() + { + return $this->format(static::RFC3339); + } + + /** + * Format the instance as RSS + * + * @return string + */ + public function toRssString() + { + return $this->format(static::RSS); + } + + /** + * Format the instance as W3C + * + * @return string + */ + public function toW3cString() + { + return $this->format(static::W3C); + } + + /////////////////////////////////////////////////////////////////// + ////////////////////////// COMPARISONS //////////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Determines if the instance is equal to another + * + * @param Carbon $dt + * + * @return boolean + */ + public function eq(Carbon $dt) + { + return $this == $dt; + } + + /** + * Determines if the instance is not equal to another + * + * @param Carbon $dt + * + * @return boolean + */ + public function ne(Carbon $dt) + { + return !$this->eq($dt); + } + + /** + * Determines if the instance is greater (after) than another + * + * @param Carbon $dt + * + * @return boolean + */ + public function gt(Carbon $dt) + { + return $this > $dt; + } + + /** + * Determines if the instance is greater (after) than or equal to another + * + * @param Carbon $dt + * + * @return boolean + */ + public function gte(Carbon $dt) + { + return $this >= $dt; + } + + /** + * Determines if the instance is less (before) than another + * + * @param Carbon $dt + * + * @return boolean + */ + public function lt(Carbon $dt) + { + return $this < $dt; + } + + /** + * Determines if the instance is less (before) or equal to another + * + * @param Carbon $dt + * + * @return boolean + */ + public function lte(Carbon $dt) + { + return $this <= $dt; + } + + /** + * Determines if the instance is between two others + * + * @param Carbon $dt1 + * @param Carbon $dt2 + * @param boolean $equal Indicates if a > and < comparison should be used or <= or >= + * + * @return boolean + */ + public function between(Carbon $dt1, Carbon $dt2, $equal = true) + { + if ($dt1->gt($dt2)) { + $temp = $dt1; + $dt1 = $dt2; + $dt2 = $temp; + } + + if ($equal) { + return $this->gte($dt1) && $this->lte($dt2); + } else { + return $this->gt($dt1) && $this->lt($dt2); + } + } + + /** + * Get the minimum instance between a given instance (default now) and the current instance. + * + * @param Carbon $dt + * + * @return static + */ + public function min(Carbon $dt = null) + { + $dt = ($dt === null) ? static::now($this->tz) : $dt; + + return $this->lt($dt) ? $this : $dt; + } + + /** + * Get the maximum instance between a given instance (default now) and the current instance. + * + * @param Carbon $dt + * + * @return static + */ + public function max(Carbon $dt = null) + { + $dt = ($dt === null) ? static::now($this->tz) : $dt; + + return $this->gt($dt) ? $this : $dt; + } + + /** + * Determines if the instance is a weekday + * + * @return boolean + */ + public function isWeekday() + { + return !$this->isWeekend(); + } + + /** + * Determines if the instance is a weekend day + * + * @return boolean + */ + public function isWeekend() + { + return in_array($this->dayOfWeek, self::$weekendDays); + } + + /** + * Determines if the instance is yesterday + * + * @return boolean + */ + public function isYesterday() + { + return $this->toDateString() === static::yesterday($this->tz)->toDateString(); + } + + /** + * Determines if the instance is today + * + * @return boolean + */ + public function isToday() + { + return $this->toDateString() === static::now($this->tz)->toDateString(); + } + + /** + * Determines if the instance is tomorrow + * + * @return boolean + */ + public function isTomorrow() + { + return $this->toDateString() === static::tomorrow($this->tz)->toDateString(); + } + + /** + * Determines if the instance is in the future, ie. greater (after) than now + * + * @return boolean + */ + public function isFuture() + { + return $this->gt(static::now($this->tz)); + } + + /** + * Determines if the instance is in the past, ie. less (before) than now + * + * @return boolean + */ + public function isPast() + { + return $this->lt(static::now($this->tz)); + } + + /** + * Determines if the instance is a leap year + * + * @return boolean + */ + public function isLeapYear() + { + return $this->format('L') == '1'; + } + + /** + * Checks if the passed in date is the same day as the instance current day. + * + * @param Carbon $dt + * @return boolean + */ + public function isSameDay(Carbon $dt) + { + return $this->toDateString() === $dt->toDateString(); + } + + /** + * Checks if this day is a Sunday. + * + * @return boolean + */ + public function isSunday() + { + return $this->dayOfWeek === static::SUNDAY; + } + + /** + * Checks if this day is a Monday. + * + * @return boolean + */ + public function isMonday() + { + return $this->dayOfWeek === static::MONDAY; + } + + /** + * Checks if this day is a Tuesday. + * + * @return boolean + */ + public function isTuesday() + { + return $this->dayOfWeek === static::TUESDAY; + } + + /** + * Checks if this day is a Wednesday. + * + * @return boolean + */ + public function isWednesday() + { + return $this->dayOfWeek === static::WEDNESDAY; + } + + /** + * Checks if this day is a Thursday. + * + * @return boolean + */ + public function isThursday() + { + return $this->dayOfWeek === static::THURSDAY; + } + + /** + * Checks if this day is a Friday. + * + * @return boolean + */ + public function isFriday() + { + return $this->dayOfWeek === static::FRIDAY; + } + + /** + * Checks if this day is a Saturday. + * + * @return boolean + */ + public function isSaturday() + { + return $this->dayOfWeek === static::SATURDAY; + } + + /////////////////////////////////////////////////////////////////// + /////////////////// ADDITIONS AND SUBTRACTIONS //////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Add years to the instance. Positive $value travel forward while + * negative $value travel into the past. + * + * @param integer $value + * + * @return static + */ + public function addYears($value) + { + return $this->modify((int) $value.' year'); + } + + /** + * Add a year to the instance + * + * @param integer $value + * + * @return static + */ + public function addYear($value = 1) + { + return $this->addYears($value); + } + + /** + * Remove a year from the instance + * + * @param integer $value + * + * @return static + */ + public function subYear($value = 1) + { + return $this->subYears($value); + } + + /** + * Remove years from the instance. + * + * @param integer $value + * + * @return static + */ + public function subYears($value) + { + return $this->addYears(-1 * $value); + } + + /** + * Add months to the instance. Positive $value travels forward while + * negative $value travels into the past. + * + * @param integer $value + * + * @return static + */ + public function addMonths($value) + { + return $this->modify((int) $value.' month'); + } + + /** + * Add a month to the instance + * + * @param integer $value + * + * @return static + */ + public function addMonth($value = 1) + { + return $this->addMonths($value); + } + + /** + * Remove a month from the instance + * + * @param integer $value + * + * @return static + */ + public function subMonth($value = 1) + { + return $this->subMonths($value); + } + + /** + * Remove months from the instance + * + * @param integer $value + * + * @return static + */ + public function subMonths($value) + { + return $this->addMonths(-1 * $value); + } + + /** + * Add months without overflowing to the instance. Positive $value + * travels forward while negative $value travels into the past. + * + * @param integer $value + * + * @return static + */ + public function addMonthsNoOverflow($value) + { + $date = $this->copy()->addMonths($value); + + if ($date->day != $this->day) { + $date->day(1)->subMonth()->day($date->daysInMonth); + } + + return $date; + } + + /** + * Add a month with no overflow to the instance + * + * @param integer $value + * + * @return static + */ + public function addMonthNoOverflow($value = 1) + { + return $this->addMonthsNoOverflow($value); + } + + /** + * Remove a month with no overflow from the instance + * + * @param integer $value + * + * @return static + */ + public function subMonthNoOverflow($value = 1) + { + return $this->subMonthsNoOverflow($value); + } + + /** + * Remove months with no overflow from the instance + * + * @param integer $value + * + * @return static + */ + public function subMonthsNoOverflow($value) + { + return $this->addMonthsNoOverflow(-1 * $value); + } + + /** + * Add days to the instance. Positive $value travels forward while + * negative $value travels into the past. + * + * @param integer $value + * + * @return static + */ + public function addDays($value) + { + return $this->modify((int) $value.' day'); + } + + /** + * Add a day to the instance + * + * @param integer $value + * + * @return static + */ + public function addDay($value = 1) + { + return $this->addDays($value); + } + + /** + * Remove a day from the instance + * + * @param integer $value + * + * @return static + */ + public function subDay($value = 1) + { + return $this->subDays($value); + } + + /** + * Remove days from the instance + * + * @param integer $value + * + * @return static + */ + public function subDays($value) + { + return $this->addDays(-1 * $value); + } + + /** + * Add weekdays to the instance. Positive $value travels forward while + * negative $value travels into the past. + * + * @param integer $value + * + * @return static + */ + public function addWeekdays($value) + { + return $this->modify((int) $value.' weekday'); + } + + /** + * Add a weekday to the instance + * + * @param integer $value + * + * @return static + */ + public function addWeekday($value = 1) + { + return $this->addWeekdays($value); + } + + /** + * Remove a weekday from the instance + * + * @param integer $value + * + * @return static + */ + public function subWeekday($value = 1) + { + return $this->subWeekdays($value); + } + + /** + * Remove weekdays from the instance + * + * @param integer $value + * + * @return static + */ + public function subWeekdays($value) + { + return $this->addWeekdays(-1 * $value); + } + + /** + * Add weeks to the instance. Positive $value travels forward while + * negative $value travels into the past. + * + * @param integer $value + * + * @return static + */ + public function addWeeks($value) + { + return $this->modify((int) $value.' week'); + } + + /** + * Add a week to the instance + * + * @param integer $value + * + * @return static + */ + public function addWeek($value = 1) + { + return $this->addWeeks($value); + } + + /** + * Remove a week from the instance + * + * @param integer $value + * + * @return static + */ + public function subWeek($value = 1) + { + return $this->subWeeks($value); + } + + /** + * Remove weeks to the instance + * + * @param integer $value + * + * @return static + */ + public function subWeeks($value) + { + return $this->addWeeks(-1 * $value); + } + + /** + * Add hours to the instance. Positive $value travels forward while + * negative $value travels into the past. + * + * @param integer $value + * + * @return static + */ + public function addHours($value) + { + return $this->modify((int) $value.' hour'); + } + + /** + * Add an hour to the instance + * + * @param integer $value + * + * @return static + */ + public function addHour($value = 1) + { + return $this->addHours($value); + } + + /** + * Remove an hour from the instance + * + * @param integer $value + * + * @return static + */ + public function subHour($value = 1) + { + return $this->subHours($value); + } + + /** + * Remove hours from the instance + * + * @param integer $value + * + * @return static + */ + public function subHours($value) + { + return $this->addHours(-1 * $value); + } + + /** + * Add minutes to the instance. Positive $value travels forward while + * negative $value travels into the past. + * + * @param integer $value + * + * @return static + */ + public function addMinutes($value) + { + return $this->modify((int) $value.' minute'); + } + + /** + * Add a minute to the instance + * + * @param integer $value + * + * @return static + */ + public function addMinute($value = 1) + { + return $this->addMinutes($value); + } + + /** + * Remove a minute from the instance + * + * @param integer $value + * + * @return static + */ + public function subMinute($value = 1) + { + return $this->subMinutes($value); + } + + /** + * Remove minutes from the instance + * + * @param integer $value + * + * @return static + */ + public function subMinutes($value) + { + return $this->addMinutes(-1 * $value); + } + + /** + * Add seconds to the instance. Positive $value travels forward while + * negative $value travels into the past. + * + * @param integer $value + * + * @return static + */ + public function addSeconds($value) + { + return $this->modify((int) $value.' second'); + } + + /** + * Add a second to the instance + * + * @param integer $value + * + * @return static + */ + public function addSecond($value = 1) + { + return $this->addSeconds($value); + } + + /** + * Remove a second from the instance + * + * @param integer $value + * + * @return static + */ + public function subSecond($value = 1) + { + return $this->subSeconds($value); + } + + /** + * Remove seconds from the instance + * + * @param integer $value + * + * @return static + */ + public function subSeconds($value) + { + return $this->addSeconds(-1 * $value); + } + + /////////////////////////////////////////////////////////////////// + /////////////////////////// DIFFERENCES /////////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Get the difference in years + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return integer + */ + public function diffInYears(Carbon $dt = null, $abs = true) + { + $dt = ($dt === null) ? static::now($this->tz) : $dt; + + return (int) $this->diff($dt, $abs)->format('%r%y'); + } + + /** + * Get the difference in months + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return integer + */ + public function diffInMonths(Carbon $dt = null, $abs = true) + { + $dt = ($dt === null) ? static::now($this->tz) : $dt; + + return $this->diffInYears($dt, $abs) * static::MONTHS_PER_YEAR + (int) $this->diff($dt, $abs)->format('%r%m'); + } + + /** + * Get the difference in weeks + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return integer + */ + public function diffInWeeks(Carbon $dt = null, $abs = true) + { + return (int) ($this->diffInDays($dt, $abs) / static::DAYS_PER_WEEK); + } + + /** + * Get the difference in days + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return integer + */ + public function diffInDays(Carbon $dt = null, $abs = true) + { + $dt = ($dt === null) ? static::now($this->tz) : $dt; + + return (int) $this->diff($dt, $abs)->format('%r%a'); + } + + /** + * Get the difference in days using a filter closure + * + * @param Closure $callback + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return int + */ + public function diffInDaysFiltered(Closure $callback, Carbon $dt = null, $abs = true) + { + return $this->diffFiltered(CarbonInterval::day(), $callback, $dt, $abs); + } + + /** + * Get the difference in hours using a filter closure + * + * @param Closure $callback + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return int + */ + public function diffInHoursFiltered(Closure $callback, Carbon $dt = null, $abs = true) + { + return $this->diffFiltered(CarbonInterval::hour(), $callback, $dt, $abs); + } + + /** + * Get the difference by the given interval using a filter closure + * + * @param CarbonInterval $ci An interval to traverse by + * @param Closure $callback + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return int + */ + public function diffFiltered(CarbonInterval $ci, Closure $callback, Carbon $dt = null, $abs = true) + { + $start = $this; + $end = ($dt === null) ? static::now($this->tz) : $dt; + $inverse = false; + + if ($end < $start) { + $start = $end; + $end = $this; + $inverse = true; + } + + $period = new DatePeriod($start, $ci, $end); + $vals = array_filter(iterator_to_array($period), function (DateTime $date) use ($callback) { + return call_user_func($callback, Carbon::instance($date)); + }); + + $diff = count($vals); + + return $inverse && !$abs ? -$diff : $diff; + } + + /** + * Get the difference in weekdays + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return int + */ + public function diffInWeekdays(Carbon $dt = null, $abs = true) + { + return $this->diffInDaysFiltered(function (Carbon $date) { + return $date->isWeekday(); + }, $dt, $abs); + } + + /** + * Get the difference in weekend days using a filter + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return int + */ + public function diffInWeekendDays(Carbon $dt = null, $abs = true) + { + return $this->diffInDaysFiltered(function (Carbon $date) { + return $date->isWeekend(); + }, $dt, $abs); + } + + /** + * Get the difference in hours + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return integer + */ + public function diffInHours(Carbon $dt = null, $abs = true) + { + return (int) ($this->diffInSeconds($dt, $abs) / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR); + } + + /** + * Get the difference in minutes + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return integer + */ + public function diffInMinutes(Carbon $dt = null, $abs = true) + { + return (int) ($this->diffInSeconds($dt, $abs) / static::SECONDS_PER_MINUTE); + } + + /** + * Get the difference in seconds + * + * @param Carbon $dt + * @param boolean $abs Get the absolute of the difference + * + * @return integer + */ + public function diffInSeconds(Carbon $dt = null, $abs = true) + { + $dt = ($dt === null) ? static::now($this->tz) : $dt; + $value = $dt->getTimestamp() - $this->getTimestamp(); + + return $abs ? abs($value) : $value; + } + + /** + * The number of seconds since midnight. + * + * @return integer + */ + public function secondsSinceMidnight() + { + return $this->diffInSeconds($this->copy()->startOfDay()); + } + + /** + * The number of seconds until 23:23:59. + * + * @return integer + */ + public function secondsUntilEndOfDay() + { + return $this->diffInSeconds($this->copy()->endOfDay()); + } + + /** + * Get the difference in a human readable format in the current locale. + * + * When comparing a value in the past to default now: + * 1 hour ago + * 5 months ago + * + * When comparing a value in the future to default now: + * 1 hour from now + * 5 months from now + * + * When comparing a value in the past to another value: + * 1 hour before + * 5 months before + * + * When comparing a value in the future to another value: + * 1 hour after + * 5 months after + * + * @param Carbon $other + * @param bool $absolute removes time difference modifiers ago, after, etc + * + * @return string + */ + public function diffForHumans(Carbon $other = null, $absolute = false) + { + $isNow = $other === null; + + if ($isNow) { + $other = static::now($this->tz); + } + + $diffInterval = $this->diff($other); + + switch (true) { + case ($diffInterval->y > 0): + $unit = 'year'; + $count = $diffInterval->y; + break; + + case ($diffInterval->m > 0): + $unit = 'month'; + $count = $diffInterval->m; + break; + + case ($diffInterval->d > 0): + $unit = 'day'; + $count = $diffInterval->d; + if ($count >= self::DAYS_PER_WEEK) { + $unit = 'week'; + $count = (int) ($count / self::DAYS_PER_WEEK); + } + break; + + case ($diffInterval->h > 0): + $unit = 'hour'; + $count = $diffInterval->h; + break; + + case ($diffInterval->i > 0): + $unit = 'minute'; + $count = $diffInterval->i; + break; + + default: + $count = $diffInterval->s; + $unit = 'second'; + break; + } + + if ($count == 0) { + $count = 1; + } + + $time = static::translator()->transChoice($unit, $count, array(':count' => $count)); + + if ($absolute) { + return $time; + } + + $isFuture = $diffInterval->invert === 1; + + $transId = $isNow ? ($isFuture ? 'from_now' : 'ago') : ($isFuture ? 'after' : 'before'); + + // Some langs have special pluralization for past and future tense. + $tryKeyExists = $unit.'_'.$transId; + if ($tryKeyExists !== static::translator()->transChoice($tryKeyExists, $count)) { + $time = static::translator()->transChoice($tryKeyExists, $count, array(':count' => $count)); + } + + return static::translator()->trans($transId, array(':time' => $time)); + } + + /////////////////////////////////////////////////////////////////// + //////////////////////////// MODIFIERS //////////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Resets the time to 00:00:00 + * + * @return static + */ + public function startOfDay() + { + return $this->hour(0)->minute(0)->second(0); + } + + /** + * Resets the time to 23:59:59 + * + * @return static + */ + public function endOfDay() + { + return $this->hour(23)->minute(59)->second(59); + } + + /** + * Resets the date to the first day of the month and the time to 00:00:00 + * + * @return static + */ + public function startOfMonth() + { + return $this->startOfDay()->day(1); + } + + /** + * Resets the date to end of the month and time to 23:59:59 + * + * @return static + */ + public function endOfMonth() + { + return $this->day($this->daysInMonth)->endOfDay(); + } + + /** + * Resets the date to the first day of the year and the time to 00:00:00 + * + * @return static + */ + public function startOfYear() + { + return $this->month(1)->startOfMonth(); + } + + /** + * Resets the date to end of the year and time to 23:59:59 + * + * @return static + */ + public function endOfYear() + { + return $this->month(static::MONTHS_PER_YEAR)->endOfMonth(); + } + + /** + * Resets the date to the first day of the decade and the time to 00:00:00 + * + * @return static + */ + public function startOfDecade() + { + return $this->startOfYear()->year($this->year - $this->year % static::YEARS_PER_DECADE); + } + + /** + * Resets the date to end of the decade and time to 23:59:59 + * + * @return static + */ + public function endOfDecade() + { + return $this->endOfYear()->year($this->year - $this->year % static::YEARS_PER_DECADE + static::YEARS_PER_DECADE - 1); + } + + /** + * Resets the date to the first day of the century and the time to 00:00:00 + * + * @return static + */ + public function startOfCentury() + { + return $this->startOfYear()->year($this->year - $this->year % static::YEARS_PER_CENTURY); + } + + /** + * Resets the date to end of the century and time to 23:59:59 + * + * @return static + */ + public function endOfCentury() + { + return $this->endOfYear()->year($this->year - $this->year % static::YEARS_PER_CENTURY + static::YEARS_PER_CENTURY - 1); + } + + /** + * Resets the date to the first day of week (defined in $weekStartsAt) and the time to 00:00:00 + * + * @return static + */ + public function startOfWeek() + { + if ($this->dayOfWeek != static::$weekStartsAt) { + $this->previous(static::$weekStartsAt); + } + + return $this->startOfDay(); + } + + /** + * Resets the date to end of week (defined in $weekEndsAt) and time to 23:59:59 + * + * @return static + */ + public function endOfWeek() + { + if ($this->dayOfWeek != static::$weekEndsAt) { + $this->next(static::$weekEndsAt); + } + + return $this->endOfDay(); + } + + /** + * Modify to the next occurence of a given day of the week. + * If no dayOfWeek is provided, modify to the next occurence + * of the current day of the week. Use the supplied consts + * to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $dayOfWeek + * + * @return mixed + */ + public function next($dayOfWeek = null) + { + if ($dayOfWeek === null) { + $dayOfWeek = $this->dayOfWeek; + } + + return $this->startOfDay()->modify('next '.static::$days[$dayOfWeek]); + } + + /** + * Modify to the previous occurence of a given day of the week. + * If no dayOfWeek is provided, modify to the previous occurence + * of the current day of the week. Use the supplied consts + * to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $dayOfWeek + * + * @return mixed + */ + public function previous($dayOfWeek = null) + { + if ($dayOfWeek === null) { + $dayOfWeek = $this->dayOfWeek; + } + + return $this->startOfDay()->modify('last '.static::$days[$dayOfWeek]); + } + + /** + * Modify to the first occurence of a given day of the week + * in the current month. If no dayOfWeek is provided, modify to the + * first day of the current month. Use the supplied consts + * to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $dayOfWeek + * + * @return mixed + */ + public function firstOfMonth($dayOfWeek = null) + { + $this->startOfDay(); + + if ($dayOfWeek === null) { + return $this->day(1); + } + + return $this->modify('first '.static::$days[$dayOfWeek].' of '.$this->format('F').' '.$this->year); + } + + /** + * Modify to the last occurence of a given day of the week + * in the current month. If no dayOfWeek is provided, modify to the + * last day of the current month. Use the supplied consts + * to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $dayOfWeek + * + * @return mixed + */ + public function lastOfMonth($dayOfWeek = null) + { + $this->startOfDay(); + + if ($dayOfWeek === null) { + return $this->day($this->daysInMonth); + } + + return $this->modify('last '.static::$days[$dayOfWeek].' of '.$this->format('F').' '.$this->year); + } + + /** + * Modify to the given occurence of a given day of the week + * in the current month. If the calculated occurence is outside the scope + * of the current month, then return false and no modifications are made. + * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $nth + * @param int $dayOfWeek + * + * @return mixed + */ + public function nthOfMonth($nth, $dayOfWeek) + { + $dt = $this->copy()->firstOfMonth(); + $check = $dt->format('Y-m'); + $dt->modify('+'.$nth.' '.static::$days[$dayOfWeek]); + + return ($dt->format('Y-m') === $check) ? $this->modify($dt) : false; + } + + /** + * Modify to the first occurence of a given day of the week + * in the current quarter. If no dayOfWeek is provided, modify to the + * first day of the current quarter. Use the supplied consts + * to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $dayOfWeek + * + * @return mixed + */ + public function firstOfQuarter($dayOfWeek = null) + { + return $this->day(1)->month($this->quarter * 3 - 2)->firstOfMonth($dayOfWeek); + } + + /** + * Modify to the last occurence of a given day of the week + * in the current quarter. If no dayOfWeek is provided, modify to the + * last day of the current quarter. Use the supplied consts + * to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $dayOfWeek + * + * @return mixed + */ + public function lastOfQuarter($dayOfWeek = null) + { + return $this->day(1)->month($this->quarter * 3)->lastOfMonth($dayOfWeek); + } + + /** + * Modify to the given occurence of a given day of the week + * in the current quarter. If the calculated occurence is outside the scope + * of the current quarter, then return false and no modifications are made. + * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $nth + * @param int $dayOfWeek + * + * @return mixed + */ + public function nthOfQuarter($nth, $dayOfWeek) + { + $dt = $this->copy()->day(1)->month($this->quarter * 3); + $last_month = $dt->month; + $year = $dt->year; + $dt->firstOfQuarter()->modify('+'.$nth.' '.static::$days[$dayOfWeek]); + + return ($last_month < $dt->month || $year !== $dt->year) ? false : $this->modify($dt); + } + + /** + * Modify to the first occurence of a given day of the week + * in the current year. If no dayOfWeek is provided, modify to the + * first day of the current year. Use the supplied consts + * to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $dayOfWeek + * + * @return mixed + */ + public function firstOfYear($dayOfWeek = null) + { + return $this->month(1)->firstOfMonth($dayOfWeek); + } + + /** + * Modify to the last occurence of a given day of the week + * in the current year. If no dayOfWeek is provided, modify to the + * last day of the current year. Use the supplied consts + * to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $dayOfWeek + * + * @return mixed + */ + public function lastOfYear($dayOfWeek = null) + { + return $this->month(static::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek); + } + + /** + * Modify to the given occurence of a given day of the week + * in the current year. If the calculated occurence is outside the scope + * of the current year, then return false and no modifications are made. + * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY. + * + * @param int $nth + * @param int $dayOfWeek + * + * @return mixed + */ + public function nthOfYear($nth, $dayOfWeek) + { + $dt = $this->copy()->firstOfYear()->modify('+'.$nth.' '.static::$days[$dayOfWeek]); + + return $this->year == $dt->year ? $this->modify($dt) : false; + } + + /** + * Modify the current instance to the average of a given instance (default now) and the current instance. + * + * @param Carbon $dt + * + * @return static + */ + public function average(Carbon $dt = null) + { + $dt = ($dt === null) ? static::now($this->tz) : $dt; + + return $this->addSeconds((int) ($this->diffInSeconds($dt, false) / 2)); + } + + /** + * Check if its the birthday. Compares the date/month values of the two dates. + * + * @param Carbon $dt + * + * @return boolean + */ + public function isBirthday(Carbon $dt) + { + return $this->format('md') === $dt->format('md'); + } +} diff --git a/vendor/nesbot/carbon/src/Carbon/CarbonInterval.php b/vendor/nesbot/carbon/src/Carbon/CarbonInterval.php new file mode 100644 index 0000000..27f8627 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/CarbonInterval.php @@ -0,0 +1,517 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Carbon; + +use DateInterval; +use InvalidArgumentException; +use Symfony\Component\Translation\Translator; +use Symfony\Component\Translation\TranslatorInterface; +use Symfony\Component\Translation\Loader\ArrayLoader; + +/** + * A simple API extension for DateInterval. + * The implemenation provides helpers to handle weeks but only days are saved. + * Weeks are calculated based on the total days of the current instance. + * + * @property integer $years Total years of the current interval. + * @property integer $months Total months of the current interval. + * @property integer $weeks Total weeks of the current interval calculated from the days. + * @property integer $dayz Total days of the current interval (weeks * 7 + days). + * @property integer $hours Total hours of the current interval. + * @property integer $minutes Total minutes of the current interval. + * @property integer $seconds Total seconds of the current interval. + * + * @property-read integer $dayzExcludeWeeks Total days remaining in the final week of the current instance (days % 7). + * @property-read integer $daysExcludeWeeks alias of dayzExcludeWeeks + * + * @method static CarbonInterval years($years = 1) Create instance specifying a number of years. + * @method static CarbonInterval year($years = 1) Alias for years() + * @method static CarbonInterval months($months = 1) Create instance specifying a number of months. + * @method static CarbonInterval month($months = 1) Alias for months() + * @method static CarbonInterval weeks($weeks = 1) Create instance specifying a number of weeks. + * @method static CarbonInterval week($weeks = 1) Alias for weeks() + * @method static CarbonInterval days($days = 1) Create instance specifying a number of days. + * @method static CarbonInterval dayz($days = 1) Alias for days() + * @method static CarbonInterval day($days = 1) Alias for days() + * @method static CarbonInterval hours($hours = 1) Create instance specifying a number of hours. + * @method static CarbonInterval hour($hours = 1) Alias for hours() + * @method static CarbonInterval minutes($minutes = 1) Create instance specifying a number of minutes. + * @method static CarbonInterval minute($minutes = 1) Alias for minutes() + * @method static CarbonInterval seconds($seconds = 1) Create instance specifying a number of seconds. + * @method static CarbonInterval second($seconds = 1) Alias for seconds() + * + * @method CarbonInterval years() years($years = 1) Set the years portion of the current interval. + * @method CarbonInterval year() year($years = 1) Alias for years(). + * @method CarbonInterval months() months($months = 1) Set the months portion of the current interval. + * @method CarbonInterval month() month($months = 1) Alias for months(). + * @method CarbonInterval weeks() weeks($weeks = 1) Set the weeks portion of the current interval. Will overwrite dayz value. + * @method CarbonInterval week() week($weeks = 1) Alias for weeks(). + * @method CarbonInterval days() days($days = 1) Set the days portion of the current interval. + * @method CarbonInterval dayz() dayz($days = 1) Alias for days(). + * @method CarbonInterval day() day($days = 1) Alias for days(). + * @method CarbonInterval hours() hours($hours = 1) Set the hours portion of the current interval. + * @method CarbonInterval hour() hour($hours = 1) Alias for hours(). + * @method CarbonInterval minutes() minutes($minutes = 1) Set the minutes portion of the current interval. + * @method CarbonInterval minute() minute($minutes = 1) Alias for minutes(). + * @method CarbonInterval seconds() seconds($seconds = 1) Set the seconds portion of the current interval. + * @method CarbonInterval second() second($seconds = 1) Alias for seconds(). + */ +class CarbonInterval extends DateInterval +{ + /** + * Interval spec period designators + */ + const PERIOD_PREFIX = 'P'; + const PERIOD_YEARS = 'Y'; + const PERIOD_MONTHS = 'M'; + const PERIOD_DAYS = 'D'; + const PERIOD_TIME_PREFIX = 'T'; + const PERIOD_HOURS = 'H'; + const PERIOD_MINUTES = 'M'; + const PERIOD_SECONDS = 'S'; + + /** + * A translator to ... er ... translate stuff + * + * @var TranslatorInterface + */ + protected static $translator; + + /** + * Before PHP 5.4.20/5.5.4 instead of FALSE days will be set to -99999 when the interval instance + * was created by DateTime:diff(). + */ + const PHP_DAYS_FALSE = -99999; + + /** + * Determine if the interval was created via DateTime:diff() or not. + * + * @param DateInterval $interval + * + * @return boolean + */ + private static function wasCreatedFromDiff(DateInterval $interval) + { + return ($interval->days !== false && $interval->days !== static::PHP_DAYS_FALSE); + } + + /////////////////////////////////////////////////////////////////// + //////////////////////////// CONSTRUCTORS ///////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Create a new CarbonInterval instance. + * + * @param integer $years + * @param integer $months + * @param integer $weeks + * @param integer $days + * @param integer $hours + * @param integer $minutes + * @param integer $seconds + */ + public function __construct($years = 1, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null) + { + $spec = static::PERIOD_PREFIX; + + $spec .= $years > 0 ? $years.static::PERIOD_YEARS : ''; + $spec .= $months > 0 ? $months.static::PERIOD_MONTHS : ''; + + $specDays = 0; + $specDays += $weeks > 0 ? $weeks * Carbon::DAYS_PER_WEEK : 0; + $specDays += $days > 0 ? $days : 0; + + $spec .= ($specDays > 0) ? $specDays.static::PERIOD_DAYS : ''; + + if ($hours > 0 || $minutes > 0 || $seconds > 0) { + $spec .= static::PERIOD_TIME_PREFIX; + $spec .= $hours > 0 ? $hours.static::PERIOD_HOURS : ''; + $spec .= $minutes > 0 ? $minutes.static::PERIOD_MINUTES : ''; + $spec .= $seconds > 0 ? $seconds.static::PERIOD_SECONDS : ''; + } + + parent::__construct($spec); + } + + /** + * Create a new CarbonInterval instance from specific values. + * This is an alias for the constructor that allows better fluent + * syntax as it allows you to do CarbonInterval::create(1)->fn() rather than + * (new CarbonInterval(1))->fn(). + * + * @param integer $years + * @param integer $months + * @param integer $weeks + * @param integer $days + * @param integer $hours + * @param integer $minutes + * @param integer $seconds + * + * @return static + */ + public static function create($years = 1, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null) + { + return new static($years, $months, $weeks, $days, $hours, $minutes, $seconds); + } + + /** + * Provide static helpers to create instances. Allows CarbonInterval::years(3). + * + * Note: This is done using the magic method to allow static and instance methods to + * have the same names. + * + * @param string $name + * @param array $args + * + * @return static + */ + public static function __callStatic($name, $args) + { + $arg = count($args) == 0 ? 1 : $args[0]; + + switch ($name) { + case 'years': + case 'year': + return new static($arg); + + case 'months': + case 'month': + return new static(null, $arg); + + case 'weeks': + case 'week': + return new static(null, null, $arg); + + case 'days': + case 'dayz': + case 'day': + return new static(null, null, null, $arg); + + case 'hours': + case 'hour': + return new static(null, null, null, null, $arg); + + case 'minutes': + case 'minute': + return new static(null, null, null, null, null, $arg); + + case 'seconds': + case 'second': + return new static(null, null, null, null, null, null, $arg); + } + } + + /** + * Create a CarbonInterval instance from a DateInterval one. Can not instance + * DateInterval objects created from DateTime::diff() as you can't externally + * set the $days field. + * + * @param DateInterval $di + * + * @throws InvalidArgumentException + * + * @return static + */ + public static function instance(DateInterval $di) + { + if (static::wasCreatedFromDiff($di)) { + throw new InvalidArgumentException("Can not instance a DateInterval object created from DateTime::diff()."); + } + + $instance = new static($di->y, $di->m, 0, $di->d, $di->h, $di->i, $di->s); + $instance->invert = $di->invert; + $instance->days = $di->days; + return $instance; + } + + /////////////////////////////////////////////////////////////////// + /////////////////////// LOCALIZATION ////////////////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Intialize the translator instance if necessary. + * + * @return TranslatorInterface + */ + protected static function translator() + { + if (static::$translator == null) { + static::$translator = new Translator('en'); + static::$translator->addLoader('array', new ArrayLoader()); + static::setLocale('en'); + } + + return static::$translator; + } + + /** + * Get the translator instance in use + * + * @return TranslatorInterface + */ + public static function getTranslator() + { + return static::translator(); + } + + /** + * Set the translator instance to use + * + * @param TranslatorInterface $translator + */ + public static function setTranslator(TranslatorInterface $translator) + { + static::$translator = $translator; + } + + /** + * Get the current translator locale + * + * @return string + */ + public static function getLocale() + { + return static::translator()->getLocale(); + } + + /** + * Set the current translator locale + * + * @param string $locale + */ + public static function setLocale($locale) + { + static::translator()->setLocale($locale); + + // Ensure the locale has been loaded. + static::translator()->addResource('array', require __DIR__.'/Lang/'.$locale.'.php', $locale); + } + + /////////////////////////////////////////////////////////////////// + ///////////////////////// GETTERS AND SETTERS ///////////////////// + /////////////////////////////////////////////////////////////////// + + /** + * Get a part of the CarbonInterval object + * + * @param string $name + * + * @throws InvalidArgumentException + * + * @return integer + */ + public function __get($name) + { + switch ($name) { + case 'years': + return $this->y; + + case 'months': + return $this->m; + + case 'dayz': + return $this->d; + + case 'hours': + return $this->h; + + case 'minutes': + return $this->i; + + case 'seconds': + return $this->s; + + case 'weeks': + return (int)floor($this->d / Carbon::DAYS_PER_WEEK); + + case 'daysExcludeWeeks': + case 'dayzExcludeWeeks': + return $this->d % Carbon::DAYS_PER_WEEK; + + default: + throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name)); + } + } + + /** + * Set a part of the CarbonInterval object + * + * @param string $name + * @param integer $val + * + * @throws InvalidArgumentException + */ + public function __set($name, $val) + { + switch ($name) { + case 'years': + $this->y = $val; + break; + + case 'months': + $this->m = $val; + break; + + case 'weeks': + $this->d = $val * Carbon::DAYS_PER_WEEK; + break; + + case 'dayz': + $this->d = $val; + break; + + case 'hours': + $this->h = $val; + break; + + case 'minutes': + $this->i = $val; + break; + + case 'seconds': + $this->s = $val; + break; + } + } + + /** + * Allow setting of weeks and days to be cumulative. + * + * @param int $weeks Number of weeks to set + * @param int $days Number of days to set + * + * @return static + */ + public function weeksAndDays($weeks, $days) + { + $this->dayz = ($weeks * Carbon::DAYS_PER_WEEK) + $days; + return $this; + } + + /** + * Allow fluent calls on the setters... CarbonInterval::years(3)->months(5)->day(). + * + * Note: This is done using the magic method to allow static and instance methods to + * have the same names. + * + * @param string $name + * @param array $args + * + * @return static + */ + public function __call($name, $args) + { + $arg = count($args) == 0 ? 1 : $args[0]; + + switch ($name) { + case 'years': + case 'year': + $this->years = $arg; + break; + + case 'months': + case 'month': + $this->months = $arg; + break; + + case 'weeks': + case 'week': + $this->dayz = $arg * Carbon::DAYS_PER_WEEK; + break; + + case 'days': + case 'dayz': + case 'day': + $this->dayz = $arg; + break; + + case 'hours': + case 'hour': + $this->hours = $arg; + break; + + case 'minutes': + case 'minute': + $this->minutes = $arg; + break; + + case 'seconds': + case 'second': + $this->seconds = $arg; + break; + } + + return $this; + } + + /** + * Get the current interval in a human readable format in the current locale. + * + * @return string + */ + public function forHumans() + { + $periods = array( + 'year' => $this->years, + 'month' => $this->months, + 'week' => $this->weeks, + 'day' => $this->daysExcludeWeeks, + 'hour' => $this->hours, + 'minute' => $this->minutes, + 'second' => $this->seconds, + ); + + $parts = array(); + foreach ($periods as $unit => $count) { + if ($count > 0) { + array_push($parts, static::translator()->transChoice($unit, $count, array(':count' => $count))); + } + } + + return implode(' ', $parts); + } + + /** + * Format the instance as a string using the forHumans() function. + * + * @return string + */ + public function __toString() + { + return $this->forHumans(); + } + + /** + * Add the passed interval to the current instance + * + * @param DateInterval $interval + * + * @return static + */ + public function add(DateInterval $interval) + { + $sign = ($interval->invert === 1) ? -1 : 1; + + if (static::wasCreatedFromDiff($interval)) { + $this->dayz = $this->dayz + ($interval->days * $sign); + } else { + $this->years = $this->years + ($interval->y * $sign); + $this->months = $this->months + ($interval->m * $sign); + $this->dayz = $this->dayz + ($interval->d * $sign); + $this->hours = $this->hours + ($interval->h * $sign); + $this->minutes = $this->minutes + ($interval->i * $sign); + $this->seconds = $this->seconds + ($interval->s * $sign); + } + + return $this; + } +} diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ar.php b/vendor/nesbot/carbon/src/Carbon/Lang/ar.php new file mode 100644 index 0000000..610e064 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/ar.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/ar/date.php + */ + +return array( + 'year' => '{0}سنة|{1}سنة|{2}سنتين|[3,10]:count سنوات|[11,Inf] سنة', + 'month' => '{0}شهر|{1}شهر|{2}شهرين|[3,10]:count أشهر|[11,Inf] شهر', + 'week' => '{0}أسبوع|{1}أسبوع|{2}أسبوعين|[3,10]:count أسابيع|[11,Inf] أسبوع', + 'day' => '{0}يوم|{1}يوم|{2}يومين|[3,10]:count أيام|[11,Inf] يوم', + 'hour' => '{0}ساعة|{1}ساعة|{2}ساعتين|[3,10]:count ساعات|[11,Inf] ساعة', + 'minute' => '{0}دقيقة|{1}دقيقة|{2}دقيقتين|[3,10]:count دقائق|[11,Inf]:count دقيقة', + 'second' => '{0}ثانية|{1}ثانية|{2}ثانيتين|[3,10]:count ثوان|[11,Inf] ثانية', + 'ago' => 'منذ :time', + 'from_now' => 'من الآن :time', + 'after' => 'بعد :time', + 'before' => 'قبل :time', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/az.php b/vendor/nesbot/carbon/src/Carbon/Lang/az.php new file mode 100644 index 0000000..6202be9 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/az.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ + /** + * Extracted from https://github.com/The-Hasanov/laravel-date/blob/1006f37c431178b5c7219d02c93579c9690ae546/src/Lang/az.php + */ +return array( + 'year' => ':count il', + 'month' => ':count ay', + 'week' => ':count həftə', + 'day' => ':count gün', + 'hour' => ':count saat', + 'minute' => ':count dəqiqə', + 'second' => ':count saniyə', + 'ago' => ':time öncə', + 'from_now' => ':time sonra', + 'after' => ':time sonra', + 'before' => ':time öncə' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/bg.php b/vendor/nesbot/carbon/src/Carbon/Lang/bg.php new file mode 100644 index 0000000..7a262a7 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/bg.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/bg/date.php + */ + +return array( + 'year' => '1 година|:count години', + 'month' => '1 месец|:count месеца', + 'week' => '1 седмица|:count седмици', + 'day' => '1 ден|:count дни', + 'hour' => '1 час|:count часа', + 'minute' => '1 минута|:count минути', + 'second' => '1 секунда|:count секунди', + 'ago' => 'преди :time', + 'from_now' => ':time от сега', + 'after' => 'след :time', + 'before' => 'преди :time', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/bn.php b/vendor/nesbot/carbon/src/Carbon/Lang/bn.php new file mode 100644 index 0000000..6a31e53 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/bn.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/eu/date.php + */ +return array( + 'year' => '১ বছর|:count বছর', + 'month' => '১ মাস|:count মাস', + 'week' => '১ সপ্তাহ|:count সপ্তাহ', + 'day' => '১ দিন|:count দিন', + 'hour' => '১ ঘন্টা|:count ঘন্টা', + 'minute' => '১ মিনিট|:count মিনিট', + 'second' => '১ সেকেন্ড|:count সেকেন্ড', + 'ago' => ':time পূর্বে', + 'from_now' => 'এখন থেকে :time', + 'after' => ':time পরে', + 'before' => ':time আগে', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ca.php b/vendor/nesbot/carbon/src/Carbon/Lang/ca.php new file mode 100644 index 0000000..95e04e4 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/ca.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/ca/date.php + */ +return array( + 'year' => '1 any|:count anys', + 'month' => '1 mes|:count mesos', + 'week' => '1 setmana|:count setmanes', + 'day' => '1 dia|:count díes', + 'hour' => '1 hora|:count hores', + 'minute' => '1 minut|:count minuts', + 'second' => '1 segon|:count segons', + 'ago' => 'Fa :time', + 'from_now' => 'Dins de :time', + 'after' => ':time després', + 'before' => ':time abans', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/cs.php b/vendor/nesbot/carbon/src/Carbon/Lang/cs.php new file mode 100644 index 0000000..d8890c4 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/cs.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/cs/date.php + */ +return array( + 'year' => '1 rok|:count roky|:count let', + 'month' => '1 měsíc|:count měsíce|:count měsíců', + 'week' => '1 týden|:count týdny|:count týdnů', + 'day' => '1 den|:count dny|:count dní', + 'hour' => '1 hodinu|:count hodiny|:count hodin', + 'minute' => '1 minutu|:count minuty|:count minut', + 'second' => '1 sekundu|:count sekundy|:count sekund', + 'ago' => 'před :time', + 'from_now' => 'za :time', + 'after' => ':time později', + 'before' => ':time předtím', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/da.php b/vendor/nesbot/carbon/src/Carbon/Lang/da.php new file mode 100644 index 0000000..4586fad --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/da.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 år|:count år', + 'month' => '1 måned|:count måneder', + 'week' => '1 uge|:count uger', + 'day' => '1 dag|:count dage', + 'hour' => '1 time|:count timer', + 'minute' => '1 minut|:count minutter', + 'second' => '1 sekund|:count sekunder', + 'ago' => ':time siden', + 'from_now' => 'om :time', + 'after' => ':time efter', + 'before' => ':time før', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/de.php b/vendor/nesbot/carbon/src/Carbon/Lang/de.php new file mode 100644 index 0000000..7586b32 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/de.php @@ -0,0 +1,39 @@ + + * + * This file is released under the terms of CC0. + * CC0 is even more permissive than the MIT license, allowing you to use the code in + * any manner you want, without any copyright headers, notices, or other attribution. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 Jahr|:count Jahre', + 'month' => '1 Monat|:count Monate', + 'week' => '1 Woche|:count Wochen', + 'day' => '1 Tag|:count Tage', + 'hour' => '1 Stunde|:count Stunden', + 'minute' => '1 Minute|:count Minuten', + 'second' => '1 Sekunde|:count Sekunden', + 'ago' => 'vor :time', + 'from_now' => 'in :time', + 'after' => ':time später', + 'before' => ':time zuvor', + + 'year_from_now' => '1 Jahr|:count Jahren', + 'month_from_now' => '1 Monat|:count Monaten', + 'week_from_now' => '1 Woche|:count Wochen', + 'day_from_now' => '1 Tag|:count Tagen', + 'year_ago' => '1 Jahr|:count Jahren', + 'month_ago' => '1 Monat|:count Monaten', + 'week_ago' => '1 Woche|:count Wochen', + 'day_ago' => '1 Tag|:count Tagen', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/el.php b/vendor/nesbot/carbon/src/Carbon/Lang/el.php new file mode 100644 index 0000000..0cc34e6 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/el.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/el/date.php + */ +return array( + 'year' => '1 χρόνος|:count χρόνια', + 'month' => '1 μήνας|:count μήνες', + 'week' => '1 εβδομάδα|:count εβδομάδες', + 'day' => '1 μέρα|:count μέρες', + 'hour' => '1 ώρα|:count ώρες', + 'minute' => '1 λεπτό|:count λεπτά', + 'second' => '1 δευτερόλεπτο|:count δευτερόλεπτα', + 'ago' => 'πρίν απο :time', + 'from_now' => 'σε :time απο τώρα', + 'after' => ':time μετά', + 'before' => ':time πρίν' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/en.php b/vendor/nesbot/carbon/src/Carbon/Lang/en.php new file mode 100644 index 0000000..6b682b5 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/en.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 year|:count years', + 'month' => '1 month|:count months', + 'week' => '1 week|:count weeks', + 'day' => '1 day|:count days', + 'hour' => '1 hour|:count hours', + 'minute' => '1 minute|:count minutes', + 'second' => '1 second|:count seconds', + 'ago' => ':time ago', + 'from_now' => ':time from now', + 'after' => ':time after', + 'before' => ':time before', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/eo.php b/vendor/nesbot/carbon/src/Carbon/Lang/eo.php new file mode 100644 index 0000000..34cd0ee --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/eo.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/eo/date.php + */ +return array( + 'year' => '1 jaro|:count jaroj', + 'month' => '1 monato|:count monatoj', + 'week' => '1 semajno|:count semajnoj', + 'day' => '1 tago|:count tagoj', + 'hour' => '1 horo|:count horoj', + 'minute' => '1 minuto|:count minutoj', + 'second' => '1 sekundo|:count sekundoj', + 'ago' => 'antaŭ :time', + 'from_now' => 'je :time', + 'after' => ':time poste', + 'before' => ':time antaŭe' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/es.php b/vendor/nesbot/carbon/src/Carbon/Lang/es.php new file mode 100644 index 0000000..b4573ec --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/es.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 año|:count años', + 'month' => '1 mes|:count meses', + 'week' => '1 semana|:count semanas', + 'day' => '1 día|:count días', + 'hour' => '1 hora|:count horas', + 'minute' => '1 minuto|:count minutos', + 'second' => '1 segundo|:count segundos', + 'ago' => 'hace :time', + 'from_now' => 'dentro de :time', + 'after' => ':time antes', + 'before' => ':time después', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/eu.php b/vendor/nesbot/carbon/src/Carbon/Lang/eu.php new file mode 100644 index 0000000..91f1d2a --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/eu.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/eu/date.php + */ +return array( + 'year' => 'Urte 1|:count urte', + 'month' => 'Hile 1|:count hile', + 'week' => 'Aste 1|:count aste', + 'day' => 'Egun 1|:count egun', + 'hour' => 'Ordu 1|:count ordu', + 'minute' => 'Minutu 1|:count minutu', + 'second' => 'Segundu 1|:count segundu', + 'ago' => 'Orain dela :time', + 'from_now' => ':time barru', + 'after' => ':time geroago', + 'before' => ':time lehenago' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/fa.php b/vendor/nesbot/carbon/src/Carbon/Lang/fa.php new file mode 100644 index 0000000..e77e2f5 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/fa.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ + +return array( + 'year' => ':count سال', + 'month' => ':count ماه', + 'week' => ':count هفته', + 'day' => ':count روز', + 'hour' => ':count ساعت', + 'minute' => ':count دقیقه', + 'second' => ':count ثانیه', + 'ago' => ':time پیش', + 'from_now' => ':time بعد', + 'after' => ':time پیش از', + 'before' => ':time پس از', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/fi.php b/vendor/nesbot/carbon/src/Carbon/Lang/fi.php new file mode 100644 index 0000000..7930c6b --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/fi.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/fi/date.php + */ +return array( + 'year' => '1 vuosi|:count vuotta', + 'month' => '1 kuukausi|:count kuukautta', + 'week' => '1 viikko|:count viikkoa', + 'day' => '1 päivä|:count päivää', + 'hour' => '1 tunti|:count tuntia', + 'minute' => '1 minuutti|:count minuuttia', + 'second' => '1 sekunti|:count sekuntia', + 'ago' => ':time sitten', + 'from_now' => ':time tästä hetkestä', + 'after' => ':time sen jälkeen', + 'before' => ':time ennen' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/fo.php b/vendor/nesbot/carbon/src/Carbon/Lang/fo.php new file mode 100644 index 0000000..caa8080 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/fo.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 ár|:count ár', + 'month' => '1 mánaður|:count mánaðir', + 'week' => '1 vika|:count vikur', + 'day' => '1 dag|:count dagar', + 'hour' => '1 tími|:count tímar', + 'minute' => '1 minutt|:count minuttir', + 'second' => '1 sekund|:count sekundir', + 'ago' => ':time síðan', + 'from_now' => 'um :time', + 'after' => ':time aftaná', + 'before' => ':time áðrenn', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/fr.php b/vendor/nesbot/carbon/src/Carbon/Lang/fr.php new file mode 100644 index 0000000..b10ac40 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/fr.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 an|:count ans', + 'month' => ':count mois', + 'week' => '1 semaine|:count semaines', + 'day' => '1 jour|:count jours', + 'hour' => '1 heure|:count heures', + 'minute' => '1 minute|:count minutes', + 'second' => '1 seconde|:count secondes', + 'ago' => 'il y a :time', + 'from_now' => 'dans :time', + 'after' => ':time après', + 'before' => ':time avant', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/he.php b/vendor/nesbot/carbon/src/Carbon/Lang/he.php new file mode 100644 index 0000000..9ed00f1 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/he.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => 'שנה|{2}שנתיים|:count שנים', + 'month' => 'חודש|{2}חודשיים|:count חודשים', + 'week' => 'שבוע|{2}שבועיים|:count שבועות', + 'day' => 'יום|{2}יומיים|:count ימים', + 'hour' => 'שעה|{2}שעתיים|:count שעות', + 'minute' => 'דקה|{2}דקותיים|:count דקות', + 'second' => 'שניה|:count שניות', + 'ago' => 'לפני :time', + 'from_now' => 'בעוד :time', + 'after' => 'אחרי :time', + 'before' => 'לפני :time', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/hr.php b/vendor/nesbot/carbon/src/Carbon/Lang/hr.php new file mode 100644 index 0000000..7ab1c26 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/hr.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/hr/date.php + */ +return array( + 'year' => ':count godinu|:count godine|:count godina', + 'month' => ':count mjesec|:count mjeseca|:count mjeseci', + 'week' => ':count tjedan|:count tjedna|:count tjedana', + 'day' => ':count dan|:count dana|:count dana', + 'hour' => ':count sat|:count sata|:count sati', + 'minute' => ':count minutu|:count minute |:count minuta', + 'second' => ':count sekundu|:count sekunde|:count sekundi', + 'ago' => 'prije :time', + 'from_now' => 'za :time', + 'after' => 'za :time', + 'before' => 'prije :time' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/hu.php b/vendor/nesbot/carbon/src/Carbon/Lang/hu.php new file mode 100644 index 0000000..a866039 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/hu.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/hu/date.php + */ +return array( + 'year' => '1 évvel|:count évvel', + 'month' => '1 hónappal|:count hónappal', + 'week' => '1 héttel|:count héttel', + 'day' => '1 nappal|:count nappal', + 'hour' => '1 órával|:count órával', + 'minute' => '1 perccel|:count perccel', + 'second' => '1 másodperccel|:count másodperccel', + 'ago' => ':time korábban', + 'from_now' => ':time később', + 'after' => ':time később', + 'before' => ':time korábban' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/id.php b/vendor/nesbot/carbon/src/Carbon/Lang/id.php new file mode 100644 index 0000000..4b168f6 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/id.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/id/date.php + */ +return array( + 'year' => ':count tahun', + 'month' => ':count bulan', + 'week' => ':count minggu', + 'day' => ':count hari', + 'hour' => ':count jam', + 'minute' => ':count menit', + 'second' => ':count detik', + 'ago' => ':time yang lalu', + 'from_now' => ':time dari sekarang', + 'after' => ':time setelah', + 'before' => ':time sebelum' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/it.php b/vendor/nesbot/carbon/src/Carbon/Lang/it.php new file mode 100644 index 0000000..ef1b55d --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/it.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 anno|:count anni', + 'month' => '1 mese|:count mesi', + 'week' => '1 settimana|:count settimane', + 'day' => '1 giorno|:count giorni', + 'hour' => '1 ora|:count ore', + 'minute' => '1 minuto|:count minuti', + 'second' => '1 secondo|:count secondi', + 'ago' => ':time fa', + 'from_now' => ':time da adesso', + 'after' => ':time dopo', + 'before' => ':time prima', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ja.php b/vendor/nesbot/carbon/src/Carbon/Lang/ja.php new file mode 100644 index 0000000..4b5e77d --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/ja.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/ja/date.php + */ +return array( + 'year' => ':count 年', + 'month' => ':count ヶ月', + 'week' => ':count 週間', + 'day' => ':count 日', + 'hour' => ':count 時間', + 'minute' => ':count 分', + 'second' => ':count 秒', + 'ago' => ':time 前', + 'from_now' => '今から :time', + 'after' => ':time 後', + 'before' => ':time 前' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ko.php b/vendor/nesbot/carbon/src/Carbon/Lang/ko.php new file mode 100644 index 0000000..f3ed1c4 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/ko.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/cs/date.php + */ +return array( + 'year' => ':count 년', + 'month' => ':count 개월', + 'week' => ':count 주일', + 'day' => ':count 일', + 'hour' => ':count 시간', + 'minute' => ':count 분', + 'second' => ':count 초', + 'ago' => ':time 전', + 'from_now' => ':time 후', + 'after' => ':time 뒤', + 'before' => ':time 앞', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/lt.php b/vendor/nesbot/carbon/src/Carbon/Lang/lt.php new file mode 100644 index 0000000..4a6446b --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/lt.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ + +return array( + 'year' => '1 metus|:count metus|:count metų', + 'month' => '1 menesį|:count menesius|:count menesių', + 'week' => '1 savaitę|:count savaites|:count savaičių', + 'day' => '1 dieną|:count dienas|:count dienų', + 'hour' => '1 valandą|:count valandas|:count valandų', + 'minute' => '1 minutę|:count minutes|:count minučių', + 'second' => '1 sekundę|:count sekundes|:count sekundžių', + 'ago' => 'prieš :time', + 'from_now' => 'už :time', + 'after' => 'po :time', + 'before' => ':time nuo dabar', +); \ No newline at end of file diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/lv.php b/vendor/nesbot/carbon/src/Carbon/Lang/lv.php new file mode 100644 index 0000000..07b5a02 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/lv.php @@ -0,0 +1,44 @@ + '0 gadiem|:count gada|:count gadiem', + 'month' => '0 mēnešiem|:count mēneša|:count mēnešiem', + 'week' => '0 nedēļām|:count nedēļas|:count nedēļām', + 'day' => '0 dienām|:count dienas|:count dienām', + 'hour' => '0 stundām|:count stundas|:count stundām', + 'minute' => '0 minūtēm|:count minūtes|:count minūtēm', + 'second' => '0 sekundēm|:count sekundes|:count sekundēm', + 'ago' => 'pirms :time', + 'from_now' => 'pēc :time', + 'after' => ':time vēlāk', + 'before' => ':time pirms', + + 'year_after' => '0 gadus|:count gadu|:count gadus', + 'month_after' => '0 mēnešus|:count mēnesi|:count mēnešus', + 'week_after' => '0 nedēļas|:count nedēļu|:count nedēļas', + 'day_after' => '0 dienas|:count dienu|:count dienas', + 'hour_after' => '0 stundas|:count stundu|:count stundas', + 'minute_after' => '0 minūtes|:count minūti|:count minūtes', + 'second_after' => '0 sekundes|:count sekundi|:count sekundes', + + 'year_before' => '0 gadus|:count gadu|:count gadus', + 'month_before' => '0 mēnešus|:count mēnesi|:count mēnešus', + 'week_before' => '0 nedēļas|:count nedēļu|:count nedēļas', + 'day_before' => '0 dienas|:count dienu|:count dienas', + 'hour_before' => '0 stundas|:count stundu|:count stundas', + 'minute_before' => '0 minūtes|:count minūti|:count minūtes', + 'second_before' => '0 sekundes|:count sekundi|:count sekundes', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ms.php b/vendor/nesbot/carbon/src/Carbon/Lang/ms.php new file mode 100644 index 0000000..078b9d2 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/ms.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => ':count tahun', + 'month' => ':count bulan', + 'week' => ':count minggu', + 'day' => ':count hari', + 'hour' => ':count jam', + 'minute' => ':count minit', + 'second' => ':count saat', + 'ago' => ':time yang lalu', + 'from_now' => ':time dari sekarang', + 'after' => ':time selepas', + 'before' => ':time sebelum', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/nl.php b/vendor/nesbot/carbon/src/Carbon/Lang/nl.php new file mode 100644 index 0000000..8104b71 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/nl.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 jaar|:count jaren', + 'month' => '1 maand|:count maanden', + 'week' => '1 week|:count weken', + 'day' => '1 dag|:count dagen', + 'hour' => ':count uur', + 'minute' => '1 minuut|:count minuten', + 'second' => '1 seconde|:count seconden', + 'ago' => ':time geleden', + 'from_now' => 'over :time', + 'after' => ':time later', + 'before' => ':time eerder', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/no.php b/vendor/nesbot/carbon/src/Carbon/Lang/no.php new file mode 100644 index 0000000..0cfd3d3 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/no.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/no/date.php + */ +return array( + 'year' => '1 år|:count år', + 'month' => '1 måned|:count måneder', + 'week' => '1 uke|:count uker', + 'day' => '1 dag|:count dager', + 'hour' => '1 time|:count timer', + 'minute' => '1 minutt|:count minutter', + 'second' => '1 sekund|:count sekunder', + 'ago' => ':time siden', + 'from_now' => 'om :time', + 'after' => ':time etter', + 'before' => ':time før' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/pl.php b/vendor/nesbot/carbon/src/Carbon/Lang/pl.php new file mode 100644 index 0000000..05fea60 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/pl.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/pl/date.php + */ +return array( + 'year' => '1 rok|:count lata|:count lat', + 'month' => '1 miesiąc|:count miesiące|:count miesięcy', + 'week' => '1 tydzień|:count tygodnie|:count tygodni', + 'day' => '1 dzień|:count dni|:count dni', + 'hour' => '1 godzina|:count godziny|:count godzin', + 'minute' => '1 minuta|:count minuty|:count minut', + 'second' => '1 sekunda|:count sekundy|:count sekund', + 'ago' => ':time temu', + 'from_now' => ':time od teraz', + 'after' => ':time przed', + 'before' => ':time po' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/pt.php b/vendor/nesbot/carbon/src/Carbon/Lang/pt.php new file mode 100644 index 0000000..28aab4d --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/pt.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/pt/date.php + */ +return array( + 'year' => '1 ano|:count anos', + 'month' => '1 mês|:count meses', + 'week' => '1 semana|:count semanas', + 'day' => '1 dia|:count dias', + 'hour' => '1 hora|:count horas', + 'minute' => '1 minuto|:count minutos', + 'second' => '1 segundo|:count segundos', + 'ago' => ':time atrás', + 'from_now' => 'em :time', + 'after' => ':time depois', + 'before' => ':time antes' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php b/vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php new file mode 100644 index 0000000..70435ee --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/pt_BR.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => '1 ano|:count anos', + 'month' => '1 mês|:count meses', + 'week' => '1 semana|:count semanas', + 'day' => '1 dia|:count dias', + 'hour' => '1 hora|:count horas', + 'minute' => '1 minuto|:count minutos', + 'second' => '1 segundo|:count segundos', + 'ago' => 'há :time', + 'from_now' => 'dentro de :time', + 'after' => ':time depois', + 'before' => ':time antes', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ro.php b/vendor/nesbot/carbon/src/Carbon/Lang/ro.php new file mode 100644 index 0000000..efc847d --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/ro.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/ro/date.php + */ +return array( + 'year' => 'un an|:count ani|:count ani', + 'month' => 'o lună|:count luni|:count luni', + 'week' => 'o săptămână|:count săptămâni|:count săptămâni', + 'day' => 'o zi|:count zile|:count zile', + 'hour' => 'o oră|:count ore|:count ore', + 'minute' => 'un minut|:count minute|:count minute', + 'second' => 'o secundă|:count secunde|:count secunde', + 'ago' => 'acum :time', + 'from_now' => ':time de acum', + 'after' => 'peste :time', + 'before' => 'acum :time' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/ru.php b/vendor/nesbot/carbon/src/Carbon/Lang/ru.php new file mode 100644 index 0000000..e4a1cb5 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/ru.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/ru/date.php + */ +return array( + 'year' => ':count год|:count года|:count лет', + 'month' => ':count месяц|:count месяца|:count месяцев', + 'week' => ':count неделю|:count недели|:count недель', + 'day' => ':count день|:count дня|:count дней', + 'hour' => ':count час|:count часа|:count часов', + 'minute' => ':count минуту|:count минуты|:count минут', + 'second' => ':count секунду|:count секунды|:count секунд', + 'ago' => ':time назад', + 'from_now' => 'через :time', + 'after' => ':time после', + 'before' => ':time до' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sk.php b/vendor/nesbot/carbon/src/Carbon/Lang/sk.php new file mode 100644 index 0000000..8087afe --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/sk.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/sk/date.php + */ +return array( + 'year' => 'rok|:count roky|:count rokov', + 'month' => 'mesiac|:count mesiace|:count mesiacov', + 'week' => 'týždeň|:count týždne|:count týždňov', + 'day' => 'deň|:count dni|:count dní', + 'hour' => 'hodinu|:count hodiny|:count hodín', + 'minute' => 'minútu|:count minúty|:count minút', + 'second' => 'sekundu|:count sekundy|:count sekúnd', + 'ago' => 'pred :time', + 'from_now' => 'za :time', + 'after' => ':time neskôr', + 'before' => ':time predtým' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sl.php b/vendor/nesbot/carbon/src/Carbon/Lang/sl.php new file mode 100644 index 0000000..53f810b --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/sl.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/sl/date.php + */ +return array( + 'year' => ':count leto|:count leti|:count leta|:count let', + 'month' => ':count mesec|:count meseca|:count mesece|:count mesecev', + 'week' => ':count teden|:count tedna|:count tedne|:count tednov', + 'day' => ':count dan|:count dni|:count dni|:count dni', + 'hour' => ':count uro|:count uri|:count ure|:count ur', + 'minute' => ':count minuto|:count minuti|:count minute|:count minut', + 'second' => ':count sekundo|:count sekundi|:count sekunde|:count sekund', + 'year_ago' => ':count letom|:count leti|:count leti|:count leti', + 'month_ago' => ':count mesecem|:count meseci|:count meseci|:count meseci', + 'week_ago' => ':count tednom|:count tednoma|:count tedni|:count tedni', + 'day_ago' => ':count dnem|:count dnevoma|:count dnevi|:count dnevi', + 'hour_ago' => ':count uro|:count urama|:count urami|:count urami', + 'minute_ago'=> ':count minuto|:count minutama|:count minutami|:count minutami', + 'second_ago'=> ':count sekundo|:count sekundama|:count sekundami|:count sekundami', + 'ago' => 'pred :time', + 'from_now' => 'čez :time', + 'after' => 'čez :time', + 'before' => 'pred :time' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sr.php b/vendor/nesbot/carbon/src/Carbon/Lang/sr.php new file mode 100644 index 0000000..c19087f --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/sr.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/sr/date.php + */ +return array( + 'year' => ':count godina|:count godine|:count godina', + 'month' => ':count mesec|:count meseca|:count meseci', + 'week' => ':count nedelja|:count nedelje|:count nedelja', + 'day' => ':count dan|:count dana|:count dana', + 'hour' => ':count sat|:count sata|:count sati', + 'minute' => ':count minut|:count minuta |:count minuta', + 'second' => ':count sekund|:count sekunde|:count sekunde', + 'ago' => 'pre :time', + 'from_now' => ':time od sada', + 'after' => 'nakon :time', + 'before' => 'pre :time' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/sv.php b/vendor/nesbot/carbon/src/Carbon/Lang/sv.php new file mode 100644 index 0000000..2ed2349 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/sv.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/sv/date.php + */ +return array( + 'year' => '1 år|:count år', + 'month' => '1 månad|:count månader', + 'week' => '1 vecka|:count veckor', + 'day' => '1 dag|:count dagar', + 'hour' => '1 timme|:count timmar', + 'minute' => '1 minut|:count minuter', + 'second' => '1 sekund|:count sekunder', + 'ago' => ':time sedan', + 'from_now' => 'om :time', + 'after' => ':time efter', + 'before' => ':time före' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/th.php b/vendor/nesbot/carbon/src/Carbon/Lang/th.php new file mode 100644 index 0000000..aad56c2 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/th.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/th/date.php + */ +return array( + 'year' => '1 ปี|:count ปี', + 'month' => '1 เดือน|:count เดือน', + 'week' => '1 สัปดาห์|:count สัปดาห์', + 'day' => '1 วัน|:count วัน', + 'hour' => '1 ชั่วโมง|:count ชั่วโมง', + 'minute' => '1 นาที|:count นาที', + 'second' => '1 วินาที|:count วินาที', + 'ago' => ':time sitten', + 'ago' => ':time ที่แล้ว', + 'from_now' => ':time จากนี้', + 'after' => 'หลัง:time', + 'before' => 'ก่อน:time' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/tr.php b/vendor/nesbot/carbon/src/Carbon/Lang/tr.php new file mode 100644 index 0000000..52561db --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/tr.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +return array( + 'year' => ':count yıl', + 'month' => ':count ay', + 'week' => ':count hafta', + 'day' => ':count gün', + 'hour' => ':count saat', + 'minute' => ':count dakika', + 'second' => ':count saniye', + 'ago' => ':time önce', + 'from_now' => ':time andan itibaren', + 'after' => ':time sonra', + 'before' => ':time önce', +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/uk.php b/vendor/nesbot/carbon/src/Carbon/Lang/uk.php new file mode 100644 index 0000000..8e57386 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/uk.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/uk/date.php + */ +return array( + 'year' => ':count рік|:count роки|:count років', + 'month' => ':count місяць|:count місяці|:count місяців', + 'week' => ':count тиждень|:count тижні|:count тижнів', + 'day' => ':count день|:count дні|:count днів', + 'hour' => ':count година|:count години|:count годин', + 'minute' => ':count хвилину|:count хвилини|:count хвилин', + 'second' => ':count секунду|:count секунди|:count секунд', + 'ago' => ':time назад', + 'from_now' => 'через :time', + 'after' => ':time після', + 'before' => ':time до' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/uz.php b/vendor/nesbot/carbon/src/Carbon/Lang/uz.php new file mode 100644 index 0000000..14f4078 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/uz.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ + +return array( + 'year' => ':count yil|:count yil|:count yil', + 'month' => ':count oy|:count oy|:count oylar', + 'week' => ':count hafta|:count hafta|:count hafta', + 'day' => ':count kun|:count kun|:count kun', + 'hour' => ':count soat|:count soat|:count soat', + 'minute' => ':count minut|:count minut|:count minut', + 'second' => ':count sekund|:count sekund|:count sekund', + 'ago' => ':time avval', + 'from_now' => 'keyin :time', + 'after' => ':time keyin', + 'before' => ':time gacha' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/vi.php b/vendor/nesbot/carbon/src/Carbon/Lang/vi.php new file mode 100644 index 0000000..7c70ff9 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/vi.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/vi/date.php + */ +return array( + 'year' => ':count năm', + 'month' => ':count tháng', + 'week' => ':count tuần', + 'day' => ':count ngày', + 'hour' => ':count giờ', + 'minute' => ':count phút', + 'second' => ':count giây', + 'ago' => ':time trước', + 'from_now' => ':time từ bây giờ', + 'after' => ':time sau', + 'before' => ':time trước' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/zh-TW.php b/vendor/nesbot/carbon/src/Carbon/Lang/zh-TW.php new file mode 100644 index 0000000..0ffdc7f --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/zh-TW.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/zh-TW/date.php + */ +return array( + 'year' => ':count 年', + 'month' => ':count 月', + 'week' => ':count 周', + 'day' => ':count 天', + 'hour' => ':count 小時', + 'minute' => ':count 分鐘', + 'second' => ':count 秒', + 'ago' => ':time前', + 'from_now' => '距現在 :time', + 'after' => ':time後', + 'before' => ':time前' +); diff --git a/vendor/nesbot/carbon/src/Carbon/Lang/zh.php b/vendor/nesbot/carbon/src/Carbon/Lang/zh.php new file mode 100644 index 0000000..9a74f39 --- /dev/null +++ b/vendor/nesbot/carbon/src/Carbon/Lang/zh.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +/** + * Translation messages. See http://symfony.com/doc/current/book/translation.html + * for possible formats. + * + */ +/** + * Extracted from https://github.com/jenssegers/laravel-date/blob/master/src/lang/zh/date.php + */ +return array( + 'year' => ':count年', + 'month' => ':count月', + 'week' => ':count周', + 'day' => ':count天', + 'hour' => ':count小时', + 'minute' => ':count分钟', + 'second' => ':count秒', + 'ago' => ':time前', + 'from_now' => ':time距现在', + 'after' => ':time后', + 'before' => ':time前' +); diff --git a/vendor/nikic/fast-route/.travis.yml b/vendor/nikic/fast-route/.travis.yml new file mode 100644 index 0000000..e16ed63 --- /dev/null +++ b/vendor/nikic/fast-route/.travis.yml @@ -0,0 +1,12 @@ +language: php + +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - hhvm + +matrix: + allow_failures: + - php: 7.0 diff --git a/vendor/nikic/fast-route/LICENSE b/vendor/nikic/fast-route/LICENSE new file mode 100644 index 0000000..478e764 --- /dev/null +++ b/vendor/nikic/fast-route/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2013 by Nikita Popov. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/nikic/fast-route/README.md b/vendor/nikic/fast-route/README.md new file mode 100644 index 0000000..450f31f --- /dev/null +++ b/vendor/nikic/fast-route/README.md @@ -0,0 +1,199 @@ +FastRoute - Fast request router for PHP +======================================= + +This library provides a fast implementation of a regular expression based router. [Blog post explaining how the +implementation works and why it is fast.][blog_post] + +Usage +----- + +Here's a basic usage example: + +```php +addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0'); + $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1'); + $r->addRoute('GET', '/user/{name}', 'handler2'); +}); + +$routeInfo = $dispatcher->dispatch($httpMethod, $uri); +switch ($routeInfo[0]) { + case FastRoute\Dispatcher::NOT_FOUND: + // ... 404 Not Found + break; + case FastRoute\Dispatcher::METHOD_NOT_ALLOWED: + $allowedMethods = $routeInfo[1]; + // ... 405 Method Not Allowed + break; + case FastRoute\Dispatcher::FOUND: + $handler = $routeInfo[1]; + $vars = $routeInfo[2]; + // ... call $handler with $vars + break; +} +``` + +### Defining routes + +The routes are defined by calling the `FastRoute\simpleDispatcher` function, which accepts +a callable taking a `FastRoute\RouteCollector` instance. The routes are added by calling +`addRoute()` on the collector instance. + +This method accepts the HTTP method the route must match, the route pattern and an associated +handler. The handler does not necessarily have to be a callback (it could also be a controller +class name or any other kind of data you wish to associate with the route). + +By default a route pattern syntax is used where `{foo}` specified a placeholder with name `foo` +and matching the string `[^/]+`. To adjust the pattern the placeholder matches, you can specify +a custom pattern by writing `{bar:[0-9]+}`. However, it is also possible to adjust the pattern +syntax by passing using a different route parser. + +A custom pattern for a route placeholder must not use capturing groups. For example `{lang:(en|de)}` +is not a valid placeholder, because `()` is a capturing group. Instead you can use either +`{lang:en|de}` or `{lang:(?:en|de)}`. + +The reason `simpleDispatcher` accepts a callback for defining the routes is to allow seamless +caching. By using `cachedDispatcher` instead of `simpleDispatcher` you can cache the generated +routing data and construct the dispatcher from the cached information: + +```php +addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0'); + $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1'); + $r->addRoute('GET', '/user/{name}', 'handler2'); +}, [ + 'cacheFile' => __DIR__ . '/route.cache', /* required */ + 'cacheDisabled' => IS_DEBUG_ENABLED, /* optional, enabled by default */ +]); +``` + +The second parameter to the function is an options array, which can be used to specify the cache +file location, among other things. + +### Dispatching a URI + +A URI is dispatched by calling the `dispatch()` method of the created dispatcher. This method +accepts the HTTP method and a URI. Getting those two bits of information (and normalizing them +appropriately) is your job - this library is not bound to the PHP web SAPIs. + +The `dispatch()` method returns an array whose first element contains a status code. It is one +of `Dispatcher::NOT_FOUND`, `Dispatcher::METHOD_NOT_ALLOWED` and `Dispatcher::FOUND`. For the +method not allowed status the second array element contains a list of HTTP methods allowed for +the supplied URI. For example: + + [FastRoute\Dispatcher::METHOD_NOT_ALLOWED, ['GET', 'POST']] + +> **NOTE:** The HTTP specification requires that a `405 Method Not Allowed` response include the +`Allow:` header to detail available methods for the requested resource. Applications using FastRoute +should use the second array element to add this header when relaying a 405 response. + +For the found status the second array element is the handler that was associated with the route +and the third array element is a dictionary of placeholder names to their values. For example: + + /* Routing against GET /user/nikic/42 */ + + [FastRoute\Dispatcher::FOUND, 'handler0', ['name' => 'nikic', 'id' => '42']] + +### Overriding the route parser and dispatcher + +The routing process makes use of three components: A route parser, a data generator and a +dispatcher. The three components adhere to the following interfaces: + +```php + 'FastRoute\\RouteParser\\Std', + 'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased', + 'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased', +]); +``` + +The above options array corresponds to the defaults. By replacing `GroupCountBased` by +`GroupPosBased` you could switch to a different dispatching strategy. + +### A Note on HEAD Requests + +The HTTP spec requires servers to [support both GET and HEAD methods][2616-511]: + +> The methods GET and HEAD MUST be supported by all general-purpose servers + +To avoid forcing users to manually register HEAD routes for each resource we fallback to matching an +available GET route for a given resource. The PHP web SAPI transparently removes the entity body +from HEAD responses so this behavior has no effect on the vast majority of users. + +However, implementors using FastRoute outside the web SAPI environment (e.g. a custom server) MUST +NOT send entity bodies generated in response to HEAD requests. If you are a non-SAPI user this is +*your responsibility*; FastRoute has no purview to prevent you from breaking HTTP in such cases. + +Finally, note that applications MAY always specify their own HEAD method route for a given +resource to bypass this behavior entirely. + +### Credits + +This library is based on a router that [Levi Morrison][levi] implemented for the Aerys server. + +A large number of tests, as well as HTTP compliance considerations, were provided by [Daniel Lowrey][rdlowrey]. + + +[2616-511]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1 "RFC 2616 Section 5.1.1" +[blog_post]: http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html +[levi]: https://github.com/morrisonlevi +[rdlowrey]: https://github.com/rdlowrey diff --git a/vendor/nikic/fast-route/composer.json b/vendor/nikic/fast-route/composer.json new file mode 100644 index 0000000..62aad22 --- /dev/null +++ b/vendor/nikic/fast-route/composer.json @@ -0,0 +1,21 @@ +{ + "name": "nikic/fast-route", + "description": "Fast request router for PHP", + "keywords": ["routing", "router"], + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } + ], + "require": { + "php": ">=5.4.0" + }, + "autoload": { + "psr-4": { + "FastRoute\\": "src/" + }, + "files": ["src/functions.php"] + } +} diff --git a/vendor/nikic/fast-route/phpunit.xml b/vendor/nikic/fast-route/phpunit.xml new file mode 100644 index 0000000..3c807b6 --- /dev/null +++ b/vendor/nikic/fast-route/phpunit.xml @@ -0,0 +1,24 @@ + + + + + + ./test/ + + + + + + ./src/ + + + diff --git a/vendor/nikic/fast-route/src/BadRouteException.php b/vendor/nikic/fast-route/src/BadRouteException.php new file mode 100644 index 0000000..7e38479 --- /dev/null +++ b/vendor/nikic/fast-route/src/BadRouteException.php @@ -0,0 +1,6 @@ + $route) { + $suffixLen++; + $suffix .= "\t"; + + $regexes[] = '(?:' . $regex . '/(\t{' . $suffixLen . '})\t{' . ($count - $suffixLen) . '})'; + $routeMap[$suffix] = [$route->handler, $route->variables]; + } + + $regex = '~^(?|' . implode('|', $regexes) . ')$~'; + return ['regex' => $regex, 'suffix' => '/' . $suffix, 'routeMap' => $routeMap]; + } +} diff --git a/vendor/nikic/fast-route/src/DataGenerator/GroupCountBased.php b/vendor/nikic/fast-route/src/DataGenerator/GroupCountBased.php new file mode 100644 index 0000000..d51807f --- /dev/null +++ b/vendor/nikic/fast-route/src/DataGenerator/GroupCountBased.php @@ -0,0 +1,28 @@ + $route) { + $numVariables = count($route->variables); + $numGroups = max($numGroups, $numVariables); + + $regexes[] = $regex . str_repeat('()', $numGroups - $numVariables); + $routeMap[$numGroups + 1] = [$route->handler, $route->variables]; + + ++$numGroups; + } + + $regex = '~^(?|' . implode('|', $regexes) . ')$~'; + return ['regex' => $regex, 'routeMap' => $routeMap]; + } +} + diff --git a/vendor/nikic/fast-route/src/DataGenerator/GroupPosBased.php b/vendor/nikic/fast-route/src/DataGenerator/GroupPosBased.php new file mode 100644 index 0000000..4152f7a --- /dev/null +++ b/vendor/nikic/fast-route/src/DataGenerator/GroupPosBased.php @@ -0,0 +1,25 @@ + $route) { + $regexes[] = $regex; + $routeMap[$offset] = [$route->handler, $route->variables]; + + $offset += count($route->variables); + } + + $regex = '~^(?:' . implode('|', $regexes) . ')$~'; + return ['regex' => $regex, 'routeMap' => $routeMap]; + } +} + diff --git a/vendor/nikic/fast-route/src/DataGenerator/MarkBased.php b/vendor/nikic/fast-route/src/DataGenerator/MarkBased.php new file mode 100644 index 0000000..61359f5 --- /dev/null +++ b/vendor/nikic/fast-route/src/DataGenerator/MarkBased.php @@ -0,0 +1,25 @@ + $route) { + $regexes[] = $regex . '(*MARK:' . $markName . ')'; + $routeMap[$markName] = [$route->handler, $route->variables]; + + ++$markName; + } + + $regex = '~^(?|' . implode('|', $regexes) . ')$~'; + return ['regex' => $regex, 'routeMap' => $routeMap]; + } +} + diff --git a/vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php b/vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php new file mode 100644 index 0000000..6c1e0c5 --- /dev/null +++ b/vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php @@ -0,0 +1,113 @@ +isStaticRoute($routeData)) { + $this->addStaticRoute($httpMethod, $routeData, $handler); + } else { + $this->addVariableRoute($httpMethod, $routeData, $handler); + } + } + + public function getData() { + if (empty($this->methodToRegexToRoutesMap)) { + return [$this->staticRoutes, []]; + } + + return [$this->staticRoutes, $this->generateVariableRouteData()]; + } + + private function generateVariableRouteData() { + $data = []; + foreach ($this->methodToRegexToRoutesMap as $method => $regexToRoutesMap) { + $chunkSize = $this->computeChunkSize(count($regexToRoutesMap)); + $chunks = array_chunk($regexToRoutesMap, $chunkSize, true); + $data[$method] = array_map([$this, 'processChunk'], $chunks); + } + return $data; + } + + private function computeChunkSize($count) { + $numParts = max(1, round($count / $this->getApproxChunkSize())); + return ceil($count / $numParts); + } + + private function isStaticRoute($routeData) { + return count($routeData) == 1 && is_string($routeData[0]); + } + + private function addStaticRoute($httpMethod, $routeData, $handler) { + $routeStr = $routeData[0]; + + if (isset($this->staticRoutes[$routeStr][$httpMethod])) { + throw new BadRouteException(sprintf( + 'Cannot register two routes matching "%s" for method "%s"', + $routeStr, $httpMethod + )); + } + + if (isset($this->methodToRegexToRoutesMap[$httpMethod])) { + foreach ($this->methodToRegexToRoutesMap[$httpMethod] as $route) { + if ($route->matches($routeStr)) { + throw new BadRouteException(sprintf( + 'Static route "%s" is shadowed by previously defined variable route "%s" for method "%s"', + $routeStr, $route->regex, $httpMethod + )); + } + } + } + + $this->staticRoutes[$routeStr][$httpMethod] = $handler; + } + + private function addVariableRoute($httpMethod, $routeData, $handler) { + list($regex, $variables) = $this->buildRegexForRoute($routeData); + + if (isset($this->methodToRegexToRoutesMap[$httpMethod][$regex])) { + throw new BadRouteException(sprintf( + 'Cannot register two routes matching "%s" for method "%s"', + $regex, $httpMethod + )); + } + + $this->methodToRegexToRoutesMap[$httpMethod][$regex] = new Route( + $httpMethod, $handler, $regex, $variables + ); + } + + private function buildRegexForRoute($routeData) { + $regex = ''; + $variables = []; + foreach ($routeData as $part) { + if (is_string($part)) { + $regex .= preg_quote($part, '~'); + continue; + } + + list($varName, $regexPart) = $part; + + if (isset($variables[$varName])) { + throw new BadRouteException(sprintf( + 'Cannot use the same placeholder "%s" twice', $varName + )); + } + + $variables[$varName] = $varName; + $regex .= '(' . $regexPart . ')'; + } + + return [$regex, $variables]; + } +} diff --git a/vendor/nikic/fast-route/src/Dispatcher.php b/vendor/nikic/fast-route/src/Dispatcher.php new file mode 100644 index 0000000..ea98009 --- /dev/null +++ b/vendor/nikic/fast-route/src/Dispatcher.php @@ -0,0 +1,25 @@ + 'value', ...]] + * + * @param string $httpMethod + * @param string $uri + * + * @return array + */ + public function dispatch($httpMethod, $uri); +} diff --git a/vendor/nikic/fast-route/src/Dispatcher/CharCountBased.php b/vendor/nikic/fast-route/src/Dispatcher/CharCountBased.php new file mode 100644 index 0000000..22ba240 --- /dev/null +++ b/vendor/nikic/fast-route/src/Dispatcher/CharCountBased.php @@ -0,0 +1,28 @@ +staticRouteMap, $this->variableRouteData) = $data; + } + + protected function dispatchVariableRoute($routeData, $uri) { + foreach ($routeData as $data) { + if (!preg_match($data['regex'], $uri . $data['suffix'], $matches)) { + continue; + } + + list($handler, $varNames) = $data['routeMap'][end($matches)]; + + $vars = []; + $i = 0; + foreach ($varNames as $varName) { + $vars[$varName] = $matches[++$i]; + } + return [self::FOUND, $handler, $vars]; + } + + return [self::NOT_FOUND]; + } +} diff --git a/vendor/nikic/fast-route/src/Dispatcher/GroupCountBased.php b/vendor/nikic/fast-route/src/Dispatcher/GroupCountBased.php new file mode 100644 index 0000000..0abd322 --- /dev/null +++ b/vendor/nikic/fast-route/src/Dispatcher/GroupCountBased.php @@ -0,0 +1,28 @@ +staticRouteMap, $this->variableRouteData) = $data; + } + + protected function dispatchVariableRoute($routeData, $uri) { + foreach ($routeData as $data) { + if (!preg_match($data['regex'], $uri, $matches)) { + continue; + } + + list($handler, $varNames) = $data['routeMap'][count($matches)]; + + $vars = []; + $i = 0; + foreach ($varNames as $varName) { + $vars[$varName] = $matches[++$i]; + } + return [self::FOUND, $handler, $vars]; + } + + return [self::NOT_FOUND]; + } +} diff --git a/vendor/nikic/fast-route/src/Dispatcher/GroupPosBased.php b/vendor/nikic/fast-route/src/Dispatcher/GroupPosBased.php new file mode 100644 index 0000000..32227d4 --- /dev/null +++ b/vendor/nikic/fast-route/src/Dispatcher/GroupPosBased.php @@ -0,0 +1,30 @@ +staticRouteMap, $this->variableRouteData) = $data; + } + + protected function dispatchVariableRoute($routeData, $uri) { + foreach ($routeData as $data) { + if (!preg_match($data['regex'], $uri, $matches)) { + continue; + } + + // find first non-empty match + for ($i = 1; '' === $matches[$i]; ++$i); + + list($handler, $varNames) = $data['routeMap'][$i]; + + $vars = []; + foreach ($varNames as $varName) { + $vars[$varName] = $matches[$i++]; + } + return [self::FOUND, $handler, $vars]; + } + + return [self::NOT_FOUND]; + } +} diff --git a/vendor/nikic/fast-route/src/Dispatcher/MarkBased.php b/vendor/nikic/fast-route/src/Dispatcher/MarkBased.php new file mode 100644 index 0000000..fefa711 --- /dev/null +++ b/vendor/nikic/fast-route/src/Dispatcher/MarkBased.php @@ -0,0 +1,28 @@ +staticRouteMap, $this->variableRouteData) = $data; + } + + protected function dispatchVariableRoute($routeData, $uri) { + foreach ($routeData as $data) { + if (!preg_match($data['regex'], $uri, $matches)) { + continue; + } + + list($handler, $varNames) = $data['routeMap'][$matches['MARK']]; + + $vars = []; + $i = 0; + foreach ($varNames as $varName) { + $vars[$varName] = $matches[++$i]; + } + return [self::FOUND, $handler, $vars]; + } + + return [self::NOT_FOUND]; + } +} diff --git a/vendor/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php b/vendor/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php new file mode 100644 index 0000000..5e86907 --- /dev/null +++ b/vendor/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php @@ -0,0 +1,64 @@ +staticRouteMap[$uri])) { + return $this->dispatchStaticRoute($httpMethod, $uri); + } + + $varRouteData = $this->variableRouteData; + if (isset($varRouteData[$httpMethod])) { + $result = $this->dispatchVariableRoute($varRouteData[$httpMethod], $uri); + if ($result[0] === self::FOUND) { + return $result; + } + } else if ($httpMethod === 'HEAD' && isset($varRouteData['GET'])) { + $result = $this->dispatchVariableRoute($varRouteData['GET'], $uri); + if ($result[0] === self::FOUND) { + return $result; + } + } + + // Find allowed methods for this URI by matching against all other + // HTTP methods as well + $allowedMethods = []; + foreach ($varRouteData as $method => $routeData) { + if ($method === $httpMethod) { + continue; + } + + $result = $this->dispatchVariableRoute($routeData, $uri); + if ($result[0] === self::FOUND) { + $allowedMethods[] = $method; + } + } + + // If there are no allowed methods the route simply does not exist + if ($allowedMethods) { + return [self::METHOD_NOT_ALLOWED, $allowedMethods]; + } else { + return [self::NOT_FOUND]; + } + } + + protected function dispatchStaticRoute($httpMethod, $uri) { + $routes = $this->staticRouteMap[$uri]; + + if (isset($routes[$httpMethod])) { + return [self::FOUND, $routes[$httpMethod], []]; + } elseif ($httpMethod === 'HEAD' && isset($routes['GET'])) { + return [self::FOUND, $routes['GET'], []]; + } else { + return [self::METHOD_NOT_ALLOWED, array_keys($routes)]; + } + } +} diff --git a/vendor/nikic/fast-route/src/Route.php b/vendor/nikic/fast-route/src/Route.php new file mode 100644 index 0000000..d71ded1 --- /dev/null +++ b/vendor/nikic/fast-route/src/Route.php @@ -0,0 +1,38 @@ +httpMethod = $httpMethod; + $this->handler = $handler; + $this->regex = $regex; + $this->variables = $variables; + } + + /** + * Tests whether this route matches the given string. + * + * @param string $str + * + * @return bool + */ + public function matches($str) { + $regex = '~^' . $this->regex . '$~'; + return (bool) preg_match($regex, $str); + } +} + diff --git a/vendor/nikic/fast-route/src/RouteCollector.php b/vendor/nikic/fast-route/src/RouteCollector.php new file mode 100644 index 0000000..15d5e88 --- /dev/null +++ b/vendor/nikic/fast-route/src/RouteCollector.php @@ -0,0 +1,44 @@ +routeParser = $routeParser; + $this->dataGenerator = $dataGenerator; + } + + /** + * Adds a route to the collection. + * + * The syntax used in the $route string depends on the used route parser. + * + * @param string|string[] $httpMethod + * @param string $route + * @param mixed $handler + */ + public function addRoute($httpMethod, $route, $handler) { + $routeData = $this->routeParser->parse($route); + foreach ((array) $httpMethod as $method) { + $this->dataGenerator->addRoute($method, $routeData, $handler); + } + } + + /** + * Returns the collected route data, as provided by the data generator. + * + * @return array + */ + public function getData() { + return $this->dataGenerator->getData(); + } +} diff --git a/vendor/nikic/fast-route/src/RouteParser.php b/vendor/nikic/fast-route/src/RouteParser.php new file mode 100644 index 0000000..6c2c2cf --- /dev/null +++ b/vendor/nikic/fast-route/src/RouteParser.php @@ -0,0 +1,21 @@ + $offset) { + $routeData[] = substr($route, $offset, $set[0][1] - $offset); + } + $routeData[] = [ + $set[1][0], + isset($set[2]) ? trim($set[2][0]) : self::DEFAULT_DISPATCH_REGEX + ]; + $offset = $set[0][1] + strlen($set[0][0]); + } + + if ($offset != strlen($route)) { + $routeData[] = substr($route, $offset); + } + + return $routeData; + } +} diff --git a/vendor/nikic/fast-route/src/bootstrap.php b/vendor/nikic/fast-route/src/bootstrap.php new file mode 100644 index 0000000..add216c --- /dev/null +++ b/vendor/nikic/fast-route/src/bootstrap.php @@ -0,0 +1,12 @@ + 'FastRoute\\RouteParser\\Std', + 'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased', + 'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased', + ]; + + $routeCollector = new RouteCollector( + new $options['routeParser'], new $options['dataGenerator'] + ); + $routeDefinitionCallback($routeCollector); + + return new $options['dispatcher']($routeCollector->getData()); +} + +/** + * @param callable $routeDefinitionCallback + * @param array $options + * + * @return Dispatcher + */ +function cachedDispatcher(callable $routeDefinitionCallback, array $options = []) { + $options += [ + 'routeParser' => 'FastRoute\\RouteParser\\Std', + 'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased', + 'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased', + 'cacheDisabled' => false, + ]; + + if (!isset($options['cacheFile'])) { + throw new \LogicException('Must specify "cacheFile" option'); + } + + if (!$options['cacheDisabled'] && file_exists($options['cacheFile'])) { + $dispatchData = require $options['cacheFile']; + if (!is_array($dispatchData)) { + throw new \RuntimeException('Invalid cache file "' . $options['cacheFile'] . '"'); + } + return new $options['dispatcher']($dispatchData); + } + + $routeCollector = new RouteCollector( + new $options['routeParser'], new $options['dataGenerator'] + ); + $routeDefinitionCallback($routeCollector); + + $dispatchData = $routeCollector->getData(); + file_put_contents( + $options['cacheFile'], + ' $this->getDataGeneratorClass(), + 'dispatcher' => $this->getDispatcherClass() + ]; + } + + /** + * @dataProvider provideFoundDispatchCases + */ + public function testFoundDispatches($method, $uri, $callback, $handler, $argDict) { + $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions()); + list($routedStatus, $routedTo, $routedArgs) = $dispatcher->dispatch($method, $uri); + $this->assertSame($dispatcher::FOUND, $routedStatus); + $this->assertSame($handler, $routedTo); + $this->assertSame($argDict, $routedArgs); + } + + /** + * @dataProvider provideNotFoundDispatchCases + */ + public function testNotFoundDispatches($method, $uri, $callback) { + $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions()); + $this->assertFalse(isset($routeInfo[1]), + "NOT_FOUND result must only contain a single element in the returned info array" + ); + list($routedStatus) = $dispatcher->dispatch($method, $uri); + $this->assertSame($dispatcher::NOT_FOUND, $routedStatus); + } + + /** + * @dataProvider provideMethodNotAllowedDispatchCases + */ + public function testMethodNotAllowedDispatches($method, $uri, $callback, $availableMethods) { + $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions()); + $routeInfo = $dispatcher->dispatch($method, $uri); + $this->assertTrue(isset($routeInfo[1]), + "METHOD_NOT_ALLOWED result must return an array of allowed methods at index 1" + ); + + list($routedStatus, $methodArray) = $dispatcher->dispatch($method, $uri); + $this->assertSame($dispatcher::METHOD_NOT_ALLOWED, $routedStatus); + $this->assertSame($availableMethods, $methodArray); + } + + /** + * @expectedException \FastRoute\BadRouteException + * @expectedExceptionMessage Cannot use the same placeholder "test" twice + */ + public function testDuplicateVariableNameError() { + \FastRoute\simpleDispatcher(function(RouteCollector $r) { + $r->addRoute('GET', '/foo/{test}/{test:\d+}', 'handler0'); + }, $this->generateDispatcherOptions()); + } + + /** + * @expectedException \FastRoute\BadRouteException + * @expectedExceptionMessage Cannot register two routes matching "/user/([^/]+)" for method "GET" + */ + public function testDuplicateVariableRoute() { + \FastRoute\simpleDispatcher(function(RouteCollector $r) { + $r->addRoute('GET', '/user/{id}', 'handler0'); // oops, forgot \d+ restriction ;) + $r->addRoute('GET', '/user/{name}', 'handler1'); + }, $this->generateDispatcherOptions()); + } + + /** + * @expectedException \FastRoute\BadRouteException + * @expectedExceptionMessage Cannot register two routes matching "/user" for method "GET" + */ + public function testDuplicateStaticRoute() { + \FastRoute\simpleDispatcher(function(RouteCollector $r) { + $r->addRoute('GET', '/user', 'handler0'); + $r->addRoute('GET', '/user', 'handler1'); + }, $this->generateDispatcherOptions()); + } + + /** + * @expectedException \FastRoute\BadRouteException + * @expectedExceptionMessage Static route "/user/nikic" is shadowed by previously defined variable route "/user/([^/]+)" for method "GET" + */ + public function testShadowedStaticRoute() { + \FastRoute\simpleDispatcher(function(RouteCollector $r) { + $r->addRoute('GET', '/user/{name}', 'handler0'); + $r->addRoute('GET', '/user/nikic', 'handler1'); + }, $this->generateDispatcherOptions()); + } + + public function provideFoundDispatchCases() { + $cases = []; + + // 0 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/resource/123/456', 'handler0'); + }; + + $method = 'GET'; + $uri = '/resource/123/456'; + $handler = 'handler0'; + $argDict = []; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 1 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/handler0', 'handler0'); + $r->addRoute('GET', '/handler1', 'handler1'); + $r->addRoute('GET', '/handler2', 'handler2'); + }; + + $method = 'GET'; + $uri = '/handler2'; + $handler = 'handler2'; + $argDict = []; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 2 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0'); + $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1'); + $r->addRoute('GET', '/user/{name}', 'handler2'); + }; + + $method = 'GET'; + $uri = '/user/rdlowrey'; + $handler = 'handler2'; + $argDict = ['name' => 'rdlowrey']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 3 --------------------------------------------------------------------------------------> + + // reuse $callback from #2 + + $method = 'GET'; + $uri = '/user/12345'; + $handler = 'handler1'; + $argDict = ['id' => '12345']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 4 --------------------------------------------------------------------------------------> + + // reuse $callback from #3 + + $method = 'GET'; + $uri = '/user/NaN'; + $handler = 'handler2'; + $argDict = ['name' => 'NaN']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 5 --------------------------------------------------------------------------------------> + + // reuse $callback from #4 + + $method = 'GET'; + $uri = '/user/rdlowrey/12345'; + $handler = 'handler0'; + $argDict = ['name' => 'rdlowrey', 'id' => '12345']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 6 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler0'); + $r->addRoute('GET', '/user/12345/extension', 'handler1'); + $r->addRoute('GET', '/user/{id:[0-9]+}.{extension}', 'handler2'); + + }; + + $method = 'GET'; + $uri = '/user/12345.svg'; + $handler = 'handler2'; + $argDict = ['id' => '12345', 'extension' => 'svg']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 7 ----- Test GET method fallback on HEAD route miss ------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/user/{name}', 'handler0'); + $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler1'); + $r->addRoute('GET', '/static0', 'handler2'); + $r->addRoute('GET', '/static1', 'handler3'); + $r->addRoute('HEAD', '/static1', 'handler4'); + }; + + $method = 'HEAD'; + $uri = '/user/rdlowrey'; + $handler = 'handler0'; + $argDict = ['name' => 'rdlowrey']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 8 ----- Test GET method fallback on HEAD route miss ------------------------------------> + + // reuse $callback from #7 + + $method = 'HEAD'; + $uri = '/user/rdlowrey/1234'; + $handler = 'handler1'; + $argDict = ['name' => 'rdlowrey', 'id' => '1234']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 9 ----- Test GET method fallback on HEAD route miss ------------------------------------> + + // reuse $callback from #8 + + $method = 'HEAD'; + $uri = '/static0'; + $handler = 'handler2'; + $argDict = []; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 10 ---- Test existing HEAD route used if available (no fallback) -----------------------> + + // reuse $callback from #9 + + $method = 'HEAD'; + $uri = '/static1'; + $handler = 'handler4'; + $argDict = []; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 11 ---- More specified routes are not shadowed by less specific of another method ------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/user/{name}', 'handler0'); + $r->addRoute('POST', '/user/{name:[a-z]+}', 'handler1'); + }; + + $method = 'POST'; + $uri = '/user/rdlowrey'; + $handler = 'handler1'; + $argDict = ['name' => 'rdlowrey']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 12 ---- Handler of more specific routes is used, if it occurs first --------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/user/{name}', 'handler0'); + $r->addRoute('POST', '/user/{name:[a-z]+}', 'handler1'); + $r->addRoute('POST', '/user/{name}', 'handler2'); + }; + + $method = 'POST'; + $uri = '/user/rdlowrey'; + $handler = 'handler1'; + $argDict = ['name' => 'rdlowrey']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 13 ---- Route with constant suffix -----------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/user/{name}', 'handler0'); + $r->addRoute('GET', '/user/{name}/edit', 'handler1'); + }; + + $method = 'GET'; + $uri = '/user/rdlowrey/edit'; + $handler = 'handler1'; + $argDict = ['name' => 'rdlowrey']; + + $cases[] = [$method, $uri, $callback, $handler, $argDict]; + + // 14 ---- Handle multiple methods with the same handler ----------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute(['GET', 'POST'], '/user', 'handlerGetPost'); + $r->addRoute(['DELETE'], '/user', 'handlerDelete'); + $r->addRoute([], '/user', 'handlerNone'); + }; + + $argDict = []; + $cases[] = ['GET', '/user', $callback, 'handlerGetPost', $argDict]; + $cases[] = ['POST', '/user', $callback, 'handlerGetPost', $argDict]; + $cases[] = ['DELETE', '/user', $callback, 'handlerDelete', $argDict]; + + + // x --------------------------------------------------------------------------------------> + + return $cases; + } + + public function provideNotFoundDispatchCases() { + $cases = []; + + // 0 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/resource/123/456', 'handler0'); + }; + + $method = 'GET'; + $uri = '/not-found'; + + $cases[] = [$method, $uri, $callback]; + + // 1 --------------------------------------------------------------------------------------> + + // reuse callback from #0 + $method = 'POST'; + $uri = '/not-found'; + + $cases[] = [$method, $uri, $callback]; + + // 2 --------------------------------------------------------------------------------------> + + // reuse callback from #1 + $method = 'PUT'; + $uri = '/not-found'; + + $cases[] = [$method, $uri, $callback]; + + // 3 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/handler0', 'handler0'); + $r->addRoute('GET', '/handler1', 'handler1'); + $r->addRoute('GET', '/handler2', 'handler2'); + }; + + $method = 'GET'; + $uri = '/not-found'; + + $cases[] = [$method, $uri, $callback]; + + // 4 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0'); + $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1'); + $r->addRoute('GET', '/user/{name}', 'handler2'); + }; + + $method = 'GET'; + $uri = '/not-found'; + + $cases[] = [$method, $uri, $callback]; + + // 5 --------------------------------------------------------------------------------------> + + // reuse callback from #4 + $method = 'GET'; + $uri = '/user/rdlowrey/12345/not-found'; + + $cases[] = [$method, $uri, $callback]; + + // 6 --------------------------------------------------------------------------------------> + + // reuse callback from #5 + $method = 'HEAD'; + + $cases[] = array($method, $uri, $callback); + + // x --------------------------------------------------------------------------------------> + + return $cases; + } + + public function provideMethodNotAllowedDispatchCases() { + $cases = []; + + // 0 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/resource/123/456', 'handler0'); + }; + + $method = 'POST'; + $uri = '/resource/123/456'; + $allowedMethods = ['GET']; + + $cases[] = [$method, $uri, $callback, $allowedMethods]; + + // 1 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/resource/123/456', 'handler0'); + $r->addRoute('POST', '/resource/123/456', 'handler1'); + $r->addRoute('PUT', '/resource/123/456', 'handler2'); + }; + + $method = 'DELETE'; + $uri = '/resource/123/456'; + $allowedMethods = ['GET', 'POST', 'PUT']; + + $cases[] = [$method, $uri, $callback, $allowedMethods]; + + // 2 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0'); + $r->addRoute('POST', '/user/{name}/{id:[0-9]+}', 'handler1'); + $r->addRoute('PUT', '/user/{name}/{id:[0-9]+}', 'handler2'); + $r->addRoute('PATCH', '/user/{name}/{id:[0-9]+}', 'handler3'); + }; + + $method = 'DELETE'; + $uri = '/user/rdlowrey/42'; + $allowedMethods = ['GET', 'POST', 'PUT', 'PATCH']; + + $cases[] = [$method, $uri, $callback, $allowedMethods]; + + // 3 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute('POST', '/user/{name}', 'handler1'); + $r->addRoute('PUT', '/user/{name:[a-z]+}', 'handler2'); + $r->addRoute('PATCH', '/user/{name:[a-z]+}', 'handler3'); + }; + + $method = 'GET'; + $uri = '/user/rdlowrey'; + $allowedMethods = ['POST', 'PUT', 'PATCH']; + + $cases[] = [$method, $uri, $callback, $allowedMethods]; + + // 4 --------------------------------------------------------------------------------------> + + $callback = function(RouteCollector $r) { + $r->addRoute(['GET', 'POST'], '/user', 'handlerGetPost'); + $r->addRoute(['DELETE'], '/user', 'handlerDelete'); + $r->addRoute([], '/user', 'handlerNone'); + }; + + $cases[] = ['PUT', '/user', $callback, ['GET', 'POST', 'DELETE']]; + + // x --------------------------------------------------------------------------------------> + + return $cases; + } + +} diff --git a/vendor/nikic/fast-route/test/Dispatcher/GroupCountBasedTest.php b/vendor/nikic/fast-route/test/Dispatcher/GroupCountBasedTest.php new file mode 100644 index 0000000..74820fc --- /dev/null +++ b/vendor/nikic/fast-route/test/Dispatcher/GroupCountBasedTest.php @@ -0,0 +1,13 @@ +markTestSkipped('PHP 5.6 required for MARK support'); + } + } + + protected function getDispatcherClass() { + return 'FastRoute\\Dispatcher\\MarkBased'; + } + + protected function getDataGeneratorClass() { + return 'FastRoute\\DataGenerator\\MarkBased'; + } +} diff --git a/vendor/nikic/fast-route/test/bootstrap.php b/vendor/nikic/fast-route/test/bootstrap.php new file mode 100644 index 0000000..27e6d4c --- /dev/null +++ b/vendor/nikic/fast-route/test/bootstrap.php @@ -0,0 +1,11 @@ +GetRandom()` + 5. `openssl_random_pseudo_bytes()` + +If libsodium is available, we get random data from it. This is the preferred +method on all OSes, but libsodium is not very widely installed, so other +fallbacks are available. + +Next, we read `/dev/urandom` (if it exists). This is the preferred file to read +for random data for cryptographic purposes for BSD and Linux. + +Despite [strongly urging people not to use mcrypt in their projects](https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong), +because libmcrypt is abandonware and the API puts too much responsibility on the +implementor, we prioritize `mcrypt_create_iv()` with `MCRYPT_DEV_URANDOM` above +the remaining implementations. + +The reason is simple: `mcrypt_create_iv()` is part of PHP's `ext/mcrypt` code, +and is not part `libmcrypt`. It actually does the right thing: + + * On Unix-based operating systems, it reads from `/dev/urandom`, which is the + sane and correct thing to do. + * On Windows, it reads from `CryptGenRandom`, which is an exclusively Windows + way to get random bytes. + +If we're on Windows and don't have access to `mcrypt`, we use `CAPICOM.Utilities.1`. + +Finally, we use `openssl_random_pseudo_bytes()` **as a last resort**, due to +[PHP bug #70014](https://bugs.php.net/bug.php?id=70014). Internally, this +function calls `RAND_pseudo_bytes()`, which has been [deprecated](https://github.com/paragonie/random_compat/issues/5) +by the OpenSSL team. Furthermore, [it might silently return weak random data](https://github.com/paragonie/random_compat/issues/6#issuecomment-119564973) +if it is called before OpenSSL's **userspace** CSPRNG is seeded. Also, +[you want the OS CSPRNG, not a userspace CSPRNG](http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/). diff --git a/vendor/paragonie/random_compat/LICENSE b/vendor/paragonie/random_compat/LICENSE new file mode 100644 index 0000000..45c7017 --- /dev/null +++ b/vendor/paragonie/random_compat/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Paragon Initiative Enterprises + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/paragonie/random_compat/README.md b/vendor/paragonie/random_compat/README.md new file mode 100644 index 0000000..ed5b1d8 --- /dev/null +++ b/vendor/paragonie/random_compat/README.md @@ -0,0 +1,149 @@ +# random_compat + +[![Build Status](https://travis-ci.org/paragonie/random_compat.svg?branch=master)](https://travis-ci.org/paragonie/random_compat) +[![Scrutinizer](https://scrutinizer-ci.com/g/paragonie/random_compat/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/paragonie/random_compat) + +PHP 5.x polyfill for `random_bytes()` and `random_int()` created and maintained +by [Paragon Initiative Enterprises](https://paragonie.com). + +Although this library *should* function in earlier versions of PHP, we will only +consider issues relevant to [supported PHP versions](https://secure.php.net/supported-versions.php). +**If you are using an unsupported version of PHP, please upgrade as soon as possible.** + +## Important + +Although this library has been examined by some security experts in the PHP +community, there will always be a chance that we overlooked something. Please +ask your favorite trusted hackers to hammer it for implementation errors and +bugs before even thinking about deploying it in production. + +**Do not use the master branch, use a [stable release](https://github.com/paragonie/random_compat/releases/latest).** + +For the background of this library, please refer to our blog post on +[Generating Random Integers and Strings in PHP](https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php). + +### Usability Notice + +If PHP cannot safely generate random data, this library will throw an `Exception`. +It will never fall back to insecure random data. If this keeps happening, upgrade +to a newer version of PHP immediately. + +## Usage + +This library exposes the [CSPRNG functions added in PHP 7](https://secure.php.net/manual/en/ref.csprng.php) +for use in PHP 5 projects. Their behavior should be identical. + +### Generate a string of random bytes + +```php +try { + $string = random_bytes(32); +} catch (TypeError $e) { + // Well, it's an integer, so this IS unexpected. + die("An unexpected error has occurred"); +} catch (Error $e) { + // This is also unexpected because 32 is a reasonable integer. + die("An unexpected error has occurred"); +} catch (Exception $e) { + // If you get this message, the CSPRNG failed hard. + die("Could not generate a random string. Is our OS secure?"); +} + +var_dump(bin2hex($string)); +// string(64) "5787c41ae124b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2eeac6f" +``` + +### Generate a random integer between two given integers (inclusive) + +```php +try { + $int = random_int(0,255); + +} catch (TypeError $e) { + // Well, it's an integer, so this IS unexpected. + die("An unexpected error has occurred"); +} catch (Error $e) { + // This is also unexpected because 0 and 255 are both reasonable integers. + die("An unexpected error has occurred"); +} catch (Exception $e) { + // If you get this message, the CSPRNG failed hard. + die("Could not generate a random string. Is our OS secure?"); +} + +var_dump($int); +// int(47) +``` + +### Exception handling + +When handling exceptions and errors you must account for differences between +PHP 5 and PHP7. + +The differences: + +* Catching `Error` works, so long as it is caught before `Exception`. +* Catching `Exception` has different behavior, without previously catching `Error`. +* There is *no* portable way to catch all errors/exceptions. + +#### Our recommendation + +**Always** catch `Error` before `Exception`. + +#### Example + +```php +try { + return random_int(1, $userInput); +} catch (TypeError $e) { + // This is okay, so long as `Error` is caught before `Exception`. + throw new Exception('Please enter a number!'); +} catch (Error $e) { + // This is required, if you do not need to do anything just rethrow. + throw $e; +} catch (Exception $e) { + // This is optional and maybe omitted if you do not want to handle errors + // during generation. + throw new InternalServerErrorException( + 'Oops, our server is bust and cannot generate any random data.', + 500, + $e + ); +} +``` + +## Contributors + +This project would not be anywhere near as excellent as it is today if it +weren't for the contributions of the following individuals: + +* [@AndrewCarterUK (Andrew Carter)](https://github.com/AndrewCarterUK) +* [@asgrim (James Titcumb)](https://github.com/asgrim) +* [@CodesInChaos (Christian Winnerlein)](https://github.com/CodesInChaos) +* [@chriscct7 (Chris Christoff)](https://github.com/chriscct7) +* [@cs278 (Chris Smith)](https://github.com/cs278) +* [@cweagans (Cameron Eagans)](https://github.com/cweagans) +* [@dd32 (Dion Hulse)](https://github.com/dd32) +* [@geggleto (Glenn Eggleton)](https://github.com/geggleto) +* [@ircmaxell (Anthony Ferrara)](https://github.com/ircmaxell) +* [@jedisct1 (Frank Denis)](https://github.com/jedisct1) +* [@juliangut (Julián Gutiérrez)](https://github.com/juliangut) +* [@kelunik (Niklas Keller)](https://github.com/kelunik) +* [@lt (Leigh)](https://github.com/lt) +* [@MasonM (Mason Malone)](https://github.com/MasonM) +* [@mmeyer2k (Michael M)](https://github.com/mmeyer2k) +* [@narfbg (Andrey Andreev)](https://github.com/narfbg) +* [@nicolas-grekas (Nicolas Grekas)](https://github.com/nicolas-grekas) +* [@oittaa](https://github.com/oittaa) +* [@redragonx (Stephen Chavez)](https://github.com/redragonx) +* [@rchouinard (Ryan Chouinard)](https://github.com/rchouinard) +* [@SammyK (Sammy Kaye Powers)](https://github.com/SammyK) +* [@scottchiefbaker (Scott Baker)](https://github.com/scottchiefbaker) +* [@skyosev (Stoyan Kyosev)](https://github.com/skyosev) +* [@stof (Christophe Coevoet)](https://github.com/stof) +* [@teohhanhui (Teoh Han Hui)](https://github.com/teohhanhui) +* [@tom-- (Tom Worster)](https://github.com/tom--) +* [@tsyr2ko](https://github.com/tsyr2ko) +* [@trowski (Aaron Piotrowski)](https://github.com/trowski) +* [@twistor (Chris Lepannen)](https://github.com/twistor) +* [@voku (Lars Moelleken)](https://github.com/voku) +* [@xabbuh (Christian Flothmann)](https://github.com/xabbuh) diff --git a/vendor/paragonie/random_compat/SECURITY.md b/vendor/paragonie/random_compat/SECURITY.md new file mode 100644 index 0000000..8f731b3 --- /dev/null +++ b/vendor/paragonie/random_compat/SECURITY.md @@ -0,0 +1,108 @@ +# An Invitation to Security Researchers + +Every company says they take security "very seriously." Rather than bore anyone +with banal boilerplate, here are some quick answers followed by detailed +elaboration. If you have any questions about our policies, please email them to +`scott@paragonie.com`. + +## Quick Answers + +* There is no compulsion to disclose vulnerabilities privately, but we + appreciate a head's up. +* `security@paragonie.com` will get your reports to the right person. Our GPG + fingerprint, should you decide to encrypt your report, is + `7F52 D5C6 1D12 55C7 3136 2E82 6B97 A1C2 8264 04DA`. + +* **YES**, we will reward security researchers who disclose vulnerabilities in + our software. +* In most cases, **No Proof-of-Concept Required.** + +## How to Report a Security Bug to Paragon Initiative Enterprises + +### There is no compulsion to disclose privately. + +We believe vulnerability disclosure style is a personal choice and enjoy working +with a diverse community. We understand and appreciate the importance of Full +Disclosure in the history and practice of security research. + +We would *like* to know about high-severity bugs before they become public +knowledge, so we can fix them in a timely manner, but **we do not believe in +threatening researchers or trying to enforce vulnerability embargoes**. + +Ultimately, if you discover a security-affecting vulnerability, what you do with +it is your choice. We would like to work with people, and to celebrate and +reward their skill, experience, and dedication. We appreciate being informed of +our mistakes so we can learn from them and build a better product. Our goal is +to empower the community. + +### Where to Send Security Vulnerabilities + +Our security email address is `security@paragonie.com`. Also feel free to open a +new issue on Github if you want to disclose publicly. + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG + +mQENBFUgwRUBCADcIpqNwyYc5UmY/tpx1sF/rQ3knR1YNXYZThzFV+Gmqhp1fDH5 +qBs9foh1xwI6O7knWmQngnf/nBumI3x6xj7PuOdEZUh2FwCG/VWnglW8rKmoHzHA +ivjiu9SLnPIPAgHSHeh2XD7q3Ndm3nenbjAiRFNl2iXcwA2cTQp9Mmfw9vVcw0G0 +z1o0G3s8cC8ZS6flFySIervvfSRWj7A1acI5eE3+AH/qXJRdEJ+9J8OB65p1JMfk +6+fWgOB1XZxMpz70S0rW6IX38WDSRhEK2fXyZJAJjyt+YGuzjZySNSoQR/V6vNYn +syrNPCJ2i5CgZQxAkyBBcr7koV9RIhPRzct/ABEBAAG0IVNlY3VyaXR5IDxzZWN1 +cml0eUBwYXJhZ29uaWUuY29tPokBOQQTAQIAIwUCVSDBFQIbAwcLCQgHAwIBBhUI +AgkKCwQWAgMBAh4BAheAAAoJEGuXocKCZATat2YIAIoejNFEQ2c1iaOEtSuB7Pn/ +WLbsDsHNLDKOV+UnfaCjv/vL7D+5NMChFCi2frde/NQb2TsjqmIH+V+XbnJtlrXD +Vj7yvMVal+Jqjwj7v4eOEWcKVcFZk+9cfUgh7t92T2BMX58RpgZF0IQZ6Z1R3FfC +9Ub4X6ykW+te1q0/4CoRycniwmlQi6iGSr99LQ5pfJq2Qlmz/luTZ0UX0h575T7d +cp2T1sX/zFRk/fHeANWSksipdDBjAXR7NMnYZgw2HghEdFk/xRDY7K1NRWNZBf05 +WrMHmh6AIVJiWZvI175URxEe268hh+wThBhXQHMhFNJM1qPIuzb4WogxM3UUD7m5 +AQ0EVSDBFQEIALNkpzSuJsHAHh79sc0AYWztdUe2MzyofQbbOnOCpWZebYsC3EXU +335fIg59k0m6f+O7GmEZzzIv5v0i99GS1R8CJm6FvhGqtH8ZqmOGbc71WdJSiNVE +0kpQoJlVzRbig6ZyyjzrggbM1eh5OXOk5pw4+23FFEdw7JWU0HJS2o71r1hwp05Z +vy21kcUEobz/WWQQyGS0Neo7PJn+9KS6wOxXul/UE0jct/5f7KLMdWMJ1VgniQmm +hjvkHLPSICteqCI04RfcmMseW9gueHQXeUu1SNIvsWa2MhxjeBej3pDnrZWszKwy +gF45GO9/v4tkIXNMy5J1AtOyRgQ3IUMqp8EAEQEAAYkBHwQYAQIACQUCVSDBFQIb +DAAKCRBrl6HCgmQE2jnIB/4/xFz8InpM7eybnBOAir3uGcYfs3DOmaKn7qWVtGzv +rKpQPYnVtlU2i6Z5UO4c4jDLT/8Xm1UDz3Lxvqt4xCaDwJvBZexU5BMK8l5DvOzH +6o6P2L1UDu6BvmPXpVZz7/qUhOnyf8VQg/dAtYF4/ax19giNUpI5j5o5mX5w80Rx +qSXV9NdSL4fdjeG1g/xXv2luhoV53T1bsycI3wjk/x5tV+M2KVhZBvvuOm/zhJje +oLWp0saaESkGXIXqurj6gZoujJvSvzl0n9F9VwqMEizDUfrXgtD1siQGhP0sVC6q +ha+F/SAEJ0jEquM4TfKWWU2S5V5vgPPpIQSYRnhQW4b1 +=xJPW +-----END PGP PUBLIC KEY BLOCK----- +``` + +### We Will Reward Security Researchers + +**This process has not been formalized; nor have dollar amounts been +discussed.** + +However, if you report a valid security-affecting bug, we will compensate you +for the time spent finding the vulnerability and reward you for being a good +neighbor. + +#### What does a "valid" bug mean? + +There are two sides to this: + +1. Some have spammed projects with invalid bug reports hoping to collect + bounties for pressing a button and running an automated analysis tool. This + is not cool. +2. There is a potential for the developers of a project to declare all security + bug reports as invalid to save money. + +Our team members have an established history of reporting vulnerabilities to +large open source projects. **We aren't in the business of ripping people off.** +When in doubt, our policy is to err on the side of generosity. + +### No Proof-of-Concept Required + +We might ask for one if we feel we do not understand some of the details +pertaining to a specific vulnerability. We certainly appreciate them if you +include them in your report, but we believe **the burden lies with the developer +to prove their software *is* secure** rather than with the researcher to prove +that it isn't. + +In our experience, most bugs are simpler to fix than they are to exploit. + diff --git a/vendor/paragonie/random_compat/composer.json b/vendor/paragonie/random_compat/composer.json new file mode 100644 index 0000000..d70abf4 --- /dev/null +++ b/vendor/paragonie/random_compat/composer.json @@ -0,0 +1,32 @@ +{ + "name": "paragonie/random_compat", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "random", + "pseudorandom" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "support": { + "issues": "https://github.com/paragonie/random_compat/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/random_compat" + }, + "require": { + "php": ">=5.2.0" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "autoload": { + "files": ["lib/random.php"] + } +} diff --git a/vendor/paragonie/random_compat/lib/byte_safe_strings.php b/vendor/paragonie/random_compat/lib/byte_safe_strings.php new file mode 100644 index 0000000..a3cc90b --- /dev/null +++ b/vendor/paragonie/random_compat/lib/byte_safe_strings.php @@ -0,0 +1,160 @@ + operators might accidentally let a float + * through. + * + * @param numeric $number The number we want to convert to an int + * @param boolean $fail_open Set to true to not throw an exception + * + * @return int (or float if $fail_open) + */ + function RandomCompat_intval($number, $fail_open = false) + { + if (is_numeric($number)) { + $number += 0; + } + if ( + is_float($number) && + $number > ~PHP_INT_MAX && + $number < PHP_INT_MAX + ) { + $number = (int) $number; + } + if (is_int($number) || $fail_open) { + return $number; + } + throw new TypeError( + 'Expected an integer.' + ); + } +} diff --git a/vendor/paragonie/random_compat/lib/error_polyfill.php b/vendor/paragonie/random_compat/lib/error_polyfill.php new file mode 100644 index 0000000..57cfefd --- /dev/null +++ b/vendor/paragonie/random_compat/lib/error_polyfill.php @@ -0,0 +1,42 @@ +GetRandom() + * 5. openssl_random_pseudo_bytes() (absolute last resort) + * + * See ERRATA.md for our reasoning behind this particular order + */ + if (extension_loaded('libsodium')) { + // See random_bytes_libsodium.php + require_once $RandomCompatDIR.'/random_bytes_libsodium.php'; + } + if ( + !function_exists('random_bytes') && + DIRECTORY_SEPARATOR === '/' && + @is_readable('/dev/urandom') + ) { + // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast + // way to exclude Windows. + // + // Error suppression on is_readable() in case of an open_basedir or + // safe_mode failure. All we care about is whether or not we can + // read it at this point. If the PHP environment is going to panic + // over trying to see if the file can be read in the first place, + // that is not helpful to us here. + + // See random_bytes_dev_urandom.php + require_once $RandomCompatDIR.'/random_bytes_dev_urandom.php'; + } + if ( + !function_exists('random_bytes') && + PHP_VERSION_ID >= 50307 && + extension_loaded('mcrypt') + ) { + // See random_bytes_mcrypt.php + require_once $RandomCompatDIR.'/random_bytes_mcrypt.php'; + } + if ( + !function_exists('random_bytes') && + extension_loaded('com_dotnet') && + class_exists('COM') + ) { + try { + $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); + if (method_exists($RandomCompatCOMtest, 'GetRandom')) { + // See random_bytes_com_dotnet.php + require_once $RandomCompatDIR.'/random_bytes_com_dotnet.php'; + } + } catch (com_exception $e) { + // Don't try to use it. + } + $RandomCompatCOMtest = null; + } + if ( + !function_exists('random_bytes') && + extension_loaded('openssl') && + ( + // Unix-like with PHP >= 5.3.0 or + ( + DIRECTORY_SEPARATOR === '/' && + PHP_VERSION_ID >= 50300 + ) || + // Windows with PHP >= 5.3.4 + PHP_VERSION_ID >= 50304 + ) + ) { + // See random_bytes_openssl.php + require_once $RandomCompatDIR.'/random_bytes_openssl.php'; + } + if (!function_exists('random_bytes')) { + /** + * We don't have any more options, so let's throw an exception right now + * and hope the developer won't let it fail silently. + */ + function random_bytes() + { + throw new Exception( + 'There is no suitable CSPRNG installed on your system' + ); + } + } + } + if (!function_exists('random_int')) { + require_once $RandomCompatDIR.'/random_int.php'; + } + $RandomCompatDIR = null; +} diff --git a/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php b/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php new file mode 100644 index 0000000..c0ae639 --- /dev/null +++ b/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php @@ -0,0 +1,77 @@ +GetRandom($bytes, 0)); + if (RandomCompat_strlen($buf) >= $bytes) { + /** + * Return our random entropy buffer here: + */ + return RandomCompat_substr($buf, 0, $bytes); + } + ++$execCount; + } while ($execCount < $bytes); + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'PHP failed to generate random data.' + ); +} diff --git a/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php b/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php new file mode 100644 index 0000000..5606dbb --- /dev/null +++ b/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php @@ -0,0 +1,137 @@ + 0); + + /** + * Is our result valid? + */ + if ($buf !== false) { + if (RandomCompat_strlen($buf) === $bytes) { + /** + * Return our random entropy buffer here: + */ + return $buf; + } + } + } + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'PHP failed to generate random data.' + ); +} diff --git a/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php b/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php new file mode 100644 index 0000000..796ba6a --- /dev/null +++ b/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php @@ -0,0 +1,84 @@ + 2147483647) { + $buf = ''; + for ($i = 0; $i < $bytes; $i += 1073741824) { + $n = ($bytes - $i) > 1073741824 + ? 1073741824 + : $bytes - $i; + $buf .= \Sodium\randombytes_buf($n); + } + } else { + $buf = \Sodium\randombytes_buf($bytes); + } + + if ($buf !== false) { + if (RandomCompat_strlen($buf) === $bytes) { + return $buf; + } + } + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'PHP failed to generate random data.' + ); +} diff --git a/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php b/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php new file mode 100644 index 0000000..8524c52 --- /dev/null +++ b/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php @@ -0,0 +1,72 @@ + operators might accidentally let a float + * through. + */ + + try { + $min = RandomCompat_intval($min); + } catch (TypeError $ex) { + throw new TypeError( + 'random_int(): $min must be an integer' + ); + } + try { + $max = RandomCompat_intval($max); + } catch (TypeError $ex) { + throw new TypeError( + 'random_int(): $max must be an integer' + ); + } + + /** + * Now that we've verified our weak typing system has given us an integer, + * let's validate the logic then we can move forward with generating random + * integers along a given range. + */ + if ($min > $max) { + throw new Error( + 'Minimum value must be less than or equal to the maximum value' + ); + } + if ($max === $min) { + return $min; + } + + /** + * Initialize variables to 0 + * + * We want to store: + * $bytes => the number of random bytes we need + * $mask => an integer bitmask (for use with the &) operator + * so we can minimize the number of discards + */ + $attempts = $bits = $bytes = $mask = $valueShift = 0; + + /** + * At this point, $range is a positive number greater than 0. It might + * overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to + * a float and we will lose some precision. + */ + $range = $max - $min; + + /** + * Test for integer overflow: + */ + if (!is_int($range)) { + /** + * Still safely calculate wider ranges. + * Provided by @CodesInChaos, @oittaa + * + * @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435 + * + * We use ~0 as a mask in this case because it generates all 1s + * + * @ref https://eval.in/400356 (32-bit) + * @ref http://3v4l.org/XX9r5 (64-bit) + */ + $bytes = PHP_INT_SIZE; + $mask = ~0; + } else { + /** + * $bits is effectively ceil(log($range, 2)) without dealing with + * type juggling + */ + while ($range > 0) { + if ($bits % 8 === 0) { + ++$bytes; + } + ++$bits; + $range >>= 1; + $mask = $mask << 1 | 1; + } + $valueShift = $min; + } + + /** + * Now that we have our parameters set up, let's begin generating + * random integers until one falls between $min and $max + */ + do { + /** + * The rejection probability is at most 0.5, so this corresponds + * to a failure probability of 2^-128 for a working RNG + */ + if ($attempts > 128) { + throw new Exception( + 'random_int: RNG is broken - too many rejections' + ); + } + + /** + * Let's grab the necessary number of random bytes + */ + $randomByteString = random_bytes($bytes); + if ($randomByteString === false) { + throw new Exception( + 'Random number generator failure' + ); + } + + /** + * Let's turn $randomByteString into an integer + * + * This uses bitwise operators (<< and |) to build an integer + * out of the values extracted from ord() + * + * Example: [9F] | [6D] | [32] | [0C] => + * 159 + 27904 + 3276800 + 201326592 => + * 204631455 + */ + $val = 0; + for ($i = 0; $i < $bytes; ++$i) { + $val |= ord($randomByteString[$i]) << ($i * 8); + } + + /** + * Apply mask + */ + $val &= $mask; + $val += $valueShift; + + ++$attempts; + /** + * If $val overflows to a floating point number, + * ... or is larger than $max, + * ... or smaller than $min, + * then try again. + */ + } while (!is_int($val) || $val > $max || $val < $min); + return (int) $val; +} diff --git a/vendor/paragonie/random_compat/tests/full/DieHardTest.php b/vendor/paragonie/random_compat/tests/full/DieHardTest.php new file mode 100644 index 0000000..2e6dc70 --- /dev/null +++ b/vendor/paragonie/random_compat/tests/full/DieHardTest.php @@ -0,0 +1,61 @@ + $i, + 'value' => $buckets[$i], + 'min' => $min, + 'nums' => $nums_to_generate, + 'reason' => 'below min' + ]); + } + if ($buckets[$i] >= $max ) { + var_dump([ + 'bucket' => $i, + 'value' => $buckets[$i], + 'maax' => $max, + 'nums' => $nums_to_generate, + 'reason' => 'above max' + ]); + } + + $this->assertTrue($buckets[$i] < $max && $buckets[$i] > $min); + } + } + } +} \ No newline at end of file diff --git a/vendor/paragonie/random_compat/tests/full/StatTest.php b/vendor/paragonie/random_compat/tests/full/StatTest.php new file mode 100644 index 0000000..e78eb14 --- /dev/null +++ b/vendor/paragonie/random_compat/tests/full/StatTest.php @@ -0,0 +1,52 @@ + 30% but less than 170% + * + * This also catches 0 and 1000 + */ + public function testDistribution() + { + $integers = array_fill(0, 100, 0); + for ($i = 0; $i < 10000; ++$i) { + ++$integers[random_int(0,99)]; + } + for ($i = 0; $i < 100; ++$i) { + $this->assertFalse($integers[$i] < 30); + $this->assertFalse($integers[$i] > 170); + } + } + + /** + * This should be between 55% and 75%, always + */ + public function testCoverage() + { + $integers = array_fill(0, 2000, 0); + for ($i = 0; $i < 2000; ++$i) { + ++$integers[random_int(0,1999)]; + } + $coverage = 0; + for ($i = 0; $i < 2000; ++$i) { + if ($integers[$i] > 0) { + ++$coverage; + } + } + $this->assertTrue($coverage >= 1150); + $this->assertTrue($coverage <= 1350); + } + + public function testCompressionRatios() + { + $some_bytes = random_bytes(65536); + $compressed = gzcompress($some_bytes, 9); + if (function_exists('mb_strlen')) { + $length = mb_strlen($compressed, '8bit'); + } else { + $length = strlen($compressed); + } + $this->assertTrue($length >= 65000 && $length <= 67000); + } +} \ No newline at end of file diff --git a/vendor/paragonie/random_compat/tests/phpunit.sh b/vendor/paragonie/random_compat/tests/phpunit.sh new file mode 100755 index 0000000..93c9970 --- /dev/null +++ b/vendor/paragonie/random_compat/tests/phpunit.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +if [ "$1" == 'full' ]; then + fulltest=1 +elif [ "$1" == 'each' ]; then + testeach=1 +else + fulltest=0 +fi +origdir=`pwd` +cdir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +cd $origdir +parentdir="$(dirname $cdir)" + +clean=0 # Clean up? + +gpg --fingerprint D8406D0D82947747293778314AA394086372C20A +if [ $? -ne 0 ]; then + echo -e "\033[33mDownloading PGP Public Key...\033[0m" + gpg --recv-keys D8406D0D82947747293778314AA394086372C20A + # Sebastian Bergmann + gpg --fingerprint D8406D0D82947747293778314AA394086372C20A + if [ $? -ne 0 ]; then + echo -e "\033[31mCould not download PGP public key for verification\033[0m" + exit + fi +fi + +if [ "$clean" -eq 1 ]; then + # Let's clean them up, if they exist + if [ -f phpunit.phar ]; then + rm -f phpunit.phar + fi + if [ -f phpunit.phar.asc ]; then + rm -f phpunit.phar.asc + fi +fi + +PHP_VERSION=$(php -r "echo PHP_VERSION_ID;") + +# Let's grab the latest release and its signature +if [ ! -f phpunit.phar ]; then + if [[ $PHP_VERSION -ge 50600 ]]; then + wget https://phar.phpunit.de/phpunit.phar + else + wget -O phpunit.phar https://phar.phpunit.de/phpunit-old.phar + fi +fi +if [ ! -f phpunit.phar.asc ]; then + if [[ $PHP_VERSION -ge 50600 ]]; then + wget https://phar.phpunit.de/phpunit.phar.asc + else + wget -O phpunit.phar.asc https://phar.phpunit.de/phpunit-old.phar.asc + fi +fi + +# Verify before running +gpg --verify phpunit.phar.asc phpunit.phar +if [ $? -eq 0 ]; then + echo + echo -e "\033[33mBegin Unit Testing\033[0m" + # Run the testing suite + echo "Basic test suite:" + php phpunit.phar --bootstrap "$parentdir/lib/random.php" "$parentdir/tests/unit" + if [ $? -ne 0 ]; then + # Test failure + exit 1 + fi + echo "With open_basedir enabled:" + php -d open_basedir=$parentdir phpunit.phar --bootstrap "$parentdir/vendor/autoload.php" "$parentdir/tests/unit" + if [ $? -ne 0 ]; then + # Test failure + exit 1 + fi + echo "With open_basedir enabled, allowing /dev:" + php -d open_basedir=$parentdir:/dev phpunit.phar --bootstrap "$parentdir/vendor/autoload.php" "$parentdir/tests/unit" + if [ $? -ne 0 ]; then + # Test failure + exit 1 + fi + echo "With mbstring.func_overload enabled:" + php -d mbstring.func_overload=7 phpunit.phar --bootstrap "$parentdir/vendor/autoload.php" "$parentdir/tests/unit" + if [ $? -ne 0 ]; then + # Test failure + exit 1 + fi + + if [[ "$testeach" == "1" ]]; then + echo " CAPICOM:" + php phpunit.phar --bootstrap "$parentdir/tests/specific/capicom.php" "$parentdir/tests/unit" + echo " /dev/urandom:" + php phpunit.phar --bootstrap "$parentdir/tests/specific/dev_urandom.php" "$parentdir/tests/unit" + echo " libsodium:" + php phpunit.phar --bootstrap "$parentdir/tests/specific/libsodium.php" "$parentdir/tests/unit" + echo " mcrypt:" + php phpunit.phar --bootstrap "$parentdir/tests/specific/mcrypt.php" "$parentdir/tests/unit" + echo " openssl:" + php phpunit.phar --bootstrap "$parentdir/tests/specific/openssl.php" "$parentdir/tests/unit" + fi + + # Should we perform full statistical analyses? + if [[ "$fulltest" == "1" ]]; then + php phpunit.phar --bootstrap "$parentdir/vendor/autoload.php" "$parentdir/tests/full" + if [ $? -ne 0 ]; then + # Test failure + exit 1 + fi + fi + # Cleanup + if [[ "$clean" == "1" ]]; then + echo -e "\033[32mCleaning Up!\033[0m" + rm -f phpunit.phar + rm -f phpunit.phar.asc + fi +else + echo + chmod -x phpunit.phar + mv phpunit.phar /tmp/bad-phpunit.phar + mv phpunit.phar.asc /tmp/bad-phpunit.phar.asc + echo -e "\033[31mSignature did not match! Check /tmp/bad-phpunit.phar for trojans\033[0m" + exit 1 +fi diff --git a/vendor/paragonie/random_compat/tests/specific/capicom.php b/vendor/paragonie/random_compat/tests/specific/capicom.php new file mode 100644 index 0000000..640be1b --- /dev/null +++ b/vendor/paragonie/random_compat/tests/specific/capicom.php @@ -0,0 +1,7 @@ +assertTrue(function_exists('random_bytes')); + } + + public function testOutput() + { + $bytes = array( + random_bytes(12), + random_bytes(64), + random_bytes(64), + random_bytes(1.5) + ); + + $this->assertTrue( + strlen(bin2hex($bytes[0])) === 24 + ); + $this->assertTrue( + strlen(bin2hex($bytes[3])) === 2 + ); + + // This should never generate identical byte strings + $this->assertFalse( + $bytes[1] === $bytes[2] + ); + + try { + $x = random_bytes(~PHP_INT_MAX - 1000000000); + $this->assertTrue(false); + } catch (TypeError $ex) { + $this->assertTrue(true); + } catch (Error $ex) { + $this->assertTrue(true); + } catch (Exception $ex) { + $this->assertTrue(true); + } + + try { + $x = random_bytes(PHP_INT_MAX + 1000000000); + $this->assertTrue(false); + } catch (TypeError $ex) { + $this->assertTrue(true); + } catch (Error $ex) { + $this->assertTrue(true); + } catch (Exception $ex) { + $this->assertTrue(true); + } + } +} diff --git a/vendor/paragonie/random_compat/tests/unit/RandomIntTest.php b/vendor/paragonie/random_compat/tests/unit/RandomIntTest.php new file mode 100644 index 0000000..f9fc3c3 --- /dev/null +++ b/vendor/paragonie/random_compat/tests/unit/RandomIntTest.php @@ -0,0 +1,52 @@ +assertTrue(function_exists('random_int')); + } + + public function testOutput() + { + $half_neg_max = (~PHP_INT_MAX / 2); + $integers = array( + random_int(0, 1000), + random_int(1001,2000), + random_int(-100, -10), + random_int(-1000, 1000), + random_int(~PHP_INT_MAX, PHP_INT_MAX), + random_int("0", "1"), + random_int(0.11111, 0.99999), + random_int($half_neg_max, PHP_INT_MAX), + random_int(0.0, 255.0), + random_int(-4.5, -4.5), + random_int("1337e3","1337e3") + ); + + $this->assertFalse($integers[0] === $integers[1]); + $this->assertTrue($integers[0] >= 0 && $integers[0] <= 1000); + $this->assertTrue($integers[1] >= 1001 && $integers[1] <= 2000); + $this->assertTrue($integers[2] >= -100 && $integers[2] <= -10); + $this->assertTrue($integers[3] >= -1000 && $integers[3] <= 1000); + $this->assertTrue($integers[4] >= ~PHP_INT_MAX && $integers[4] <= PHP_INT_MAX); + $this->assertTrue($integers[5] >= 0 && $integers[5] <= 1); + $this->assertTrue($integers[6] === 0); + $this->assertTrue($integers[7] >= $half_neg_max && $integers[7] <= PHP_INT_MAX); + $this->assertTrue($integers[8] >= 0 && $integers[8] <= 255); + $this->assertTrue($integers[9] === -4); + $this->assertTrue($integers[10] === 1337000); + + try { + $h = random_int("2147483648", "2147483647"); + $i = random_int("9223372036854775808", "9223372036854775807"); + $this->assertFalse(is_int($i)); + $h = random_int("-2147483648", "2147483647"); + $i = random_int("-9223372036854775808", "9223372036854775807"); + $this->assertFalse(true); + } catch (Error $ex) { + $this->assertTrue($ex instanceof Error); + } catch (Exception $ex) { + $this->assertTrue($ex instanceof Exception); + } + } +} diff --git a/vendor/paragonie/random_compat/tests/unit/UtilityTest.php b/vendor/paragonie/random_compat/tests/unit/UtilityTest.php new file mode 100644 index 0000000..294a801 --- /dev/null +++ b/vendor/paragonie/random_compat/tests/unit/UtilityTest.php @@ -0,0 +1,95 @@ +markTestSkipped( + 'We don\' need to test this in PHP 7.' + ); + } + $this->assertEquals(RandomCompat_strlen("\xF0\x9D\x92\xB3"), 4); + } + + public function testIntval() + { + if (!function_exists('RandomCompat_intval')) { + return $this->markTestSkipped( + 'We don\' need to test this in PHP 7.' + ); + } + // Equals + $this->assertEquals( + abs(RandomCompat_intval(-4.5)), + abs(RandomCompat_intval(4.5)) + ); + + // True + $this->assertTrue( + is_int(RandomCompat_intval(PHP_INT_MAX, true)) + ); + $this->assertTrue( + is_int(RandomCompat_intval(~PHP_INT_MAX, true)) + ); + $this->assertTrue( + is_int(RandomCompat_intval(~PHP_INT_MAX + 1, true)) + ); + $this->assertTrue( + is_int(RandomCompat_intval("1337e3", true)) + ); + $this->assertTrue( + is_int(RandomCompat_intval("1.", true)) + ); + + // False + $this->assertFalse( + is_int(RandomCompat_intval((float) PHP_INT_MAX, true)) + ); + $this->assertFalse( + is_int(RandomCompat_intval((float) ~PHP_INT_MAX, true)) + ); + $this->assertFalse( + is_int(RandomCompat_intval(PHP_INT_MAX + 1, true)) + ); + $this->assertFalse( + is_int(RandomCompat_intval(~PHP_INT_MAX - 1, true)) + ); + $this->assertFalse( + is_int(RandomCompat_intval(~PHP_INT_MAX - 0.1, true)) + ); + $this->assertFalse( + is_int(RandomCompat_intval(PHP_INT_MAX + 0.1, true)) + ); + $this->assertFalse( + is_int(RandomCompat_intval("hello", true)) + ); + + if (PHP_INT_SIZE === 8) { + $this->assertFalse( + is_int(RandomCompat_intval("-9223372036854775809", true)) + ); + $this->assertTrue( + is_int(RandomCompat_intval("-9223372036854775808", true)) + ); + $this->assertFalse( + is_int(RandomCompat_intval("9223372036854775808", true)) + ); + $this->assertTrue( + is_int(RandomCompat_intval("9223372036854775807", true)) + ); + } else { + $this->assertFalse( + is_int(RandomCompat_intval("2147483648", true)) + ); + $this->assertTrue( + is_int(RandomCompat_intval("2147483647", true)) + ); + $this->assertFalse( + is_int(RandomCompat_intval("-2147483649", true)) + ); + $this->assertTrue( + is_int(RandomCompat_intval("-2147483648", true)) + ); + } + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/.gitignore b/vendor/phpdocumentor/reflection-docblock/.gitignore new file mode 100644 index 0000000..3ce5adb --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/.gitignore @@ -0,0 +1,2 @@ +.idea +vendor diff --git a/vendor/phpdocumentor/reflection-docblock/.travis.yml b/vendor/phpdocumentor/reflection-docblock/.travis.yml new file mode 100644 index 0000000..eef782c --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/.travis.yml @@ -0,0 +1,32 @@ +language: php +php: + - 5.3.3 + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + - hhvm-nightly + +matrix: + allow_failures: + - php: hhvm + - php: hhvm-nightly + +script: + - vendor/bin/phpunit + +before_script: + - sudo apt-get -qq update > /dev/null + - phpenv rehash > /dev/null + - composer selfupdate --quiet + - composer install --no-interaction --prefer-source --dev + - vendor/bin/phpunit + - composer update --no-interaction --prefer-source --dev + +notifications: + irc: "irc.freenode.org#phpdocumentor" + email: + - mike.vanriel@naenius.com + - ashnazg@php.net + - boen.robot@gmail.com diff --git a/vendor/phpdocumentor/reflection-docblock/LICENSE b/vendor/phpdocumentor/reflection-docblock/LICENSE new file mode 100644 index 0000000..792e404 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2010 Mike van Riel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/phpdocumentor/reflection-docblock/README.md b/vendor/phpdocumentor/reflection-docblock/README.md new file mode 100644 index 0000000..6405d1a --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/README.md @@ -0,0 +1,57 @@ +The ReflectionDocBlock Component [![Build Status](https://secure.travis-ci.org/phpDocumentor/ReflectionDocBlock.png)](https://travis-ci.org/phpDocumentor/ReflectionDocBlock) +================================ + +Introduction +------------ + +The ReflectionDocBlock component of phpDocumentor provides a DocBlock parser +that is 100% compatible with the [PHPDoc standard](http://phpdoc.org/docs/latest). + +With this component, a library can provide support for annotations via DocBlocks +or otherwise retrieve information that is embedded in a DocBlock. + +> **Note**: *this is a core component of phpDocumentor and is constantly being +> optimized for performance.* + +Installation +------------ + +You can install the component in the following ways: + +* Use the official Github repository (https://github.com/phpDocumentor/ReflectionDocBlock) +* Via Composer (http://packagist.org/packages/phpdocumentor/reflection-docblock) + +Usage +----- + +The ReflectionDocBlock component is designed to work in an identical fashion to +PHP's own Reflection extension (http://php.net/manual/en/book.reflection.php). + +Parsing can be initiated by instantiating the +`\phpDocumentor\Reflection\DocBlock()` class and passing it a string containing +a DocBlock (including asterisks) or by passing an object supporting the +`getDocComment()` method. + +> *Examples of objects having the `getDocComment()` method are the +> `ReflectionClass` and the `ReflectionMethod` classes of the PHP +> Reflection extension* + +Example: + + $class = new ReflectionClass('MyClass'); + $phpdoc = new \phpDocumentor\Reflection\DocBlock($class); + +or + + $docblock = <<=5.3.3" + }, + "autoload": { + "psr-0": {"phpDocumentor": ["src/"]} + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/composer.lock b/vendor/phpdocumentor/reflection-docblock/composer.lock new file mode 100644 index 0000000..4c6a8bb --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/composer.lock @@ -0,0 +1,827 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "ea1734d11b8c878445c2c6e58de8b85f", + "packages": [], + "packages-dev": [ + { + "name": "ocramius/instantiator", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/Instantiator.git", + "reference": "a7abbb5fc9df6e7126af741dd6c140d1a7369435" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/Instantiator/zipball/a7abbb5fc9df6e7126af741dd6c140d1a7369435", + "reference": "a7abbb5fc9df6e7126af741dd6c140d1a7369435", + "shasum": "" + }, + "require": { + "ocramius/lazy-map": "1.0.*", + "php": "~5.3" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.*@ALPHA" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Instantiator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/Ocramius/Instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2014-08-14 15:10:55" + }, + { + "name": "ocramius/lazy-map", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/LazyMap.git", + "reference": "7fe3d347f5e618bcea7d39345ff83f3651d8b752" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/LazyMap/zipball/7fe3d347f5e618bcea7d39345ff83f3651d8b752", + "reference": "7fe3d347f5e618bcea7d39345ff83f3651d8b752", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "athletic/athletic": "~0.1.6", + "phpmd/phpmd": "1.5.*", + "phpunit/phpunit": ">=3.7", + "satooshi/php-coveralls": "~0.6", + "squizlabs/php_codesniffer": "1.4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "LazyMap\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/", + "role": "Developer" + } + ], + "description": "A library that provides lazy instantiation logic for a map of objects", + "homepage": "https://github.com/Ocramius/LazyMap", + "keywords": [ + "lazy", + "lazy instantiation", + "lazy loading", + "map", + "service location" + ], + "time": "2013-11-09 22:30:54" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6d196af48e8c100a3ae881940123e693da5a9217" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6d196af48e8c100a3ae881940123e693da5a9217", + "reference": "6d196af48e8c100a3ae881940123e693da5a9217", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3.1", + "phpunit/php-text-template": "~1.2.0", + "phpunit/php-token-stream": "~1.2.2", + "sebastian/environment": "~1.0.0", + "sebastian/version": "~1.0.3" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4.0.14" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2014-08-06 06:39:42" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2013-10-10 15:34:57" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30 17:20:04" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2013-08-02 07:42:54" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", + "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2014-03-03 05:10:30" + }, + { + "name": "phpunit/phpunit", + "version": "4.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "a33fa68ece9f8c68589bfc2da8d2794e27b820bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a33fa68ece9f8c68589bfc2da8d2794e27b820bc", + "reference": "a33fa68ece9f8c68589bfc2da8d2794e27b820bc", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": "~2.0", + "phpunit/php-file-iterator": "~1.3.1", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.2", + "sebastian/comparator": "~1.0", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.0", + "sebastian/exporter": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2014-08-18 05:12:30" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "42e589e08bc86e3e9bdf20d385e948347788505b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/42e589e08bc86e3e9bdf20d385e948347788505b", + "reference": "42e589e08bc86e3e9bdf20d385e948347788505b", + "shasum": "" + }, + "require": { + "ocramius/instantiator": "~1.0", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "4.2.*@dev" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2014-08-02 13:50:58" + }, + { + "name": "sebastian/comparator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.1", + "sebastian/exporter": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2014-05-02 07:05:58" + }, + { + "name": "sebastian/diff", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2013-08-03 16:46:33" + }, + { + "name": "sebastian/environment", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "4.0.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2014-02-18 16:17:19" + }, + { + "name": "sebastian/exporter", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "4.0.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net", + "role": "Lead" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2014-02-16 08:26:31" + }, + { + "name": "sebastian/version", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2014-03-07 15:35:33" + }, + { + "name": "symfony/yaml", + "version": "v2.5.3", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f", + "reference": "5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2014-08-05 09:00:40" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "platform": { + "php": ">=5.3.3" + }, + "platform-dev": [] +} diff --git a/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist b/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist new file mode 100644 index 0000000..f67ad2a --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist @@ -0,0 +1,14 @@ + + + + + + ./tests/ + + + + + ./src/ + + + diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock.php new file mode 100644 index 0000000..02968b1 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock.php @@ -0,0 +1,468 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\Context; +use phpDocumentor\Reflection\DocBlock\Location; + +/** + * Parses the DocBlock for any structure. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class DocBlock implements \Reflector +{ + /** @var string The opening line for this docblock. */ + protected $short_description = ''; + + /** + * @var DocBlock\Description The actual + * description for this docblock. + */ + protected $long_description = null; + + /** + * @var Tag[] An array containing all + * the tags in this docblock; except inline. + */ + protected $tags = array(); + + /** @var Context Information about the context of this DocBlock. */ + protected $context = null; + + /** @var Location Information about the location of this DocBlock. */ + protected $location = null; + + /** @var bool Is this DocBlock (the start of) a template? */ + protected $isTemplateStart = false; + + /** @var bool Does this DocBlock signify the end of a DocBlock template? */ + protected $isTemplateEnd = false; + + /** + * Parses the given docblock and populates the member fields. + * + * The constructor may also receive namespace information such as the + * current namespace and aliases. This information is used by some tags + * (e.g. @return, @param, etc.) to turn a relative Type into a FQCN. + * + * @param \Reflector|string $docblock A docblock comment (including + * asterisks) or reflector supporting the getDocComment method. + * @param Context $context The context in which the DocBlock + * occurs. + * @param Location $location The location within the file that this + * DocBlock occurs in. + * + * @throws \InvalidArgumentException if the given argument does not have the + * getDocComment method. + */ + public function __construct( + $docblock, + Context $context = null, + Location $location = null + ) { + if (is_object($docblock)) { + if (!method_exists($docblock, 'getDocComment')) { + throw new \InvalidArgumentException( + 'Invalid object passed; the given reflector must support ' + . 'the getDocComment method' + ); + } + + $docblock = $docblock->getDocComment(); + } + + $docblock = $this->cleanInput($docblock); + + list($templateMarker, $short, $long, $tags) = $this->splitDocBlock($docblock); + $this->isTemplateStart = $templateMarker === '#@+'; + $this->isTemplateEnd = $templateMarker === '#@-'; + $this->short_description = $short; + $this->long_description = new DocBlock\Description($long, $this); + $this->parseTags($tags); + + $this->context = $context; + $this->location = $location; + } + + /** + * Strips the asterisks from the DocBlock comment. + * + * @param string $comment String containing the comment text. + * + * @return string + */ + protected function cleanInput($comment) + { + $comment = trim( + preg_replace( + '#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]{0,1}(.*)?#u', + '$1', + $comment + ) + ); + + // reg ex above is not able to remove */ from a single line docblock + if (substr($comment, -2) == '*/') { + $comment = trim(substr($comment, 0, -2)); + } + + // normalize strings + $comment = str_replace(array("\r\n", "\r"), "\n", $comment); + + return $comment; + } + + /** + * Splits the DocBlock into a template marker, summary, description and block of tags. + * + * @param string $comment Comment to split into the sub-parts. + * + * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split. + * @author Mike van Riel for extending the regex with template marker support. + * + * @return string[] containing the template marker (if any), summary, description and a string containing the tags. + */ + protected function splitDocBlock($comment) + { + // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This + // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the + // performance impact of running a regular expression + if (strpos($comment, '@') === 0) { + return array('', '', '', $comment); + } + + // clears all extra horizontal whitespace from the line endings to prevent parsing issues + $comment = preg_replace('/\h*$/Sum', '', $comment); + + /* + * Splits the docblock into a template marker, short description, long description and tags section + * + * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may + * occur after it and will be stripped). + * - The short description is started from the first character until a dot is encountered followed by a + * newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing + * errors). This is optional. + * - The long description, any character until a new line is encountered followed by an @ and word + * characters (a tag). This is optional. + * - Tags; the remaining characters + * + * Big thanks to RichardJ for contributing this Regular Expression + */ + preg_match( + '/ + \A + # 1. Extract the template marker + (?:(\#\@\+|\#\@\-)\n?)? + + # 2. Extract the summary + (?: + (?! @\pL ) # The summary may not start with an @ + ( + [^\n.]+ + (?: + (?! \. \n | \n{2} ) # End summary upon a dot followed by newline or two newlines + [\n.] (?! [ \t]* @\pL ) # End summary when an @ is found as first character on a new line + [^\n.]+ # Include anything else + )* + \.? + )? + ) + + # 3. Extract the description + (?: + \s* # Some form of whitespace _must_ precede a description because a summary must be there + (?! @\pL ) # The description may not start with an @ + ( + [^\n]+ + (?: \n+ + (?! [ \t]* @\pL ) # End description when an @ is found as first character on a new line + [^\n]+ # Include anything else + )* + ) + )? + + # 4. Extract the tags (anything that follows) + (\s+ [\s\S]*)? # everything that follows + /ux', + $comment, + $matches + ); + array_shift($matches); + + while (count($matches) < 4) { + $matches[] = ''; + } + + return $matches; + } + + /** + * Creates the tag objects. + * + * @param string $tags Tag block to parse. + * + * @return void + */ + protected function parseTags($tags) + { + $result = array(); + $tags = trim($tags); + if ('' !== $tags) { + if ('@' !== $tags[0]) { + throw new \LogicException( + 'A tag block started with text instead of an actual tag,' + . ' this makes the tag block invalid: ' . $tags + ); + } + foreach (explode("\n", $tags) as $tag_line) { + if (isset($tag_line[0]) && ($tag_line[0] === '@')) { + $result[] = $tag_line; + } else { + $result[count($result) - 1] .= "\n" . $tag_line; + } + } + + // create proper Tag objects + foreach ($result as $key => $tag_line) { + $result[$key] = Tag::createInstance(trim($tag_line), $this); + } + } + + $this->tags = $result; + } + + /** + * Gets the text portion of the doc block. + * + * Gets the text portion (short and long description combined) of the doc + * block. + * + * @return string The text portion of the doc block. + */ + public function getText() + { + $short = $this->getShortDescription(); + $long = $this->getLongDescription()->getContents(); + + if ($long) { + return "{$short}\n\n{$long}"; + } else { + return $short; + } + } + + /** + * Set the text portion of the doc block. + * + * Sets the text portion (short and long description combined) of the doc + * block. + * + * @param string $docblock The new text portion of the doc block. + * + * @return $this This doc block. + */ + public function setText($comment) + { + list(,$short, $long) = $this->splitDocBlock($comment); + $this->short_description = $short; + $this->long_description = new DocBlock\Description($long, $this); + return $this; + } + /** + * Returns the opening line or also known as short description. + * + * @return string + */ + public function getShortDescription() + { + return $this->short_description; + } + + /** + * Returns the full description or also known as long description. + * + * @return DocBlock\Description + */ + public function getLongDescription() + { + return $this->long_description; + } + + /** + * Returns whether this DocBlock is the start of a Template section. + * + * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker + * (`#@+`) that is appended directly after the opening `/**` of a DocBlock. + * + * An example of such an opening is: + * + * ``` + * /**#@+ + * * My DocBlock + * * / + * ``` + * + * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all + * elements that follow until another DocBlock is found that contains the closing marker (`#@-`). + * + * @see self::isTemplateEnd() for the check whether a closing marker was provided. + * + * @return boolean + */ + public function isTemplateStart() + { + return $this->isTemplateStart; + } + + /** + * Returns whether this DocBlock is the end of a Template section. + * + * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality. + * + * @return boolean + */ + public function isTemplateEnd() + { + return $this->isTemplateEnd; + } + + /** + * Returns the current context. + * + * @return Context + */ + public function getContext() + { + return $this->context; + } + + /** + * Returns the current location. + * + * @return Location + */ + public function getLocation() + { + return $this->location; + } + + /** + * Returns the tags for this DocBlock. + * + * @return Tag[] + */ + public function getTags() + { + return $this->tags; + } + + /** + * Returns an array of tags matching the given name. If no tags are found + * an empty array is returned. + * + * @param string $name String to search by. + * + * @return Tag[] + */ + public function getTagsByName($name) + { + $result = array(); + + /** @var Tag $tag */ + foreach ($this->getTags() as $tag) { + if ($tag->getName() != $name) { + continue; + } + + $result[] = $tag; + } + + return $result; + } + + /** + * Checks if a tag of a certain type is present in this DocBlock. + * + * @param string $name Tag name to check for. + * + * @return bool + */ + public function hasTag($name) + { + /** @var Tag $tag */ + foreach ($this->getTags() as $tag) { + if ($tag->getName() == $name) { + return true; + } + } + + return false; + } + + /** + * Appends a tag at the end of the list of tags. + * + * @param Tag $tag The tag to add. + * + * @return Tag The newly added tag. + * + * @throws \LogicException When the tag belongs to a different DocBlock. + */ + public function appendTag(Tag $tag) + { + if (null === $tag->getDocBlock()) { + $tag->setDocBlock($this); + } + + if ($tag->getDocBlock() === $this) { + $this->tags[] = $tag; + } else { + throw new \LogicException( + 'This tag belongs to a different DocBlock object.' + ); + } + + return $tag; + } + + + /** + * Builds a string representation of this object. + * + * @todo determine the exact format as used by PHP Reflection and + * implement it. + * + * @return string + * @codeCoverageIgnore Not yet implemented + */ + public static function export() + { + throw new \Exception('Not yet implemented'); + } + + /** + * Returns the exported information (we should use the export static method + * BUT this throws an exception at this point). + * + * @return string + * @codeCoverageIgnore Not yet implemented + */ + public function __toString() + { + return 'Not yet implemented'; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Context.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Context.php new file mode 100644 index 0000000..81aa83c --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Context.php @@ -0,0 +1,154 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +/** + * The context in which a DocBlock occurs. + * + * @author Vasil Rangelov + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class Context +{ + /** @var string The current namespace. */ + protected $namespace = ''; + + /** @var array List of namespace aliases => Fully Qualified Namespace. */ + protected $namespace_aliases = array(); + + /** @var string Name of the structural element, within the namespace. */ + protected $lsen = ''; + + /** + * Cteates a new context. + * @param string $namespace The namespace where this DocBlock + * resides in. + * @param array $namespace_aliases List of namespace aliases => Fully + * Qualified Namespace. + * @param string $lsen Name of the structural element, within + * the namespace. + */ + public function __construct( + $namespace = '', + array $namespace_aliases = array(), + $lsen = '' + ) { + if (!empty($namespace)) { + $this->setNamespace($namespace); + } + $this->setNamespaceAliases($namespace_aliases); + $this->setLSEN($lsen); + } + + /** + * @return string The namespace where this DocBlock resides in. + */ + public function getNamespace() + { + return $this->namespace; + } + + /** + * @return array List of namespace aliases => Fully Qualified Namespace. + */ + public function getNamespaceAliases() + { + return $this->namespace_aliases; + } + + /** + * Returns the Local Structural Element Name. + * + * @return string Name of the structural element, within the namespace. + */ + public function getLSEN() + { + return $this->lsen; + } + + /** + * Sets a new namespace. + * + * Sets a new namespace for the context. Leading and trailing slashes are + * trimmed, and the keywords "global" and "default" are treated as aliases + * to no namespace. + * + * @param string $namespace The new namespace to set. + * + * @return $this + */ + public function setNamespace($namespace) + { + if ('global' !== $namespace + && 'default' !== $namespace + ) { + // Srip leading and trailing slash + $this->namespace = trim((string)$namespace, '\\'); + } else { + $this->namespace = ''; + } + return $this; + } + + /** + * Sets the namespace aliases, replacing all previous ones. + * + * @param array $namespace_aliases List of namespace aliases => Fully + * Qualified Namespace. + * + * @return $this + */ + public function setNamespaceAliases(array $namespace_aliases) + { + $this->namespace_aliases = array(); + foreach ($namespace_aliases as $alias => $fqnn) { + $this->setNamespaceAlias($alias, $fqnn); + } + return $this; + } + + /** + * Adds a namespace alias to the context. + * + * @param string $alias The alias name (the part after "as", or the last + * part of the Fully Qualified Namespace Name) to add. + * @param string $fqnn The Fully Qualified Namespace Name for this alias. + * Any form of leading/trailing slashes are accepted, but what will be + * stored is a name, prefixed with a slash, and no trailing slash. + * + * @return $this + */ + public function setNamespaceAlias($alias, $fqnn) + { + $this->namespace_aliases[$alias] = '\\' . trim((string)$fqnn, '\\'); + return $this; + } + + /** + * Sets a new Local Structural Element Name. + * + * Sets a new Local Structural Element Name. A local name also contains + * punctuation determining the kind of structural element (e.g. trailing "(" + * and ")" for functions and methods). + * + * @param string $lsen The new local name of a structural element. + * + * @return $this + */ + public function setLSEN($lsen) + { + $this->lsen = (string)$lsen; + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Description.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Description.php new file mode 100644 index 0000000..d41142e --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Description.php @@ -0,0 +1,223 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock; + +/** + * Parses a Description of a DocBlock or tag. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class Description implements \Reflector +{ + /** @var string */ + protected $contents = ''; + + /** @var array The contents, as an array of strings and Tag objects. */ + protected $parsedContents = null; + + /** @var DocBlock The DocBlock which this description belongs to. */ + protected $docblock = null; + + /** + * Populates the fields of a description. + * + * @param string $content The description's conetnts. + * @param DocBlock $docblock The DocBlock which this description belongs to. + */ + public function __construct($content, DocBlock $docblock = null) + { + $this->setContent($content)->setDocBlock($docblock); + } + + /** + * Gets the text of this description. + * + * @return string + */ + public function getContents() + { + return $this->contents; + } + + /** + * Sets the text of this description. + * + * @param string $content The new text of this description. + * + * @return $this + */ + public function setContent($content) + { + $this->contents = trim($content); + + $this->parsedContents = null; + return $this; + } + + /** + * Returns the parsed text of this description. + * + * @return array An array of strings and tag objects, in the order they + * occur within the description. + */ + public function getParsedContents() + { + if (null === $this->parsedContents) { + $this->parsedContents = preg_split( + '/\{ + # "{@}" is not a valid inline tag. This ensures that + # we do not treat it as one, but treat it literally. + (?!@\}) + # We want to capture the whole tag line, but without the + # inline tag delimiters. + (\@ + # Match everything up to the next delimiter. + [^{}]* + # Nested inline tag content should not be captured, or + # it will appear in the result separately. + (?: + # Match nested inline tags. + (?: + # Because we did not catch the tag delimiters + # earlier, we must be explicit with them here. + # Notice that this also matches "{}", as a way + # to later introduce it as an escape sequence. + \{(?1)?\} + | + # Make sure we match hanging "{". + \{ + ) + # Match content after the nested inline tag. + [^{}]* + )* # If there are more inline tags, match them as well. + # We use "*" since there may not be any nested inline + # tags. + ) + \}/Sux', + $this->contents, + null, + PREG_SPLIT_DELIM_CAPTURE + ); + + $count = count($this->parsedContents); + for ($i=1; $i<$count; $i += 2) { + $this->parsedContents[$i] = Tag::createInstance( + $this->parsedContents[$i], + $this->docblock + ); + } + + //In order to allow "literal" inline tags, the otherwise invalid + //sequence "{@}" is changed to "@", and "{}" is changed to "}". + //See unit tests for examples. + for ($i=0; $i<$count; $i += 2) { + $this->parsedContents[$i] = str_replace( + array('{@}', '{}'), + array('@', '}'), + $this->parsedContents[$i] + ); + } + } + return $this->parsedContents; + } + + /** + * Return a formatted variant of the Long Description using MarkDown. + * + * @todo this should become a more intelligent piece of code where the + * configuration contains a setting what format long descriptions are. + * + * @codeCoverageIgnore Will be removed soon, in favor of adapters at + * PhpDocumentor itself that will process text in various formats. + * + * @return string + */ + public function getFormattedContents() + { + $result = $this->contents; + + // if the long description contains a plain HTML element, surround + // it with a pre element. Please note that we explicitly used str_replace + // and not preg_replace to gain performance + if (strpos($result, '') !== false) { + $result = str_replace( + array('', "\r\n", "\n", "\r", ''), + array('
    ', '', '', '', '
    '), + $result + ); + } + + if (class_exists('Parsedown')) { + $markdown = \Parsedown::instance(); + $result = $markdown->parse($result); + } elseif (class_exists('dflydev\markdown\MarkdownExtraParser')) { + $markdown = new \dflydev\markdown\MarkdownExtraParser(); + $result = $markdown->transformMarkdown($result); + } + + return trim($result); + } + + /** + * Gets the docblock this tag belongs to. + * + * @return DocBlock The docblock this description belongs to. + */ + public function getDocBlock() + { + return $this->docblock; + } + + /** + * Sets the docblock this tag belongs to. + * + * @param DocBlock $docblock The new docblock this description belongs to. + * Setting NULL removes any association. + * + * @return $this + */ + public function setDocBlock(DocBlock $docblock = null) + { + $this->docblock = $docblock; + + return $this; + } + + /** + * Builds a string representation of this object. + * + * @todo determine the exact format as used by PHP Reflection + * and implement it. + * + * @return void + * @codeCoverageIgnore Not yet implemented + */ + public static function export() + { + throw new \Exception('Not yet implemented'); + } + + /** + * Returns the long description as a string. + * + * @return string + */ + public function __toString() + { + return $this->getContents(); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Location.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Location.php new file mode 100644 index 0000000..966ed44 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Location.php @@ -0,0 +1,76 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +/** + * The location a DocBlock occurs within a file. + * + * @author Vasil Rangelov + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class Location +{ + /** @var int Line where the DocBlock text starts. */ + protected $lineNumber = 0; + + /** @var int Column where the DocBlock text starts. */ + protected $columnNumber = 0; + + public function __construct( + $lineNumber = 0, + $columnNumber = 0 + ) { + $this->setLineNumber($lineNumber)->setColumnNumber($columnNumber); + } + + /** + * @return int Line where the DocBlock text starts. + */ + public function getLineNumber() + { + return $this->lineNumber; + } + + /** + * + * @param type $lineNumber + * @return $this + */ + public function setLineNumber($lineNumber) + { + $this->lineNumber = (int)$lineNumber; + + return $this; + } + + /** + * @return int Column where the DocBlock text starts. + */ + public function getColumnNumber() + { + return $this->columnNumber; + } + + /** + * + * @param int $columnNumber + * @return $this + */ + public function setColumnNumber($columnNumber) + { + $this->columnNumber = (int)$columnNumber; + + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Serializer.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Serializer.php new file mode 100644 index 0000000..c161785 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Serializer.php @@ -0,0 +1,198 @@ + + * @copyright 2013 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock; + +/** + * Serializes a DocBlock instance. + * + * @author Barry vd. Heuvel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class Serializer +{ + + /** @var string The string to indent the comment with. */ + protected $indentString = ' '; + + /** @var int The number of times the indent string is repeated. */ + protected $indent = 0; + + /** @var bool Whether to indent the first line. */ + protected $isFirstLineIndented = true; + + /** @var int|null The max length of a line. */ + protected $lineLength = null; + + /** + * Create a Serializer instance. + * + * @param int $indent The number of times the indent string is + * repeated. + * @param string $indentString The string to indent the comment with. + * @param bool $indentFirstLine Whether to indent the first line. + * @param int|null $lineLength The max length of a line or NULL to + * disable line wrapping. + */ + public function __construct( + $indent = 0, + $indentString = ' ', + $indentFirstLine = true, + $lineLength = null + ) { + $this->setIndentationString($indentString); + $this->setIndent($indent); + $this->setIsFirstLineIndented($indentFirstLine); + $this->setLineLength($lineLength); + } + + /** + * Sets the string to indent comments with. + * + * @param string $indentationString The string to indent comments with. + * + * @return $this This serializer object. + */ + public function setIndentationString($indentString) + { + $this->indentString = (string)$indentString; + return $this; + } + + /** + * Gets the string to indent comments with. + * + * @return string The indent string. + */ + public function getIndentationString() + { + return $this->indentString; + } + + /** + * Sets the number of indents. + * + * @param int $indent The number of times the indent string is repeated. + * + * @return $this This serializer object. + */ + public function setIndent($indent) + { + $this->indent = (int)$indent; + return $this; + } + + /** + * Gets the number of indents. + * + * @return int The number of times the indent string is repeated. + */ + public function getIndent() + { + return $this->indent; + } + + /** + * Sets whether or not the first line should be indented. + * + * Sets whether or not the first line (the one with the "/**") should be + * indented. + * + * @param bool $indentFirstLine The new value for this setting. + * + * @return $this This serializer object. + */ + public function setIsFirstLineIndented($indentFirstLine) + { + $this->isFirstLineIndented = (bool)$indentFirstLine; + return $this; + } + + /** + * Gets whether or not the first line should be indented. + * + * @return bool Whether or not the first line should be indented. + */ + public function isFirstLineIndented() + { + return $this->isFirstLineIndented; + } + + /** + * Sets the line length. + * + * Sets the length of each line in the serialization. Content will be + * wrapped within this limit. + * + * @param int|null $lineLength The length of each line. NULL to disable line + * wrapping altogether. + * + * @return $this This serializer object. + */ + public function setLineLength($lineLength) + { + $this->lineLength = null === $lineLength ? null : (int)$lineLength; + return $this; + } + + /** + * Gets the line length. + * + * @return int|null The length of each line or NULL if line wrapping is + * disabled. + */ + public function getLineLength() + { + return $this->lineLength; + } + + /** + * Generate a DocBlock comment. + * + * @param DocBlock The DocBlock to serialize. + * + * @return string The serialized doc block. + */ + public function getDocComment(DocBlock $docblock) + { + $indent = str_repeat($this->indentString, $this->indent); + $firstIndent = $this->isFirstLineIndented ? $indent : ''; + + $text = $docblock->getText(); + if ($this->lineLength) { + //3 === strlen(' * ') + $wrapLength = $this->lineLength - strlen($indent) - 3; + $text = wordwrap($text, $wrapLength); + } + $text = str_replace("\n", "\n{$indent} * ", $text); + + $comment = "{$firstIndent}/**\n{$indent} * {$text}\n{$indent} *\n"; + + /** @var Tag $tag */ + foreach ($docblock->getTags() as $tag) { + $tagText = (string) $tag; + if ($this->lineLength) { + $tagText = wordwrap($tagText, $wrapLength); + } + $tagText = str_replace("\n", "\n{$indent} * ", $tagText); + + $comment .= "{$indent} * {$tagText}\n"; + } + + $comment .= $indent . ' */'; + + return $comment; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag.php new file mode 100644 index 0000000..a96db09 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag.php @@ -0,0 +1,377 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock; + +/** + * Parses a tag definition for a DocBlock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class Tag implements \Reflector +{ + /** + * PCRE regular expression matching a tag name. + */ + const REGEX_TAGNAME = '[\w\-\_\\\\]+'; + + /** @var string Name of the tag */ + protected $tag = ''; + + /** + * @var string|null Content of the tag. + * When set to NULL, it means it needs to be regenerated. + */ + protected $content = ''; + + /** @var string Description of the content of this tag */ + protected $description = ''; + + /** + * @var array|null The description, as an array of strings and Tag objects. + * When set to NULL, it means it needs to be regenerated. + */ + protected $parsedDescription = null; + + /** @var Location Location of the tag. */ + protected $location = null; + + /** @var DocBlock The DocBlock which this tag belongs to. */ + protected $docblock = null; + + /** + * @var array An array with a tag as a key, and an FQCN to a class that + * handles it as an array value. The class is expected to inherit this + * class. + */ + private static $tagHandlerMappings = array( + 'author' + => '\phpDocumentor\Reflection\DocBlock\Tag\AuthorTag', + 'covers' + => '\phpDocumentor\Reflection\DocBlock\Tag\CoversTag', + 'deprecated' + => '\phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag', + 'example' + => '\phpDocumentor\Reflection\DocBlock\Tag\ExampleTag', + 'link' + => '\phpDocumentor\Reflection\DocBlock\Tag\LinkTag', + 'method' + => '\phpDocumentor\Reflection\DocBlock\Tag\MethodTag', + 'param' + => '\phpDocumentor\Reflection\DocBlock\Tag\ParamTag', + 'property-read' + => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyReadTag', + 'property' + => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyTag', + 'property-write' + => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyWriteTag', + 'return' + => '\phpDocumentor\Reflection\DocBlock\Tag\ReturnTag', + 'see' + => '\phpDocumentor\Reflection\DocBlock\Tag\SeeTag', + 'since' + => '\phpDocumentor\Reflection\DocBlock\Tag\SinceTag', + 'source' + => '\phpDocumentor\Reflection\DocBlock\Tag\SourceTag', + 'throw' + => '\phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag', + 'throws' + => '\phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag', + 'uses' + => '\phpDocumentor\Reflection\DocBlock\Tag\UsesTag', + 'var' + => '\phpDocumentor\Reflection\DocBlock\Tag\VarTag', + 'version' + => '\phpDocumentor\Reflection\DocBlock\Tag\VersionTag' + ); + + /** + * Factory method responsible for instantiating the correct sub type. + * + * @param string $tag_line The text for this tag, including description. + * @param DocBlock $docblock The DocBlock which this tag belongs to. + * @param Location $location Location of the tag. + * + * @throws \InvalidArgumentException if an invalid tag line was presented. + * + * @return static A new tag object. + */ + final public static function createInstance( + $tag_line, + DocBlock $docblock = null, + Location $location = null + ) { + if (!preg_match( + '/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)?/us', + $tag_line, + $matches + )) { + throw new \InvalidArgumentException( + 'Invalid tag_line detected: ' . $tag_line + ); + } + + $handler = __CLASS__; + if (isset(self::$tagHandlerMappings[$matches[1]])) { + $handler = self::$tagHandlerMappings[$matches[1]]; + } elseif (isset($docblock)) { + $tagName = (string)new Type\Collection( + array($matches[1]), + $docblock->getContext() + ); + + if (isset(self::$tagHandlerMappings[$tagName])) { + $handler = self::$tagHandlerMappings[$tagName]; + } + } + + return new $handler( + $matches[1], + isset($matches[2]) ? $matches[2] : '', + $docblock, + $location + ); + } + + /** + * Registers a handler for tags. + * + * Registers a handler for tags. The class specified is autoloaded if it's + * not available. It must inherit from this class. + * + * @param string $tag Name of tag to regiser a handler for. When + * registering a namespaced tag, the full name, along with a prefixing + * slash MUST be provided. + * @param string|null $handler FQCN of handler. Specifing NULL removes the + * handler for the specified tag, if any. + * + * @return bool TRUE on success, FALSE on failure. + */ + final public static function registerTagHandler($tag, $handler) + { + $tag = trim((string)$tag); + + if (null === $handler) { + unset(self::$tagHandlerMappings[$tag]); + return true; + } + + if ('' !== $tag + && class_exists($handler, true) + && is_subclass_of($handler, __CLASS__) + && !strpos($tag, '\\') //Accept no slash, and 1st slash at offset 0. + ) { + self::$tagHandlerMappings[$tag] = $handler; + return true; + } + + return false; + } + + /** + * Parses a tag and populates the member variables. + * + * @param string $name Name of the tag. + * @param string $content The contents of the given tag. + * @param DocBlock $docblock The DocBlock which this tag belongs to. + * @param Location $location Location of the tag. + */ + public function __construct( + $name, + $content, + DocBlock $docblock = null, + Location $location = null + ) { + $this + ->setName($name) + ->setContent($content) + ->setDocBlock($docblock) + ->setLocation($location); + } + + /** + * Gets the name of this tag. + * + * @return string The name of this tag. + */ + public function getName() + { + return $this->tag; + } + + /** + * Sets the name of this tag. + * + * @param string $name The new name of this tag. + * + * @return $this + * @throws \InvalidArgumentException When an invalid tag name is provided. + */ + public function setName($name) + { + if (!preg_match('/^' . self::REGEX_TAGNAME . '$/u', $name)) { + throw new \InvalidArgumentException( + 'Invalid tag name supplied: ' . $name + ); + } + + $this->tag = $name; + + return $this; + } + + /** + * Gets the content of this tag. + * + * @return string + */ + public function getContent() + { + if (null === $this->content) { + $this->content = $this->description; + } + + return $this->content; + } + + /** + * Sets the content of this tag. + * + * @param string $content The new content of this tag. + * + * @return $this + */ + public function setContent($content) + { + $this->setDescription($content); + $this->content = $content; + + return $this; + } + + /** + * Gets the description component of this tag. + * + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * Sets the description component of this tag. + * + * @param string $description The new description component of this tag. + * + * @return $this + */ + public function setDescription($description) + { + $this->content = null; + $this->parsedDescription = null; + $this->description = trim($description); + + return $this; + } + + /** + * Gets the parsed text of this description. + * + * @return array An array of strings and tag objects, in the order they + * occur within the description. + */ + public function getParsedDescription() + { + if (null === $this->parsedDescription) { + $description = new Description($this->description, $this->docblock); + $this->parsedDescription = $description->getParsedContents(); + } + return $this->parsedDescription; + } + + /** + * Gets the docblock this tag belongs to. + * + * @return DocBlock The docblock this tag belongs to. + */ + public function getDocBlock() + { + return $this->docblock; + } + + /** + * Sets the docblock this tag belongs to. + * + * @param DocBlock $docblock The new docblock this tag belongs to. Setting + * NULL removes any association. + * + * @return $this + */ + public function setDocBlock(DocBlock $docblock = null) + { + $this->docblock = $docblock; + + return $this; + } + + /** + * Gets the location of the tag. + * + * @return Location The tag's location. + */ + public function getLocation() + { + return $this->location; + } + + /** + * Sets the location of the tag. + * + * @param Location $location The new location of the tag. + * + * @return $this + */ + public function setLocation(Location $location = null) + { + $this->location = $location; + + return $this; + } + + /** + * Builds a string representation of this object. + * + * @todo determine the exact format as used by PHP Reflection and implement it. + * + * @return void + * @codeCoverageIgnore Not yet implemented + */ + public static function export() + { + throw new \Exception('Not yet implemented'); + } + + /** + * Returns the tag as a serialized string + * + * @return string + */ + public function __toString() + { + return "@{$this->getName()} {$this->getContent()}"; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.php new file mode 100644 index 0000000..bacf52e --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.php @@ -0,0 +1,131 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for an @author tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class AuthorTag extends Tag +{ + /** + * PCRE regular expression matching any valid value for the name component. + */ + const REGEX_AUTHOR_NAME = '[^\<]*'; + + /** + * PCRE regular expression matching any valid value for the email component. + */ + const REGEX_AUTHOR_EMAIL = '[^\>]*'; + + /** @var string The name of the author */ + protected $authorName = ''; + + /** @var string The email of the author */ + protected $authorEmail = ''; + + public function getContent() + { + if (null === $this->content) { + $this->content = $this->authorName; + if ('' != $this->authorEmail) { + $this->content .= "<{$this->authorEmail}>"; + } + } + + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function setContent($content) + { + parent::setContent($content); + if (preg_match( + '/^(' . self::REGEX_AUTHOR_NAME . + ')(\<(' . self::REGEX_AUTHOR_EMAIL . + ')\>)?$/u', + $this->description, + $matches + )) { + $this->authorName = trim($matches[1]); + if (isset($matches[3])) { + $this->authorEmail = trim($matches[3]); + } + } + + return $this; + } + + /** + * Gets the author's name. + * + * @return string The author's name. + */ + public function getAuthorName() + { + return $this->authorName; + } + + /** + * Sets the author's name. + * + * @param string $authorName The new author name. + * An invalid value will set an empty string. + * + * @return $this + */ + public function setAuthorName($authorName) + { + $this->content = null; + $this->authorName + = preg_match('/^' . self::REGEX_AUTHOR_NAME . '$/u', $authorName) + ? $authorName : ''; + + return $this; + } + + /** + * Gets the author's email. + * + * @return string The author's email. + */ + public function getAuthorEmail() + { + return $this->authorEmail; + } + + /** + * Sets the author's email. + * + * @param string $authorEmail The new author email. + * An invalid value will set an empty string. + * + * @return $this + */ + public function setAuthorEmail($authorEmail) + { + $this->authorEmail + = preg_match('/^' . self::REGEX_AUTHOR_EMAIL . '$/u', $authorEmail) + ? $authorEmail : ''; + + $this->content = null; + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/CoversTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/CoversTag.php new file mode 100644 index 0000000..bd31b56 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/CoversTag.php @@ -0,0 +1,24 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @covers tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class CoversTag extends SeeTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTag.php new file mode 100644 index 0000000..7226316 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTag.php @@ -0,0 +1,26 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag\VersionTag; + +/** + * Reflection class for a @deprecated tag in a Docblock. + * + * @author Vasil Rangelov + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class DeprecatedTag extends VersionTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php new file mode 100644 index 0000000..0e163ea --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php @@ -0,0 +1,156 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @example tag in a Docblock. + * + * @author Vasil Rangelov + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class ExampleTag extends SourceTag +{ + /** + * @var string Path to a file to use as an example. + * May also be an absolute URI. + */ + protected $filePath = ''; + + /** + * @var bool Whether the file path component represents an URI. + * This determines how the file portion appears at {@link getContent()}. + */ + protected $isURI = false; + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->content) { + $filePath = ''; + if ($this->isURI) { + if (false === strpos($this->filePath, ':')) { + $filePath = str_replace( + '%2F', + '/', + rawurlencode($this->filePath) + ); + } else { + $filePath = $this->filePath; + } + } else { + $filePath = '"' . $this->filePath . '"'; + } + + $this->content = $filePath . ' ' . parent::getContent(); + } + + return $this->content; + } + /** + * {@inheritdoc} + */ + public function setContent($content) + { + Tag::setContent($content); + if (preg_match( + '/^ + # File component + (?: + # File path in quotes + \"([^\"]+)\" + | + # File URI + (\S+) + ) + # Remaining content (parsed by SourceTag) + (?:\s+(.*))? + $/sux', + $this->description, + $matches + )) { + if ('' !== $matches[1]) { + $this->setFilePath($matches[1]); + } else { + $this->setFileURI($matches[2]); + } + + if (isset($matches[3])) { + parent::setContent($matches[3]); + } else { + $this->setDescription(''); + } + $this->content = $content; + } + + return $this; + } + + /** + * Returns the file path. + * + * @return string Path to a file to use as an example. + * May also be an absolute URI. + */ + public function getFilePath() + { + return $this->filePath; + } + + /** + * Sets the file path. + * + * @param string $filePath The new file path to use for the example. + * + * @return $this + */ + public function setFilePath($filePath) + { + $this->isURI = false; + $this->filePath = trim($filePath); + + $this->content = null; + return $this; + } + + /** + * Sets the file path as an URI. + * + * This function is equivalent to {@link setFilePath()}, except that it + * convers an URI to a file path before that. + * + * There is no getFileURI(), as {@link getFilePath()} is compatible. + * + * @param type $uri The new file URI to use as an example. + */ + public function setFileURI($uri) + { + $this->isURI = true; + if (false === strpos($uri, ':')) { + //Relative URL + $this->filePath = rawurldecode( + str_replace(array('/', '\\'), '%2F', $uri) + ); + } else { + //Absolute URL or URI. + $this->filePath = $uri; + } + + $this->content = null; + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.php new file mode 100644 index 0000000..f79f25d --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.php @@ -0,0 +1,81 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @link tag in a Docblock. + * + * @author Ben Selby + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class LinkTag extends Tag +{ + /** @var string */ + protected $link = ''; + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->content) { + $this->content = "{$this->link} {$this->description}"; + } + + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function setContent($content) + { + parent::setContent($content); + $parts = preg_split('/\s+/Su', $this->description, 2); + + $this->link = $parts[0]; + + $this->setDescription(isset($parts[1]) ? $parts[1] : $parts[0]); + + $this->content = $content; + return $this; + } + + /** + * Gets the link + * + * @return string + */ + public function getLink() + { + return $this->link; + } + + /** + * Sets the link + * + * @param string $link The link + * + * @return $this + */ + public function setLink($link) + { + $this->link = $link; + + $this->content = null; + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php new file mode 100644 index 0000000..7a5ce79 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php @@ -0,0 +1,209 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @method in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class MethodTag extends ReturnTag +{ + + /** @var string */ + protected $method_name = ''; + + /** @var string */ + protected $arguments = ''; + + /** @var bool */ + protected $isStatic = false; + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->content) { + $this->content = ''; + if ($this->isStatic) { + $this->content .= 'static '; + } + $this->content .= $this->type . + " {$this->method_name}({$this->arguments}) " . + $this->description; + } + + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function setContent($content) + { + Tag::setContent($content); + // 1. none or more whitespace + // 2. optionally the keyword "static" followed by whitespace + // 3. optionally a word with underscores followed by whitespace : as + // type for the return value + // 4. then optionally a word with underscores followed by () and + // whitespace : as method name as used by phpDocumentor + // 5. then a word with underscores, followed by ( and any character + // until a ) and whitespace : as method name with signature + // 6. any remaining text : as description + if (preg_match( + '/^ + # Static keyword + # Declates a static method ONLY if type is also present + (?: + (static) + \s+ + )? + # Return type + (?: + ([\w\|_\\\\]+) + \s+ + )? + # Legacy method name (not captured) + (?: + [\w_]+\(\)\s+ + )? + # Method name + ([\w\|_\\\\]+) + # Arguments + \(([^\)]*)\) + \s* + # Description + (.*) + $/sux', + $this->description, + $matches + )) { + list( + , + $static, + $this->type, + $this->method_name, + $this->arguments, + $this->description + ) = $matches; + if ($static) { + if (!$this->type) { + $this->type = 'static'; + } else { + $this->isStatic = true; + } + } else { + if (!$this->type) { + $this->type = 'void'; + } + } + $this->parsedDescription = null; + } + + return $this; + } + + /** + * Sets the name of this method. + * + * @param string $method_name The name of the method. + * + * @return $this + */ + public function setMethodName($method_name) + { + $this->method_name = $method_name; + + $this->content = null; + return $this; + } + + /** + * Retrieves the method name. + * + * @return string + */ + public function getMethodName() + { + return $this->method_name; + } + + /** + * Sets the arguments for this method. + * + * @param string $arguments A comma-separated arguments line. + * + * @return void + */ + public function setArguments($arguments) + { + $this->arguments = $arguments; + + $this->content = null; + return $this; + } + + /** + * Returns an array containing each argument as array of type and name. + * + * Please note that the argument sub-array may only contain 1 element if no + * type was specified. + * + * @return string[] + */ + public function getArguments() + { + if (empty($this->arguments)) { + return array(); + } + + $arguments = explode(',', $this->arguments); + foreach ($arguments as $key => $value) { + $arguments[$key] = explode(' ', trim($value)); + } + + return $arguments; + } + + /** + * Checks whether the method tag describes a static method or not. + * + * @return bool TRUE if the method declaration is for a static method, FALSE + * otherwise. + */ + public function isStatic() + { + return $this->isStatic; + } + + /** + * Sets a new value for whether the method is static or not. + * + * @param bool $isStatic The new value to set. + * + * @return $this + */ + public function setIsStatic($isStatic) + { + $this->isStatic = $isStatic; + + $this->content = null; + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ParamTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ParamTag.php new file mode 100644 index 0000000..9bc0270 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ParamTag.php @@ -0,0 +1,119 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @param tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class ParamTag extends ReturnTag +{ + /** @var string */ + protected $variableName = ''; + + /** @var bool determines whether this is a variadic argument */ + protected $isVariadic = false; + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->content) { + $this->content + = "{$this->type} {$this->variableName} {$this->description}"; + } + return $this->content; + } + /** + * {@inheritdoc} + */ + public function setContent($content) + { + Tag::setContent($content); + $parts = preg_split( + '/(\s+)/Su', + $this->description, + 3, + PREG_SPLIT_DELIM_CAPTURE + ); + + // if the first item that is encountered is not a variable; it is a type + if (isset($parts[0]) + && (strlen($parts[0]) > 0) + && ($parts[0][0] !== '$') + ) { + $this->type = array_shift($parts); + array_shift($parts); + } + + // if the next item starts with a $ or ...$ it must be the variable name + if (isset($parts[0]) + && (strlen($parts[0]) > 0) + && ($parts[0][0] == '$' || substr($parts[0], 0, 4) === '...$') + ) { + $this->variableName = array_shift($parts); + array_shift($parts); + + if (substr($this->variableName, 0, 3) === '...') { + $this->isVariadic = true; + $this->variableName = substr($this->variableName, 3); + } + } + + $this->setDescription(implode('', $parts)); + + $this->content = $content; + return $this; + } + + /** + * Returns the variable's name. + * + * @return string + */ + public function getVariableName() + { + return $this->variableName; + } + + /** + * Sets the variable's name. + * + * @param string $name The new name for this variable. + * + * @return $this + */ + public function setVariableName($name) + { + $this->variableName = $name; + + $this->content = null; + return $this; + } + + /** + * Returns whether this tag is variadic. + * + * @return boolean + */ + public function isVariadic() + { + return $this->isVariadic; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyReadTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyReadTag.php new file mode 100644 index 0000000..3340602 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyReadTag.php @@ -0,0 +1,24 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @property-read tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class PropertyReadTag extends PropertyTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyTag.php new file mode 100644 index 0000000..288ecff --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyTag.php @@ -0,0 +1,24 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @property tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class PropertyTag extends ParamTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyWriteTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyWriteTag.php new file mode 100644 index 0000000..ec4e866 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/PropertyWriteTag.php @@ -0,0 +1,24 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @property-write tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class PropertyWriteTag extends PropertyTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ReturnTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ReturnTag.php new file mode 100644 index 0000000..9293db9 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ReturnTag.php @@ -0,0 +1,99 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; +use phpDocumentor\Reflection\DocBlock\Type\Collection; + +/** + * Reflection class for a @return tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class ReturnTag extends Tag +{ + /** @var string The raw type component. */ + protected $type = ''; + + /** @var Collection The parsed type component. */ + protected $types = null; + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->content) { + $this->content = "{$this->type} {$this->description}"; + } + + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function setContent($content) + { + parent::setContent($content); + + $parts = preg_split('/\s+/Su', $this->description, 2); + + // any output is considered a type + $this->type = $parts[0]; + $this->types = null; + + $this->setDescription(isset($parts[1]) ? $parts[1] : ''); + + $this->content = $content; + return $this; + } + + /** + * Returns the unique types of the variable. + * + * @return string[] + */ + public function getTypes() + { + return $this->getTypesCollection()->getArrayCopy(); + } + + /** + * Returns the type section of the variable. + * + * @return string + */ + public function getType() + { + return (string) $this->getTypesCollection(); + } + + /** + * Returns the type collection. + * + * @return void + */ + protected function getTypesCollection() + { + if (null === $this->types) { + $this->types = new Collection( + array($this->type), + $this->docblock ? $this->docblock->getContext() : null + ); + } + return $this->types; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.php new file mode 100644 index 0000000..4f5f22c --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.php @@ -0,0 +1,81 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @see tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class SeeTag extends Tag +{ + /** @var string */ + protected $refers = null; + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->content) { + $this->content = "{$this->refers} {$this->description}"; + } + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function setContent($content) + { + parent::setContent($content); + $parts = preg_split('/\s+/Su', $this->description, 2); + + // any output is considered a type + $this->refers = $parts[0]; + + $this->setDescription(isset($parts[1]) ? $parts[1] : ''); + + $this->content = $content; + return $this; + } + + /** + * Gets the structural element this tag refers to. + * + * @return string + */ + public function getReference() + { + return $this->refers; + } + + /** + * Sets the structural element this tag refers to. + * + * @param string $refers The new type this tag refers to. + * + * @return $this + */ + public function setReference($refers) + { + $this->refers = $refers; + + $this->content = null; + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SinceTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SinceTag.php new file mode 100644 index 0000000..ba009c4 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SinceTag.php @@ -0,0 +1,26 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag\VersionTag; + +/** + * Reflection class for a @since tag in a Docblock. + * + * @author Vasil Rangelov + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class SinceTag extends VersionTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php new file mode 100644 index 0000000..3400220 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php @@ -0,0 +1,137 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @source tag in a Docblock. + * + * @author Vasil Rangelov + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class SourceTag extends Tag +{ + /** + * @var int The starting line, relative to the structural element's + * location. + */ + protected $startingLine = 1; + + /** + * @var int|null The number of lines, relative to the starting line. NULL + * means "to the end". + */ + protected $lineCount = null; + + /** + * {@inheritdoc} + */ + public function getContent() + { + if (null === $this->content) { + $this->content + = "{$this->startingLine} {$this->lineCount} {$this->description}"; + } + + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function setContent($content) + { + parent::setContent($content); + if (preg_match( + '/^ + # Starting line + ([1-9]\d*) + \s* + # Number of lines + (?: + ((?1)) + \s+ + )? + # Description + (.*) + $/sux', + $this->description, + $matches + )) { + $this->startingLine = (int)$matches[1]; + if (isset($matches[2]) && '' !== $matches[2]) { + $this->lineCount = (int)$matches[2]; + } + $this->setDescription($matches[3]); + $this->content = $content; + } + + return $this; + } + + /** + * Gets the starting line. + * + * @return int The starting line, relative to the structural element's + * location. + */ + public function getStartingLine() + { + return $this->startingLine; + } + + /** + * Sets the starting line. + * + * @param int $startingLine The new starting line, relative to the + * structural element's location. + * + * @return $this + */ + public function setStartingLine($startingLine) + { + $this->startingLine = $startingLine; + + $this->content = null; + return $this; + } + + /** + * Returns the number of lines. + * + * @return int|null The number of lines, relative to the starting line. NULL + * means "to the end". + */ + public function getLineCount() + { + return $this->lineCount; + } + + /** + * Sets the number of lines. + * + * @param int|null $lineCount The new number of lines, relative to the + * starting line. NULL means "to the end". + * + * @return $this + */ + public function setLineCount($lineCount) + { + $this->lineCount = $lineCount; + + $this->content = null; + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTag.php new file mode 100644 index 0000000..58ee44a --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTag.php @@ -0,0 +1,24 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @throws tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class ThrowsTag extends ReturnTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/UsesTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/UsesTag.php new file mode 100644 index 0000000..da0d663 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/UsesTag.php @@ -0,0 +1,24 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @uses tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class UsesTag extends SeeTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/VarTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/VarTag.php new file mode 100644 index 0000000..236b2c8 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/VarTag.php @@ -0,0 +1,24 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @var tag in a Docblock. + * + * @author Mike van Riel + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class VarTag extends ParamTag +{ +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/VersionTag.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/VersionTag.php new file mode 100644 index 0000000..260f698 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Tag/VersionTag.php @@ -0,0 +1,108 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +use phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Reflection class for a @version tag in a Docblock. + * + * @author Vasil Rangelov + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class VersionTag extends Tag +{ + /** + * PCRE regular expression matching a version vector. + * Assumes the "x" modifier. + */ + const REGEX_VECTOR = '(?: + # Normal release vectors. + \d\S* + | + # VCS version vectors. Per PHPCS, they are expected to + # follow the form of the VCS name, followed by ":", followed + # by the version vector itself. + # By convention, popular VCSes like CVS, SVN and GIT use "$" + # around the actual version vector. + [^\s\:]+\:\s*\$[^\$]+\$ + )'; + + /** @var string The version vector. */ + protected $version = ''; + + public function getContent() + { + if (null === $this->content) { + $this->content = "{$this->version} {$this->description}"; + } + + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function setContent($content) + { + parent::setContent($content); + + if (preg_match( + '/^ + # The version vector + (' . self::REGEX_VECTOR . ') + \s* + # The description + (.+)? + $/sux', + $this->description, + $matches + )) { + $this->version = $matches[1]; + $this->setDescription(isset($matches[2]) ? $matches[2] : ''); + $this->content = $content; + } + + return $this; + } + + /** + * Gets the version section of the tag. + * + * @return string The version section of the tag. + */ + public function getVersion() + { + return $this->version; + } + + /** + * Sets the version section of the tag. + * + * @param string $version The new version section of the tag. + * An invalid value will set an empty string. + * + * @return $this + */ + public function setVersion($version) + { + $this->version + = preg_match('/^' . self::REGEX_VECTOR . '$/ux', $version) + ? $version + : ''; + + $this->content = null; + return $this; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Type/Collection.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Type/Collection.php new file mode 100644 index 0000000..90ead3f --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Type/Collection.php @@ -0,0 +1,221 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Type; + +use phpDocumentor\Reflection\DocBlock\Context; + +/** + * Collection + * + * @author Mike van Riel + * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class Collection extends \ArrayObject +{ + /** @var string Definition of the OR operator for types */ + const OPERATOR_OR = '|'; + + /** @var string Definition of the ARRAY operator for types */ + const OPERATOR_ARRAY = '[]'; + + /** @var string Definition of the NAMESPACE operator in PHP */ + const OPERATOR_NAMESPACE = '\\'; + + /** @var string[] List of recognized keywords */ + protected static $keywords = array( + 'string', 'int', 'integer', 'bool', 'boolean', 'float', 'double', + 'object', 'mixed', 'array', 'resource', 'void', 'null', 'scalar', + 'callback', 'callable', 'false', 'true', 'self', '$this', 'static' + ); + + /** + * Current invoking location. + * + * This is used to prepend to type with a relative location. + * May also be 'default' or 'global', in which case they are ignored. + * + * @var Context + */ + protected $context = null; + + /** + * Registers the namespace and aliases; uses that to add and expand the + * given types. + * + * @param string[] $types Array containing a list of types to add to this + * container. + * @param Context $location The current invoking location. + */ + public function __construct( + array $types = array(), + Context $context = null + ) { + $this->context = null === $context ? new Context() : $context; + + foreach ($types as $type) { + $this->add($type); + } + } + + /** + * Returns the current invoking location. + * + * @return Context + */ + public function getContext() + { + return $this->context; + } + + /** + * Adds a new type to the collection and expands it if it contains a + * relative namespace. + * + * If a class in the type contains a relative namespace than this collection + * will try to expand that into a FQCN. + * + * @param string $type A 'Type' as defined in the phpDocumentor + * documentation. + * + * @throws \InvalidArgumentException if a non-string argument is passed. + * + * @see http://phpdoc.org/docs/latest/for-users/types.html for the + * definition of a type. + * + * @return void + */ + public function add($type) + { + if (!is_string($type)) { + throw new \InvalidArgumentException( + 'A type should be represented by a string, received: ' + .var_export($type, true) + ); + } + + // separate the type by the OR operator + $type_parts = explode(self::OPERATOR_OR, $type); + foreach ($type_parts as $part) { + $expanded_type = $this->expand($part); + if ($expanded_type) { + $this[] = $expanded_type; + } + } + } + + /** + * Returns a string representation of the collection. + * + * @return string The resolved types across the collection, separated with + * {@link self::OPERATOR_OR}. + */ + public function __toString() + { + return implode(self::OPERATOR_OR, $this->getArrayCopy()); + } + + /** + * Analyzes the given type and returns the FQCN variant. + * + * When a type is provided this method checks whether it is not a keyword or + * Fully Qualified Class Name. If so it will use the given namespace and + * aliases to expand the type to a FQCN representation. + * + * This method only works as expected if the namespace and aliases are set; + * no dynamic reflection is being performed here. + * + * @param string $type The relative or absolute type. + * + * @uses getNamespace to determine with what to prefix the type name. + * @uses getNamespaceAliases to check whether the first part of the relative + * type name should not be replaced with another namespace. + * + * @return string + */ + protected function expand($type) + { + $type = trim($type); + if (!$type) { + return ''; + } + + if ($this->isTypeAnArray($type)) { + return $this->expand(substr($type, 0, -2)) . self::OPERATOR_ARRAY; + } + + if ($this->isRelativeType($type) && !$this->isTypeAKeyword($type)) { + $type_parts = explode(self::OPERATOR_NAMESPACE, $type, 2); + + $namespace_aliases = $this->context->getNamespaceAliases(); + // if the first segment is not an alias; prepend namespace name and + // return + if (!isset($namespace_aliases[$type_parts[0]])) { + $namespace = $this->context->getNamespace(); + if ('' !== $namespace) { + $namespace .= self::OPERATOR_NAMESPACE; + } + return self::OPERATOR_NAMESPACE . $namespace . $type; + } + + $type_parts[0] = $namespace_aliases[$type_parts[0]]; + $type = implode(self::OPERATOR_NAMESPACE, $type_parts); + } + + return $type; + } + + /** + * Detects whether the given type represents an array. + * + * @param string $type A relative or absolute type as defined in the + * phpDocumentor documentation. + * + * @return bool + */ + protected function isTypeAnArray($type) + { + return substr($type, -2) === self::OPERATOR_ARRAY; + } + + /** + * Detects whether the given type represents a PHPDoc keyword. + * + * @param string $type A relative or absolute type as defined in the + * phpDocumentor documentation. + * + * @return bool + */ + protected function isTypeAKeyword($type) + { + return in_array(strtolower($type), static::$keywords, true); + } + + /** + * Detects whether the given type represents a relative or absolute path. + * + * This method will detect keywords as being absolute; even though they are + * not preceeded by a namespace separator. + * + * @param string $type A relative or absolute type as defined in the + * phpDocumentor documentation. + * + * @return bool + */ + protected function isRelativeType($type) + { + return ($type[0] !== self::OPERATOR_NAMESPACE) + || $this->isTypeAKeyword($type); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/DescriptionTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/DescriptionTest.php new file mode 100644 index 0000000..a6ca7b3 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/DescriptionTest.php @@ -0,0 +1,245 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Description + * + * @author Vasil Rangelov + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class DescriptionTest extends \PHPUnit_Framework_TestCase +{ + public function testConstruct() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(1, $parsedContents); + $this->assertSame($fixture, $parsedContents[0]); + } + + public function testInlineTagParsing() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + $this->assertSame('This is text for a ', $parsedContents[0]); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag\LinkTag', + $parsedContents[1] + ); + $this->assertSame( + ' that uses inline +tags.', + $parsedContents[2] + ); + } + + public function testInlineTagAtStartParsing() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + + $this->assertSame('', $parsedContents[0]); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag\LinkTag', + $parsedContents[1] + ); + $this->assertSame( + ' is text for a description that uses inline +tags.', + $parsedContents[2] + ); + } + + public function testNestedInlineTagParsing() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + + $this->assertSame( + 'This is text for a description with ', + $parsedContents[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $parsedContents[1] + ); + $this->assertSame('.', $parsedContents[2]); + + $parsedDescription = $parsedContents[1]->getParsedDescription(); + $this->assertCount(3, $parsedDescription); + $this->assertSame("inline tag with\n", $parsedDescription[0]); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag\LinkTag', + $parsedDescription[1] + ); + $this->assertSame(' in it', $parsedDescription[2]); + } + + public function testLiteralOpeningDelimiter() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(1, $parsedContents); + $this->assertSame($fixture, $parsedContents[0]); + } + + public function testNestedLiteralOpeningDelimiter() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + $this->assertSame( + 'This is text for a description containing ', + $parsedContents[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $parsedContents[1] + ); + $this->assertSame('.', $parsedContents[2]); + + $this->assertSame( + array('inline tag that has { that +is literal'), + $parsedContents[1]->getParsedDescription() + ); + } + + public function testLiteralClosingDelimiter() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(1, $parsedContents); + $this->assertSame( + 'This is text for a description with } that is not a tag.', + $parsedContents[0] + ); + } + + public function testNestedLiteralClosingDelimiter() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + $this->assertSame( + 'This is text for a description with ', + $parsedContents[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $parsedContents[1] + ); + $this->assertSame('.', $parsedContents[2]); + + $this->assertSame( + array('inline tag with } that is not an +inline tag'), + $parsedContents[1]->getParsedDescription() + ); + } + + public function testInlineTagEscapingSequence() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(1, $parsedContents); + $this->assertSame( + 'This is text for a description with literal {@link}.', + $parsedContents[0] + ); + } + + public function testNestedInlineTagEscapingSequence() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + $this->assertSame( + 'This is text for a description with an ', + $parsedContents[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $parsedContents[1] + ); + $this->assertSame('.', $parsedContents[2]); + + $this->assertSame( + array('inline tag with literal +{@link} in it'), + $parsedContents[1]->getParsedDescription() + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/CoversTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/CoversTagTest.php new file mode 100644 index 0000000..ff257aa --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/CoversTagTest.php @@ -0,0 +1,86 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\CoversTag + * + * @author Daniel O'Connor + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class CoversTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\CoversTag can create + * a link for the covers doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exReference + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\CoversTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exReference + ) { + $tag = new CoversTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exReference, $tag->getReference()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exReference + return array( + array( + 'covers', + 'Foo::bar()', + 'Foo::bar()', + '', + 'Foo::bar()' + ), + array( + 'covers', + 'Foo::bar() Testing', + 'Foo::bar() Testing', + 'Testing', + 'Foo::bar()', + ), + array( + 'covers', + 'Foo::bar() Testing comments', + 'Foo::bar() Testing comments', + 'Testing comments', + 'Foo::bar()', + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTagTest.php new file mode 100644 index 0000000..7a75e79 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTagTest.php @@ -0,0 +1,115 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag + * + * @author Vasil Rangelov + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class DeprecatedTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\LinkTag can create + * a link for the @deprecated doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exDescription + * @param string $exVersion + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exVersion + ) { + $tag = new DeprecatedTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exVersion, $tag->getVersion()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exVersion + return array( + array( + 'deprecated', + '1.0 First release.', + '1.0 First release.', + 'First release.', + '1.0' + ), + array( + 'deprecated', + "1.0\nFirst release.", + "1.0\nFirst release.", + 'First release.', + '1.0' + ), + array( + 'deprecated', + "1.0\nFirst\nrelease.", + "1.0\nFirst\nrelease.", + "First\nrelease.", + '1.0' + ), + array( + 'deprecated', + 'Unfinished release', + 'Unfinished release', + 'Unfinished release', + '' + ), + array( + 'deprecated', + '1.0', + '1.0', + '', + '1.0' + ), + array( + 'deprecated', + 'GIT: $Id$', + 'GIT: $Id$', + '', + 'GIT: $Id$' + ), + array( + 'deprecated', + 'GIT: $Id$ Dev build', + 'GIT: $Id$ Dev build', + 'Dev build', + 'GIT: $Id$' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ExampleTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ExampleTagTest.php new file mode 100644 index 0000000..519a61b --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ExampleTagTest.php @@ -0,0 +1,203 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\ExampleTag + * + * @author Vasil Rangelov + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class ExampleTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\SourceTag can + * understand the @source DocBlock. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exStartingLine + * @param string $exLineCount + * @param string $exFilepath + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\ExampleTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exStartingLine, + $exLineCount, + $exFilePath + ) { + $tag = new ExampleTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exStartingLine, $tag->getStartingLine()); + $this->assertEquals($exLineCount, $tag->getLineCount()); + $this->assertEquals($exFilePath, $tag->getFilePath()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, + // $content, + // $exContent, + // $exDescription, + // $exStartingLine, + // $exLineCount, + // $exFilePath + return array( + array( + 'example', + 'file.php', + 'file.php', + '', + 1, + null, + 'file.php' + ), + array( + 'example', + 'Testing comments', + 'Testing comments', + 'comments', + 1, + null, + 'Testing' + ), + array( + 'example', + 'file.php 2 Testing', + 'file.php 2 Testing', + 'Testing', + 2, + null, + 'file.php' + ), + array( + 'example', + 'file.php 2 3 Testing comments', + 'file.php 2 3 Testing comments', + 'Testing comments', + 2, + 3, + 'file.php' + ), + array( + 'example', + 'file.php 2 -1 Testing comments', + 'file.php 2 -1 Testing comments', + '-1 Testing comments', + 2, + null, + 'file.php' + ), + array( + 'example', + 'file.php -1 1 Testing comments', + 'file.php -1 1 Testing comments', + '-1 1 Testing comments', + 1, + null, + 'file.php' + ), + array( + 'example', + '"file with spaces.php" Testing comments', + '"file with spaces.php" Testing comments', + 'Testing comments', + 1, + null, + 'file with spaces.php' + ), + array( + 'example', + '"file with spaces.php" 2 Testing comments', + '"file with spaces.php" 2 Testing comments', + 'Testing comments', + 2, + null, + 'file with spaces.php' + ), + array( + 'example', + '"file with spaces.php" 2 3 Testing comments', + '"file with spaces.php" 2 3 Testing comments', + 'Testing comments', + 2, + 3, + 'file with spaces.php' + ), + array( + 'example', + '"file with spaces.php" 2 -3 Testing comments', + '"file with spaces.php" 2 -3 Testing comments', + '-3 Testing comments', + 2, + null, + 'file with spaces.php' + ), + array( + 'example', + '"file with spaces.php" -2 3 Testing comments', + '"file with spaces.php" -2 3 Testing comments', + '-2 3 Testing comments', + 1, + null, + 'file with spaces.php' + ), + array( + 'example', + 'file%20with%20spaces.php Testing comments', + 'file%20with%20spaces.php Testing comments', + 'Testing comments', + 1, + null, + 'file with spaces.php' + ), + array( + 'example', + 'folder/file%20with%20spaces.php Testing comments', + 'folder/file%20with%20spaces.php Testing comments', + 'Testing comments', + 1, + null, + 'folder/file with spaces.php' + ), + array( + 'example', + 'http://example.com/file%20with%20spaces.php Testing comments', + 'http://example.com/file%20with%20spaces.php Testing comments', + 'Testing comments', + 1, + null, + 'http://example.com/file%20with%20spaces.php' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/LinkTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/LinkTagTest.php new file mode 100644 index 0000000..0c64ed0 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/LinkTagTest.php @@ -0,0 +1,87 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\LinkTag + * + * @author Ben Selby + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class LinkTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\LinkTag can create + * a link for the @link doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exDescription + * @param string $exLink + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\LinkTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exLink + ) { + $tag = new LinkTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exLink, $tag->getLink()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exLink + return array( + array( + 'link', + 'http://www.phpdoc.org/', + 'http://www.phpdoc.org/', + 'http://www.phpdoc.org/', + 'http://www.phpdoc.org/' + ), + array( + 'link', + 'http://www.phpdoc.org/ Testing', + 'http://www.phpdoc.org/ Testing', + 'Testing', + 'http://www.phpdoc.org/' + ), + array( + 'link', + 'http://www.phpdoc.org/ Testing comments', + 'http://www.phpdoc.org/ Testing comments', + 'Testing comments', + 'http://www.phpdoc.org/' + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/MethodTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/MethodTagTest.php new file mode 100644 index 0000000..efc3a15 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/MethodTagTest.php @@ -0,0 +1,146 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\MethodTag + * + * @author Mike van Riel + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class MethodTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * @param string $signature The signature to test. + * @param bool $valid Whether the given signature is expected to + * be valid. + * @param string $expected_name The method name that is expected from this + * signature. + * @param string $expected_return The return type that is expected from this + * signature. + * @param bool $paramCount Number of parameters in the signature. + * @param string $description The short description mentioned in the + * signature. + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\MethodTag + * @dataProvider getTestSignatures + * + * @return void + */ + public function testConstruct( + $signature, + $valid, + $expected_name, + $expected_return, + $expected_isStatic, + $paramCount, + $description + ) { + ob_start(); + $tag = new MethodTag('method', $signature); + $stdout = ob_get_clean(); + + $this->assertSame( + $valid, + empty($stdout), + 'No error should have been output if the signature is valid' + ); + + if (!$valid) { + return; + } + + $this->assertEquals($expected_name, $tag->getMethodName()); + $this->assertEquals($expected_return, $tag->getType()); + $this->assertEquals($description, $tag->getDescription()); + $this->assertEquals($expected_isStatic, $tag->isStatic()); + $this->assertCount($paramCount, $tag->getArguments()); + } + + public function getTestSignatures() + { + return array( + // TODO: Verify this case +// array( +// 'foo', +// false, 'foo', '', false, 0, '' +// ), + array( + 'foo()', + true, 'foo', 'void', false, 0, '' + ), + array( + 'foo() description', + true, 'foo', 'void', false, 0, 'description' + ), + array( + 'int foo()', + true, 'foo', 'int', false, 0, '' + ), + array( + 'int foo() description', + true, 'foo', 'int', false, 0, 'description' + ), + array( + 'int foo($a, $b)', + true, 'foo', 'int', false, 2, '' + ), + array( + 'int foo() foo(int $a, int $b)', + true, 'foo', 'int', false, 2, '' + ), + array( + 'int foo(int $a, int $b)', + true, 'foo', 'int', false, 2, '' + ), + array( + 'null|int foo(int $a, int $b)', + true, 'foo', 'null|int', false, 2, '' + ), + array( + 'int foo(null|int $a, int $b)', + true, 'foo', 'int', false, 2, '' + ), + array( + '\Exception foo() foo(Exception $a, Exception $b)', + true, 'foo', '\Exception', false, 2, '' + ), + array( + 'int foo() foo(Exception $a, Exception $b) description', + true, 'foo', 'int', false, 2, 'description' + ), + array( + 'int foo() foo(\Exception $a, \Exception $b) description', + true, 'foo', 'int', false, 2, 'description' + ), + array( + 'void()', + true, 'void', 'void', false, 0, '' + ), + array( + 'static foo()', + true, 'foo', 'static', false, 0, '' + ), + array( + 'static void foo()', + true, 'foo', 'void', true, 0, '' + ), + array( + 'static static foo()', + true, 'foo', 'static', true, 0, '' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ParamTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ParamTagTest.php new file mode 100644 index 0000000..0e05382 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ParamTagTest.php @@ -0,0 +1,118 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\ParamTag + * + * @author Mike van Riel + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class ParamTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\ParamTag can + * understand the @param DocBlock. + * + * @param string $type + * @param string $content + * @param string $extractedType + * @param string $extractedTypes + * @param string $extractedVarName + * @param string $extractedDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\ParamTag + * @dataProvider provideDataForConstructor + * + * @return void + */ + public function testConstructorParsesInputsIntoCorrectFields( + $type, + $content, + $extractedType, + $extractedTypes, + $extractedVarName, + $extractedDescription + ) { + $tag = new ParamTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($extractedType, $tag->getType()); + $this->assertEquals($extractedTypes, $tag->getTypes()); + $this->assertEquals($extractedVarName, $tag->getVariableName()); + $this->assertEquals($extractedDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParsesInputsIntoCorrectFields() + * + * @return array + */ + public function provideDataForConstructor() + { + return array( + array('param', 'int', 'int', array('int'), '', ''), + array('param', '$bob', '', array(), '$bob', ''), + array( + 'param', + 'int Number of bobs', + 'int', + array('int'), + '', + 'Number of bobs' + ), + array( + 'param', + 'int $bob', + 'int', + array('int'), + '$bob', + '' + ), + array( + 'param', + 'int $bob Number of bobs', + 'int', + array('int'), + '$bob', + 'Number of bobs' + ), + array( + 'param', + "int Description \n on multiple lines", + 'int', + array('int'), + '', + "Description \n on multiple lines" + ), + array( + 'param', + "int \n\$bob Variable name on a new line", + 'int', + array('int'), + '$bob', + "Variable name on a new line" + ), + array( + 'param', + "\nint \$bob Type on a new line", + 'int', + array('int'), + '$bob', + "Type on a new line" + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ReturnTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ReturnTagTest.php new file mode 100644 index 0000000..9e2aec0 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ReturnTagTest.php @@ -0,0 +1,102 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\ReturnTag + * + * @author Mike van Riel + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class ReturnTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\ReturnTag can + * understand the @return DocBlock. + * + * @param string $type + * @param string $content + * @param string $extractedType + * @param string $extractedTypes + * @param string $extractedDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\ReturnTag + * @dataProvider provideDataForConstructor + * + * @return void + */ + public function testConstructorParsesInputsIntoCorrectFields( + $type, + $content, + $extractedType, + $extractedTypes, + $extractedDescription + ) { + $tag = new ReturnTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($extractedType, $tag->getType()); + $this->assertEquals($extractedTypes, $tag->getTypes()); + $this->assertEquals($extractedDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParsesInputsIntoCorrectFields() + * + * @return array + */ + public function provideDataForConstructor() + { + return array( + array('return', '', '', array(), ''), + array('return', 'int', 'int', array('int'), ''), + array( + 'return', + 'int Number of Bobs', + 'int', + array('int'), + 'Number of Bobs' + ), + array( + 'return', + 'int|double Number of Bobs', + 'int|double', + array('int', 'double'), + 'Number of Bobs' + ), + array( + 'return', + "int Number of \n Bobs", + 'int', + array('int'), + "Number of \n Bobs" + ), + array( + 'return', + " int Number of Bobs", + 'int', + array('int'), + "Number of Bobs" + ), + array( + 'return', + "int\nNumber of Bobs", + 'int', + array('int'), + "Number of Bobs" + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SeeTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SeeTagTest.php new file mode 100644 index 0000000..6829b04 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SeeTagTest.php @@ -0,0 +1,86 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\SeeTag + * + * @author Daniel O'Connor + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class SeeTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the phpDocumentor_Reflection_DocBlock_Tag_See can create a link + * for the @see doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exReference + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\SeeTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exReference + ) { + $tag = new SeeTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exReference, $tag->getReference()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exReference + return array( + array( + 'see', + 'Foo::bar()', + 'Foo::bar()', + '', + 'Foo::bar()' + ), + array( + 'see', + 'Foo::bar() Testing', + 'Foo::bar() Testing', + 'Testing', + 'Foo::bar()', + ), + array( + 'see', + 'Foo::bar() Testing comments', + 'Foo::bar() Testing comments', + 'Testing comments', + 'Foo::bar()', + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SinceTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SinceTagTest.php new file mode 100644 index 0000000..8caf25d --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SinceTagTest.php @@ -0,0 +1,115 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\SinceTag + * + * @author Vasil Rangelov + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class SinceTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\LinkTag can create + * a link for the @since doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exDescription + * @param string $exVersion + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\SinceTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exVersion + ) { + $tag = new SinceTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exVersion, $tag->getVersion()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exVersion + return array( + array( + 'since', + '1.0 First release.', + '1.0 First release.', + 'First release.', + '1.0' + ), + array( + 'since', + "1.0\nFirst release.", + "1.0\nFirst release.", + 'First release.', + '1.0' + ), + array( + 'since', + "1.0\nFirst\nrelease.", + "1.0\nFirst\nrelease.", + "First\nrelease.", + '1.0' + ), + array( + 'since', + 'Unfinished release', + 'Unfinished release', + 'Unfinished release', + '' + ), + array( + 'since', + '1.0', + '1.0', + '', + '1.0' + ), + array( + 'since', + 'GIT: $Id$', + 'GIT: $Id$', + '', + 'GIT: $Id$' + ), + array( + 'since', + 'GIT: $Id$ Dev build', + 'GIT: $Id$ Dev build', + 'Dev build', + 'GIT: $Id$' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SourceTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SourceTagTest.php new file mode 100644 index 0000000..2a40e0a --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SourceTagTest.php @@ -0,0 +1,116 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\SourceTag + * + * @author Vasil Rangelov + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class SourceTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\SourceTag can + * understand the @source DocBlock. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exStartingLine + * @param string $exLineCount + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\SourceTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exStartingLine, + $exLineCount + ) { + $tag = new SourceTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exStartingLine, $tag->getStartingLine()); + $this->assertEquals($exLineCount, $tag->getLineCount()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exStartingLine, $exLineCount + return array( + array( + 'source', + '2', + '2', + '', + 2, + null + ), + array( + 'source', + 'Testing', + 'Testing', + 'Testing', + 1, + null + ), + array( + 'source', + '2 Testing', + '2 Testing', + 'Testing', + 2, + null + ), + array( + 'source', + '2 3 Testing comments', + '2 3 Testing comments', + 'Testing comments', + 2, + 3 + ), + array( + 'source', + '2 -1 Testing comments', + '2 -1 Testing comments', + '-1 Testing comments', + 2, + null + ), + array( + 'source', + '-1 1 Testing comments', + '-1 1 Testing comments', + '-1 1 Testing comments', + 1, + null + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTagTest.php new file mode 100644 index 0000000..3c669d5 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTagTest.php @@ -0,0 +1,102 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\ThrowsTag + * + * @author Mike van Riel + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class ThrowsTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag can + * understand the @throws DocBlock. + * + * @param string $type + * @param string $content + * @param string $extractedType + * @param string $extractedTypes + * @param string $extractedDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag + * @dataProvider provideDataForConstructor + * + * @return void + */ + public function testConstructorParsesInputsIntoCorrectFields( + $type, + $content, + $extractedType, + $extractedTypes, + $extractedDescription + ) { + $tag = new ThrowsTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($extractedType, $tag->getType()); + $this->assertEquals($extractedTypes, $tag->getTypes()); + $this->assertEquals($extractedDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParsesInputsIntoCorrectFields() + * + * @return array + */ + public function provideDataForConstructor() + { + return array( + array('throws', '', '', array(), ''), + array('throws', 'int', 'int', array('int'), ''), + array( + 'throws', + 'int Number of Bobs', + 'int', + array('int'), + 'Number of Bobs' + ), + array( + 'throws', + 'int|double Number of Bobs', + 'int|double', + array('int', 'double'), + 'Number of Bobs' + ), + array( + 'throws', + "int Number of \n Bobs", + 'int', + array('int'), + "Number of \n Bobs" + ), + array( + 'throws', + " int Number of Bobs", + 'int', + array('int'), + "Number of Bobs" + ), + array( + 'throws', + "int\nNumber of Bobs", + 'int', + array('int'), + "Number of Bobs" + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/UsesTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/UsesTagTest.php new file mode 100644 index 0000000..45868d7 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/UsesTagTest.php @@ -0,0 +1,86 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\UsesTag + * + * @author Daniel O'Connor + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class UsesTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\UsesTag can create + * a link for the @uses doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exReference + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\UsesTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exReference + ) { + $tag = new UsesTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exReference, $tag->getReference()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exReference + return array( + array( + 'uses', + 'Foo::bar()', + 'Foo::bar()', + '', + 'Foo::bar()' + ), + array( + 'uses', + 'Foo::bar() Testing', + 'Foo::bar() Testing', + 'Testing', + 'Foo::bar()', + ), + array( + 'uses', + 'Foo::bar() Testing comments', + 'Foo::bar() Testing comments', + 'Testing comments', + 'Foo::bar()', + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VarTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VarTagTest.php new file mode 100644 index 0000000..9ae2aa5 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VarTagTest.php @@ -0,0 +1,94 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\VarTag + * + * @author Daniel O'Connor + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class VarTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\VarTag can + * understand the @var doc block. + * + * @param string $type + * @param string $content + * @param string $exType + * @param string $exVariable + * @param string $exDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\VarTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exType, + $exVariable, + $exDescription + ) { + $tag = new VarTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exType, $tag->getType()); + $this->assertEquals($exVariable, $tag->getVariableName()); + $this->assertEquals($exDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exType, $exVariable, $exDescription + return array( + array( + 'var', + 'int', + 'int', + '', + '' + ), + array( + 'var', + 'int $bob', + 'int', + '$bob', + '' + ), + array( + 'var', + 'int $bob Number of bobs', + 'int', + '$bob', + 'Number of bobs' + ), + array( + 'var', + '', + '', + '', + '' + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VersionTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VersionTagTest.php new file mode 100644 index 0000000..e145386 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VersionTagTest.php @@ -0,0 +1,115 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\VersionTag + * + * @author Vasil Rangelov + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class VersionTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\LinkTag can create + * a link for the @version doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exDescription + * @param string $exVersion + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\VersionTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exVersion + ) { + $tag = new VersionTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exVersion, $tag->getVersion()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exVersion + return array( + array( + 'version', + '1.0 First release.', + '1.0 First release.', + 'First release.', + '1.0' + ), + array( + 'version', + "1.0\nFirst release.", + "1.0\nFirst release.", + 'First release.', + '1.0' + ), + array( + 'version', + "1.0\nFirst\nrelease.", + "1.0\nFirst\nrelease.", + "First\nrelease.", + '1.0' + ), + array( + 'version', + 'Unfinished release', + 'Unfinished release', + 'Unfinished release', + '' + ), + array( + 'version', + '1.0', + '1.0', + '', + '1.0' + ), + array( + 'version', + 'GIT: $Id$', + 'GIT: $Id$', + '', + 'GIT: $Id$' + ), + array( + 'version', + 'GIT: $Id$ Dev build', + 'GIT: $Id$ Dev build', + 'Dev build', + 'GIT: $Id$' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/TagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/TagTest.php new file mode 100644 index 0000000..9e873ec --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/TagTest.php @@ -0,0 +1,313 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock; + +use phpDocumentor\Reflection\DocBlock; +use phpDocumentor\Reflection\DocBlock\Context; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\VarTag + * + * @author Daniel O'Connor + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class TagTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @expectedException \InvalidArgumentException + * + * @return void + */ + public function testInvalidTagLine() + { + Tag::createInstance('Invalid tag line'); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * + * @return void + */ + public function testTagHandlerUnregistration() + { + $currentHandler = __NAMESPACE__ . '\Tag\VarTag'; + $tagPreUnreg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPreUnreg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreUnreg + ); + + Tag::registerTagHandler('var', null); + + $tagPostUnreg = Tag::createInstance('@var mixed'); + $this->assertNotInstanceOf( + $currentHandler, + $tagPostUnreg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostUnreg + ); + + Tag::registerTagHandler('var', $currentHandler); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * + * @return void + */ + public function testTagHandlerCorrectRegistration() + { + if (0 == ini_get('allow_url_include')) { + $this->markTestSkipped('"data" URIs for includes are required.'); + } + $currentHandler = __NAMESPACE__ . '\Tag\VarTag'; + $tagPreReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPreReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + + include 'data:text/plain;base64,'. base64_encode( +<<assertTrue(Tag::registerTagHandler('var', '\MyTagHandler')); + + $tagPostReg = Tag::createInstance('@var mixed'); + $this->assertNotInstanceOf( + $currentHandler, + $tagPostReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + $this->assertInstanceOf( + '\MyTagHandler', + $tagPostReg + ); + + $this->assertTrue(Tag::registerTagHandler('var', $currentHandler)); + } + + /** + * @depends testTagHandlerCorrectRegistration + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * @covers \phpDocumentor\Reflection\DocBlock\Tag::createInstance + * + * @return void + */ + public function testNamespacedTagHandlerCorrectRegistration() + { + $tagPreReg = Tag::createInstance('@T something'); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + $this->assertNotInstanceOf( + '\MyTagHandler', + $tagPreReg + ); + + $this->assertTrue( + Tag::registerTagHandler('\MyNamespace\MyTag', '\MyTagHandler') + ); + + $tagPostReg = Tag::createInstance( + '@T something', + new DocBlock( + '', + new Context('', array('T' => '\MyNamespace\MyTag')) + ) + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + $this->assertInstanceOf( + '\MyTagHandler', + $tagPostReg + ); + + $this->assertTrue( + Tag::registerTagHandler('\MyNamespace\MyTag', null) + ); + } + + /** + * @depends testTagHandlerCorrectRegistration + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * @covers \phpDocumentor\Reflection\DocBlock\Tag::createInstance + * + * @return void + */ + public function testNamespacedTagHandlerIncorrectRegistration() + { + $tagPreReg = Tag::createInstance('@T something'); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + $this->assertNotInstanceOf( + '\MyTagHandler', + $tagPreReg + ); + + $this->assertFalse( + Tag::registerTagHandler('MyNamespace\MyTag', '\MyTagHandler') + ); + + $tagPostReg = Tag::createInstance( + '@T something', + new DocBlock( + '', + new Context('', array('T' => '\MyNamespace\MyTag')) + ) + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + $this->assertNotInstanceOf( + '\MyTagHandler', + $tagPostReg + ); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * + * @return void + */ + public function testNonExistentTagHandlerRegistration() + { + $currentHandler = __NAMESPACE__ . '\Tag\VarTag'; + $tagPreReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPreReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + + $this->assertFalse(Tag::registerTagHandler('var', 'Non existent')); + + $tagPostReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPostReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * + * @return void + */ + public function testIncompatibleTagHandlerRegistration() + { + $currentHandler = __NAMESPACE__ . '\Tag\VarTag'; + $tagPreReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPreReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + + $this->assertFalse( + Tag::registerTagHandler('var', __NAMESPACE__ . '\TagTest') + ); + + $tagPostReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPostReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + } + + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\VarTag can + * understand the @var doc block. + * + * @param string $type + * @param string $content + * @param string $exDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exDescription + ) { + $tag = new Tag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($content, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exDescription + return array( + array( + 'unknown', + 'some content', + 'some content', + ), + array( + 'unknown', + '', + '', + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Type/CollectionTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Type/CollectionTest.php new file mode 100644 index 0000000..78c7306 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Type/CollectionTest.php @@ -0,0 +1,195 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Type; + +use phpDocumentor\Reflection\DocBlock\Context; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Type\Collection + * + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection + * + * @author Mike van Riel + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class CollectionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::__construct + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::getContext + * + * @return void + */ + public function testConstruct() + { + $collection = new Collection(); + $this->assertCount(0, $collection); + $this->assertEquals('', $collection->getContext()->getNamespace()); + $this->assertCount(0, $collection->getContext()->getNamespaceAliases()); + } + + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::__construct + * + * @return void + */ + public function testConstructWithTypes() + { + $collection = new Collection(array('integer', 'string')); + $this->assertCount(2, $collection); + } + + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::__construct + * + * @return void + */ + public function testConstructWithNamespace() + { + $collection = new Collection(array(), new Context('\My\Space')); + $this->assertEquals('My\Space', $collection->getContext()->getNamespace()); + + $collection = new Collection(array(), new Context('My\Space')); + $this->assertEquals('My\Space', $collection->getContext()->getNamespace()); + + $collection = new Collection(array(), null); + $this->assertEquals('', $collection->getContext()->getNamespace()); + } + + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::__construct + * + * @return void + */ + public function testConstructWithNamespaceAliases() + { + $fixture = array('a' => 'b'); + $collection = new Collection(array(), new Context(null, $fixture)); + $this->assertEquals( + array('a' => '\b'), + $collection->getContext()->getNamespaceAliases() + ); + } + + /** + * @param string $fixture + * @param array $expected + * + * @dataProvider provideTypesToExpand + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::add + * + * @return void + */ + public function testAdd($fixture, $expected) + { + $collection = new Collection( + array(), + new Context('\My\Space', array('Alias' => '\My\Space\Aliasing')) + ); + $collection->add($fixture); + + $this->assertSame($expected, $collection->getArrayCopy()); + } + + /** + * @param string $fixture + * @param array $expected + * + * @dataProvider provideTypesToExpandWithoutNamespace + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::add + * + * @return void + */ + public function testAddWithoutNamespace($fixture, $expected) + { + $collection = new Collection( + array(), + new Context(null, array('Alias' => '\My\Space\Aliasing')) + ); + $collection->add($fixture); + + $this->assertSame($expected, $collection->getArrayCopy()); + } + + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::add + * @expectedException InvalidArgumentException + * + * @return void + */ + public function testAddWithInvalidArgument() + { + $collection = new Collection(); + $collection->add(array()); + } + + /** + * Returns the types and their expected values to test the retrieval of + * types. + * + * @param string $method Name of the method consuming this data provider. + * @param string $namespace Name of the namespace to user as basis. + * + * @return string[] + */ + public function provideTypesToExpand($method, $namespace = '\My\Space\\') + { + return array( + array('', array()), + array(' ', array()), + array('int', array('int')), + array('int ', array('int')), + array('string', array('string')), + array('DocBlock', array($namespace.'DocBlock')), + array('DocBlock[]', array($namespace.'DocBlock[]')), + array(' DocBlock ', array($namespace.'DocBlock')), + array('\My\Space\DocBlock', array('\My\Space\DocBlock')), + array('Alias\DocBlock', array('\My\Space\Aliasing\DocBlock')), + array( + 'DocBlock|Tag', + array($namespace .'DocBlock', $namespace .'Tag') + ), + array( + 'DocBlock|null', + array($namespace.'DocBlock', 'null') + ), + array( + '\My\Space\DocBlock|Tag', + array('\My\Space\DocBlock', $namespace.'Tag') + ), + array( + 'DocBlock[]|null', + array($namespace.'DocBlock[]', 'null') + ), + array( + 'DocBlock[]|int[]', + array($namespace.'DocBlock[]', 'int[]') + ), + ); + } + + /** + * Returns the types and their expected values to test the retrieval of + * types when no namespace is available. + * + * @param string $method Name of the method consuming this data provider. + * + * @return string[] + */ + public function provideTypesToExpandWithoutNamespace($method) + { + return $this->provideTypesToExpand($method, '\\'); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlockTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlockTest.php new file mode 100644 index 0000000..30eedfc --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlockTest.php @@ -0,0 +1,337 @@ + + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection; + +use phpDocumentor\Reflection\DocBlock\Context; +use phpDocumentor\Reflection\DocBlock\Location; +use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag; + +/** + * Test class for phpDocumentor\Reflection\DocBlock + * + * @author Mike van Riel + * @copyright 2010-2011 Mike van Riel / Naenius. (http://www.naenius.com) + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ +class DocBlockTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers \phpDocumentor\Reflection\DocBlock + * + * @return void + */ + public function testConstruct() + { + $fixture = << '\phpDocumentor')), + new Location(2) + ); + $this->assertEquals( + 'This is a short description', + $object->getShortDescription() + ); + $this->assertEquals( + 'This is a long description', + $object->getLongDescription()->getContents() + ); + $this->assertCount(2, $object->getTags()); + $this->assertTrue($object->hasTag('see')); + $this->assertTrue($object->hasTag('return')); + $this->assertFalse($object->hasTag('category')); + + $this->assertSame('MyNamespace', $object->getContext()->getNamespace()); + $this->assertSame( + array('PHPDoc' => '\phpDocumentor'), + $object->getContext()->getNamespaceAliases() + ); + $this->assertSame(2, $object->getLocation()->getLineNumber()); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::splitDocBlock + * + * @return void + */ + public function testConstructWithTagsOnly() + { + $fixture = <<assertEquals('', $object->getShortDescription()); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertCount(2, $object->getTags()); + $this->assertTrue($object->hasTag('see')); + $this->assertTrue($object->hasTag('return')); + $this->assertFalse($object->hasTag('category')); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::isTemplateStart + */ + public function testIfStartOfTemplateIsDiscovered() + { + $fixture = <<assertEquals('', $object->getShortDescription()); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertCount(2, $object->getTags()); + $this->assertTrue($object->hasTag('see')); + $this->assertTrue($object->hasTag('return')); + $this->assertFalse($object->hasTag('category')); + $this->assertTrue($object->isTemplateStart()); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::isTemplateEnd + */ + public function testIfEndOfTemplateIsDiscovered() + { + $fixture = <<assertEquals('', $object->getShortDescription()); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertTrue($object->isTemplateEnd()); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::cleanInput + * + * @return void + */ + public function testConstructOneLiner() + { + $fixture = '/** Short description and nothing more. */'; + $object = new DocBlock($fixture); + $this->assertEquals( + 'Short description and nothing more.', + $object->getShortDescription() + ); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertCount(0, $object->getTags()); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::__construct + * + * @return void + */ + public function testConstructFromReflector() + { + $object = new DocBlock(new \ReflectionClass($this)); + $this->assertEquals( + 'Test class for phpDocumentor\Reflection\DocBlock', + $object->getShortDescription() + ); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertCount(4, $object->getTags()); + $this->assertTrue($object->hasTag('author')); + $this->assertTrue($object->hasTag('copyright')); + $this->assertTrue($object->hasTag('license')); + $this->assertTrue($object->hasTag('link')); + $this->assertFalse($object->hasTag('category')); + } + + /** + * @expectedException \InvalidArgumentException + * + * @return void + */ + public function testExceptionOnInvalidObject() + { + new DocBlock($this); + } + + public function testDotSeperation() + { + $fixture = <<assertEquals( + 'This is a short description.', + $object->getShortDescription() + ); + $this->assertEquals( + "This is a long description.\nThis is a continuation of the long " + ."description.", + $object->getLongDescription()->getContents() + ); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::parseTags + * @expectedException \LogicException + * + * @return void + */ + public function testInvalidTagBlock() + { + if (0 == ini_get('allow_url_include')) { + $this->markTestSkipped('"data" URIs for includes are required.'); + } + + include 'data:text/plain;base64,'. base64_encode( + <<assertEquals( + 'This is a short description.', + $object->getShortDescription() + ); + $this->assertEquals( + 'This is a long description.', + $object->getLongDescription()->getContents() + ); + $tags = $object->getTags(); + $this->assertCount(2, $tags); + $this->assertTrue($object->hasTag('method')); + $this->assertTrue($object->hasTag('Method')); + $this->assertInstanceOf( + __NAMESPACE__ . '\DocBlock\Tag\MethodTag', + $tags[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\DocBlock\Tag', + $tags[1] + ); + $this->assertNotInstanceOf( + __NAMESPACE__ . '\DocBlock\Tag\MethodTag', + $tags[1] + ); + } + + /** + * @depends testConstructFromReflector + * @covers \phpDocumentor\Reflection\DocBlock::getTagsByName + * + * @return void + */ + public function testGetTagsByNameZeroAndOneMatch() + { + $object = new DocBlock(new \ReflectionClass($this)); + $this->assertEmpty($object->getTagsByName('category')); + $this->assertCount(1, $object->getTagsByName('author')); + } + + /** + * @depends testConstructWithTagsOnly + * @covers \phpDocumentor\Reflection\DocBlock::parseTags + * + * @return void + */ + public function testParseMultilineTag() + { + $fixture = <<assertCount(1, $object->getTags()); + } + + /** + * @depends testConstructWithTagsOnly + * @covers \phpDocumentor\Reflection\DocBlock::parseTags + * + * @return void + */ + public function testParseMultilineTagWithLineBreaks() + { + $fixture = <<assertCount(1, $tags = $object->getTags()); + /** @var ReturnTag $tag */ + $tag = reset($tags); + $this->assertEquals("Content on\n multiple lines.\n\n One more, after the break.", $tag->getDescription()); + } + + /** + * @depends testConstructWithTagsOnly + * @covers \phpDocumentor\Reflection\DocBlock::getTagsByName + * + * @return void + */ + public function testGetTagsByNameMultipleMatch() + { + $fixture = <<assertEmpty($object->getTagsByName('category')); + $this->assertCount(1, $object->getTagsByName('return')); + $this->assertCount(2, $object->getTagsByName('param')); + } +} diff --git a/vendor/phpspec/prophecy/.gitignore b/vendor/phpspec/prophecy/.gitignore new file mode 100644 index 0000000..c50c8c4 --- /dev/null +++ b/vendor/phpspec/prophecy/.gitignore @@ -0,0 +1,4 @@ +*.tgz +*.phar +bin +vendor diff --git a/vendor/phpspec/prophecy/.travis.yml b/vendor/phpspec/prophecy/.travis.yml new file mode 100644 index 0000000..004e612 --- /dev/null +++ b/vendor/phpspec/prophecy/.travis.yml @@ -0,0 +1,19 @@ +language: php + +php: [5.3, 5.4, 5.5, 5.6, 7, hhvm] + +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +branches: + except: + - /^bugfix\/.*$/ + - /^feature\/.*$/ + - /^optimization\/.*$/ + +before_script: travis_retry composer install --no-interaction + +script: vendor/bin/phpspec run -fpretty -v diff --git a/vendor/phpspec/prophecy/CHANGES.md b/vendor/phpspec/prophecy/CHANGES.md new file mode 100644 index 0000000..c293f0d --- /dev/null +++ b/vendor/phpspec/prophecy/CHANGES.md @@ -0,0 +1,122 @@ +1.5.0 / 2015-04-27 +================== + + * Add support for PHP7 scalar type hints (thanks @trowski) + * Add support for PHP7 return types (thanks @trowski) + * Update internal test suite to support PHP7 + +1.4.1 / 2015-04-27 +================== + + * Fixed bug in closure-based argument tokens (#181) + +1.4.0 / 2015-03-27 +================== + + * Fixed errors in return type phpdocs (thanks @sobit) + * Fixed stringifying of hash containing one value (thanks @avant1) + * Improved clarity of method call expectation exception (thanks @dantleech) + * Add ability to specify which argument is returned in willReturnArgument (thanks @coderbyheart) + * Add more information to MethodNotFound exceptions (thanks @ciaranmcnulty) + * Support for mocking classes with methods that return references (thanks @edsonmedina) + * Improved object comparison (thanks @whatthejeff) + * Adopted '^' in composer dependencies (thanks @GrahamCampbell) + * Fixed non-typehinted arguments being treated as optional (thanks @whatthejeff) + * Magic methods are now filtered for keywords (thanks @seagoj) + * More readable errors for failure when expecting single calls (thanks @dantleech) + +1.3.1 / 2014-11-17 +================== + + * Fix the edge case when failed predictions weren't recorded for `getCheckedPredictions()` + +1.3.0 / 2014-11-14 +================== + + * Add a way to get checked predictions with `MethodProphecy::getCheckedPredictions()` + * Fix HHVM compatibility + * Remove dead code (thanks @stof) + * Add support for DirectoryIterators (thanks @shanethehat) + +1.2.0 / 2014-07-18 +================== + + * Added support for doubling magic methods documented in the class phpdoc (thanks @armetiz) + * Fixed a segfault appearing in some cases (thanks @dmoreaulf) + * Fixed the doubling of methods with typehints on non-existent classes (thanks @gquemener) + * Added support for internal classes using keywords as method names (thanks @milan) + * Added IdenticalValueToken and Argument::is (thanks @florianv) + * Removed the usage of scalar typehints in HHVM as HHVM 3 does not support them anymore in PHP code (thanks @whatthejeff) + +1.1.2 / 2014-01-24 +================== + + * Spy automatically promotes spied method call to an expected one + +1.1.1 / 2014-01-15 +================== + + * Added support for HHVM + +1.1.0 / 2014-01-01 +================== + + * Changed the generated class names to use a static counter instead of a random number + * Added a clss patch for ReflectionClass::newInstance to make its argument optional consistently (thanks @docteurklein) + * Fixed mirroring of classes with typehints on non-existent classes (thanks @docteurklein) + * Fixed the support of array callables in CallbackPromise and CallbackPrediction (thanks @ciaranmcnulty) + * Added support for properties in ObjectStateToken (thanks @adrienbrault) + * Added support for mocking classes with a final constructor (thanks @ciaranmcnulty) + * Added ArrayEveryEntryToken and Argument::withEveryEntry() (thanks @adrienbrault) + * Added an exception when trying to prophesize on a final method instead of ignoring silently (thanks @docteurklein) + * Added StringContainToken and Argument::containingString() (thanks @peterjmit) + * Added ``shouldNotHaveBeenCalled`` on the MethodProphecy (thanks @ciaranmcnulty) + * Fixed the comparison of objects in ExactValuetoken (thanks @sstok) + * Deprecated ``shouldNotBeenCalled`` in favor of ``shouldNotHaveBeenCalled`` + +1.0.4 / 2013-08-10 +================== + + * Better randomness for generated class names (thanks @sstok) + * Add support for interfaces into TypeToken and Argument::type() (thanks @sstok) + * Add support for old-style (method name === class name) constructors (thanks @l310 for report) + +1.0.3 / 2013-07-04 +================== + + * Support callable typehints (thanks @stof) + * Do not attempt to autoload arrays when generating code (thanks @MarcoDeBortoli) + * New ArrayEntryToken (thanks @kagux) + +1.0.2 / 2013-05-19 +================== + + * Logical `AND` token added (thanks @kagux) + * Logical `NOT` token added (thanks @kagux) + * Add support for setting custom constructor arguments + * Properly stringify hashes + * Record calls that throw exceptions + * Migrate spec suite to PhpSpec 2.0 + +1.0.1 / 2013-04-30 +================== + + * Fix broken UnexpectedCallException message + * Trim AggregateException message + +1.0.0 / 2013-04-29 +================== + + * Improve exception messages + +1.0.0-BETA2 / 2013-04-03 +======================== + + * Add more debug information to CallTimes and Call prediction exception messages + * Fix MethodNotFoundException wrong namespace (thanks @gunnarlium) + * Fix some typos in the exception messages (thanks @pborreli) + +1.0.0-BETA1 / 2013-03-25 +======================== + + * Initial release diff --git a/vendor/phpspec/prophecy/CONTRIBUTING.md b/vendor/phpspec/prophecy/CONTRIBUTING.md new file mode 100644 index 0000000..3674aac --- /dev/null +++ b/vendor/phpspec/prophecy/CONTRIBUTING.md @@ -0,0 +1,21 @@ +Contributing +------------ + +Prophecy is an open source, community-driven project. If you'd like to contribute, +feel free to do this, but remember to follow this few simple rules: + +- Make your feature addition or bug fix, +- Add either specs or examples for any changes you're making (bugfixes or additions) + (please look into `spec/` folder for some examples). This is important so we don't break + it in a future version unintentionally, +- Commit your code, but do not mess with `CHANGES.md`, + +Running tests +------------- + +Make sure that you don't break anything with your changes by running: + +```bash +$> composer install --dev --prefer-dist +$> vendor/bin/phpspec run +``` diff --git a/vendor/phpspec/prophecy/LICENSE b/vendor/phpspec/prophecy/LICENSE new file mode 100644 index 0000000..c8b3647 --- /dev/null +++ b/vendor/phpspec/prophecy/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2013 Konstantin Kudryashov + Marcello Duarte + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/phpspec/prophecy/README.md b/vendor/phpspec/prophecy/README.md new file mode 100644 index 0000000..17e57c3 --- /dev/null +++ b/vendor/phpspec/prophecy/README.md @@ -0,0 +1,390 @@ +# Prophecy + +[![Build Status](https://travis-ci.org/phpspec/prophecy.svg?branch=master)](https://travis-ci.org/phpspec/prophecy) + +Prophecy is a highly opinionated yet very powerful and flexible PHP object mocking +framework. Though initially it was created to fulfil phpspec2 needs, it is flexible +enough to be used inside any testing framework out there with minimal effort. + +## A simple example + +```php +prophet->prophesize('App\Security\Hasher'); + $user = new App\Entity\User($hasher->reveal()); + + $hasher->generateHash($user, 'qwerty')->willReturn('hashed_pass'); + + $user->setPassword('qwerty'); + + $this->assertEquals('hashed_pass', $user->getPassword()); + } + + protected function setup() + { + $this->prophet = new \Prophecy\Prophet; + } + + protected function tearDown() + { + $this->prophet->checkPredictions(); + } +} +``` + +## Installation + +### Prerequisites + +Prophecy requires PHP 5.3.3 or greater. + +### Setup through composer + +First, add Prophecy to the list of dependencies inside your `composer.json`: + +```json +{ + "require-dev": { + "phpspec/prophecy": "~1.0" + } +} +``` + +Then simply install it with composer: + +```bash +$> composer install --prefer-dist +``` + +You can read more about Composer on its [official webpage](http://getcomposer.org). + +## How to use it + +First of all, in Prophecy every word has a logical meaning, even the name of the library +itself (Prophecy). When you start feeling that, you'll become very fluid with this +tool. + +For example, Prophecy has been named that way because it concentrates on describing the future +behavior of objects with very limited knowledge about them. But as with any other prophecy, +those object prophecies can't create themselves - there should be a Prophet: + +```php +$prophet = new Prophecy\Prophet; +``` + +The Prophet creates prophecies by *prophesizing* them: + +```php +$prophecy = $prophet->prophesize(); +``` + +The result of the `prophesize()` method call is a new object of class `ObjectProphecy`. Yes, +that's your specific object prophecy, which describes how your object would behave +in the near future. But first, you need to specify which object you're talking about, +right? + +```php +$prophecy->willExtend('stdClass'); +$prophecy->willImplement('SessionHandlerInterface'); +``` + +There are 2 interesting calls - `willExtend` and `willImplement`. The first one tells +object prophecy that our object should extend specific class, the second one says that +it should implement some interface. Obviously, objects in PHP can implement multiple +interfaces, but extend only one parent class. + +### Dummies + +Ok, now we have our object prophecy. What can we do with it? First of all, we can get +our object *dummy* by revealing its prophecy: + +```php +$dummy = $prophecy->reveal(); +``` + +The `$dummy` variable now holds a special dummy object. Dummy objects are objects that extend +and/or implement preset classes/interfaces by overriding all their public methods. The key +point about dummies is that they do not hold any logic - they just do nothing. Any method +of the dummy will always return `null` and the dummy will never throw any exceptions. +Dummy is your friend if you don't care about the actual behavior of this double and just need +a token object to satisfy a method typehint. + +You need to understand one thing - a dummy is not a prophecy. Your object prophecy is still +assigned to `$prophecy` variable and in order to manipulate with your expectations, you +should work with it. `$dummy` is a dummy - a simple php object that tries to fulfil your +prophecy. + +### Stubs + +Ok, now we know how to create basic prophecies and reveal dummies from them. That's +awesome if we don't care about our _doubles_ (objects that reflect originals) +interactions. If we do, we need to use *stubs* or *mocks*. + +A stub is an object double, which doesn't have any expectations about the object behavior, +but when put in specific environment, behaves in specific way. Ok, I know, it's cryptic, +but bear with me for a minute. Simply put, a stub is a dummy, which depending on the called +method signature does different things (has logic). To create stubs in Prophecy: + +```php +$prophecy->read('123')->willReturn('value'); +``` + +Oh wow. We've just made an arbitrary call on the object prophecy? Yes, we did. And this +call returned us a new object instance of class `MethodProphecy`. Yep, that's a specific +method with arguments prophecy. Method prophecies give you the ability to create method +promises or predictions. We'll talk about method predictions later in the _Mocks_ section. + +#### Promises + +Promises are logical blocks, that represent your fictional methods in prophecy terms +and they are handled by the `MethodProphecy::will(PromiseInterface $promise)` method. +As a matter of fact, the call that we made earlier (`willReturn('value')`) is a simple +shortcut to: + +```php +$prophecy->read('123')->will(new Prophecy\Promise\ReturnPromise(array('value'))); +``` + +This promise will cause any call to our double's `read()` method with exactly one +argument - `'123'` to always return `'value'`. But that's only for this +promise, there's plenty others you can use: + +- `ReturnPromise` or `->willReturn(1)` - returns a value from a method call +- `ReturnArgumentPromise` or `->willReturnArgument($index)` - returns the nth method argument from call +- `ThrowPromise` or `->willThrow` - causes the method to throw specific exception +- `CallbackPromise` or `->will($callback)` - gives you a quick way to define your own custom logic + +Keep in mind, that you can always add even more promises by implementing +`Prophecy\Promise\PromiseInterface`. + +#### Method prophecies idempotency + +Prophecy enforces same method prophecies and, as a consequence, same promises and +predictions for the same method calls with the same arguments. This means: + +```php +$methodProphecy1 = $prophecy->read('123'); +$methodProphecy2 = $prophecy->read('123'); +$methodProphecy3 = $prophecy->read('321'); + +$methodProphecy1 === $methodProphecy2; +$methodProphecy1 !== $methodProphecy3; +``` + +That's interesting, right? Now you might ask me how would you define more complex +behaviors where some method call changes behavior of others. In PHPUnit or Mockery +you do that by predicting how many times your method will be called. In Prophecy, +you'll use promises for that: + +```php +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName('everzet')->will(function () { + $this->getName()->willReturn('everzet'); +}); + +// For PHP 5.3 +$user->setName('everzet')->will(function ($args, $user) { + $user->getName()->willReturn('everzet'); +}); + +// Or +$user->setName('everzet')->will(function ($args) use ($user) { + $user->getName()->willReturn('everzet'); +}); +``` + +And now it doesn't matter how many times or in which order your methods are called. +What matters is their behaviors and how well you faked it. + +#### Arguments wildcarding + +The previous example is awesome (at least I hope it is for you), but that's not +optimal enough. We hardcoded `'everzet'` in our expectation. Isn't there a better +way? In fact there is, but it involves understanding what this `'everzet'` +actually is. + +You see, even if method arguments used during method prophecy creation look +like simple method arguments, in reality they are not. They are argument token +wildcards. As a matter of fact, `->setName('everzet')` looks like a simple call just +because Prophecy automatically transforms it under the hood into: + +```php +$user->setName(new Prophecy\Argument\Token\ExactValueToken('everzet')); +``` + +Those argument tokens are simple PHP classes, that implement +`Prophecy\Argument\Token\TokenInterface` and tell Prophecy how to compare real arguments +with your expectations. And yes, those classnames are damn big. That's why there's a +shortcut class `Prophecy\Argument`, which you can use to create tokens like that: + +```php +use Prophecy\Argument; + +$user->setName(Argument::exact('everzet')); +``` + +`ExactValueToken` is not very useful in our case as it forced us to hardcode the username. +That's why Prophecy comes bundled with a bunch of other tokens: + +- `IdenticalValueToken` or `Argument::is($value)` - checks that the argument is identical to a specific value +- `ExactValueToken` or `Argument::exact($value)` - checks that the argument matches a specific value +- `TypeToken` or `Argument::type($typeOrClass)` - checks that the argument matches a specific type or + classname +- `ObjectStateToken` or `Argument::which($method, $value)` - checks that the argument method returns + a specific value +- `CallbackToken` or `Argument::that(callback)` - checks that the argument matches a custom callback +- `AnyValueToken` or `Argument::any()` - matches any argument +- `AnyValuesToken` or `Argument::cetera()` - matches any arguments to the rest of the signature +- `StringContainsToken` or `Argument::containingString($value)` - checks that the argument contains a specific string value + +And you can add even more by implementing `TokenInterface` with your own custom classes. + +So, let's refactor our initial `{set,get}Name()` logic with argument tokens: + +```php +use Prophecy\Argument; + +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName(Argument::type('string'))->will(function ($args) { + $this->getName()->willReturn($args[0]); +}); + +// For PHP 5.3 +$user->setName(Argument::type('string'))->will(function ($args, $user) { + $user->getName()->willReturn($args[0]); +}); + +// Or +$user->setName(Argument::type('string'))->will(function ($args) use ($user) { + $user->getName()->willReturn($args[0]); +}); +``` + +That's it. Now our `{set,get}Name()` prophecy will work with any string argument provided to it. +We've just described how our stub object should behave, even though the original object could have +no behavior whatsoever. + +One last bit about arguments now. You might ask, what happens in case of: + +```php +use Prophecy\Argument; + +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName(Argument::type('string'))->will(function ($args) { + $this->getName()->willReturn($args[0]); +}); + +// For PHP 5.3 +$user->setName(Argument::type('string'))->will(function ($args, $user) { + $user->getName()->willReturn($args[0]); +}); + +// Or +$user->setName(Argument::type('string'))->will(function ($args) use ($user) { + $user->getName()->willReturn($args[0]); +}); + +$user->setName(Argument::any())->will(function () { +}); +``` + +Nothing. Your stub will continue behaving the way it did before. That's because of how +arguments wildcarding works. Every argument token type has a different score level, which +wildcard then uses to calculate the final arguments match score and use the method prophecy +promise that has the highest score. In this case, `Argument::type()` in case of success +scores `5` and `Argument::any()` scores `3`. So the type token wins, as does the first +`setName()` method prophecy and its promise. The simple rule of thumb - more precise token +always wins. + +#### Getting stub objects + +Ok, now we know how to define our prophecy method promises, let's get our stub from +it: + +```php +$stub = $prophecy->reveal(); +``` + +As you might see, the only difference between how we get dummies and stubs is that with +stubs we describe every object conversation instead of just agreeing with `null` returns +(object being *dummy*). As a matter of fact, after you define your first promise +(method call), Prophecy will force you to define all the communications - it throws +the `UnexpectedCallException` for any call you didn't describe with object prophecy before +calling it on a stub. + +### Mocks + +Now we know how to define doubles without behavior (dummies) and doubles with behavior, but +no expectations (stubs). What's left is doubles for which we have some expectations. These +are called mocks and in Prophecy they look almost exactly the same as stubs, except that +they define *predictions* instead of *promises* on method prophecies: + +```php +$entityManager->flush()->shouldBeCalled(); +``` + +#### Predictions + +The `shouldBeCalled()` method here assigns `CallPrediction` to our method prophecy. +Predictions are a delayed behavior check for your prophecies. You see, during the entire lifetime +of your doubles, Prophecy records every single call you're making against it inside your +code. After that, Prophecy can use this collected information to check if it matches defined +predictions. You can assign predictions to method prophecies using the +`MethodProphecy::should(PredictionInterface $prediction)` method. As a matter of fact, +the `shouldBeCalled()` method we used earlier is just a shortcut to: + +```php +$entityManager->flush()->should(new Prophecy\Prediction\CallPrediction()); +``` + +It checks if your method of interest (that matches both the method name and the arguments wildcard) +was called 1 or more times. If the prediction failed then it throws an exception. When does this +check happen? Whenever you call `checkPredictions()` on the main Prophet object: + +```php +$prophet->checkPredictions(); +``` + +In PHPUnit, you would want to put this call into the `tearDown()` method. If no predictions +are defined, it would do nothing. So it won't harm to call it after every test. + +There are plenty more predictions you can play with: + +- `CallPrediction` or `shouldBeCalled()` - checks that the method has been called 1 or more times +- `NoCallsPrediction` or `shouldNotBeCalled()` - checks that the method has not been called +- `CallTimesPrediction` or `shouldBeCalledTimes($count)` - checks that the method has been called + `$count` times +- `CallbackPrediction` or `should($callback)` - checks the method against your own custom callback + +Of course, you can always create your own custom prediction any time by implementing +`PredictionInterface`. + +### Spies + +The last bit of awesomeness in Prophecy is out-of-the-box spies support. As I said in the previous +section, Prophecy records every call made during the double's entire lifetime. This means +you don't need to record predictions in order to check them. You can also do it +manually by using the `MethodProphecy::shouldHave(PredictionInterface $prediction)` method: + +```php +$em = $prophet->prophesize('Doctrine\ORM\EntityManager'); + +$controller->createUser($em->reveal()); + +$em->flush()->shouldHaveBeenCalled(); +``` + +Such manipulation with doubles is called spying. And with Prophecy it just works. diff --git a/vendor/phpspec/prophecy/composer.json b/vendor/phpspec/prophecy/composer.json new file mode 100644 index 0000000..654aaad --- /dev/null +++ b/vendor/phpspec/prophecy/composer.json @@ -0,0 +1,40 @@ +{ + "name": "phpspec/prophecy", + "description": "Highly opinionated mocking framework for PHP 5.3+", + "keywords": ["Mock", "Stub", "Dummy", "Double", "Fake", "Spy"], + "homepage": "https://github.com/phpspec/prophecy", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "require": { + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1", + "doctrine/instantiator": "^1.0.2" + }, + + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + } +} diff --git a/vendor/phpspec/prophecy/composer.lock b/vendor/phpspec/prophecy/composer.lock new file mode 100644 index 0000000..0c5521a --- /dev/null +++ b/vendor/phpspec/prophecy/composer.lock @@ -0,0 +1,731 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "642fa332c5fa99e1d5086035641b5a74", + "packages": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03 12:10:50" + }, + { + "name": "sebastian/comparator", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-07-26 15:48:44" + }, + { + "name": "sebastian/diff", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", + "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-02-22 15:13:53" + }, + { + "name": "sebastian/exporter", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "7ae5513327cb536431847bcc0c10edba2701064e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", + "reference": "7ae5513327cb536431847bcc0c10edba2701064e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2015-06-21 07:55:53" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", + "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-06-21 08:04:50" + } + ], + "packages-dev": [ + { + "name": "phpspec/php-diff", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/phpspec/php-diff.git", + "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a", + "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Diff": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Chris Boulton", + "homepage": "http://github.com/chrisboulton", + "role": "Original developer" + } + ], + "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", + "time": "2013-11-01 13:02:21" + }, + { + "name": "phpspec/phpspec", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/phpspec.git", + "reference": "e9a40577323e67f1de2e214abf32976a0352d8f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/phpspec/zipball/e9a40577323e67f1de2e214abf32976a0352d8f8", + "reference": "e9a40577323e67f1de2e214abf32976a0352d8f8", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.1", + "php": ">=5.3.3", + "phpspec/php-diff": "~1.0.0", + "phpspec/prophecy": "~1.4", + "sebastian/exporter": "~1.0", + "symfony/console": "~2.3", + "symfony/event-dispatcher": "~2.1", + "symfony/finder": "~2.1", + "symfony/process": "~2.1", + "symfony/yaml": "~2.1" + }, + "require-dev": { + "behat/behat": "^3.0.11", + "bossa/phpspec2-expect": "~1.0", + "phpunit/phpunit": "~4.4", + "symfony/filesystem": "~2.1", + "symfony/process": "~2.1" + }, + "suggest": { + "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters" + }, + "bin": [ + "bin/phpspec" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "PhpSpec": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "homepage": "http://marcelloduarte.net/" + } + ], + "description": "Specification-oriented BDD framework for PHP 5.3+", + "homepage": "http://phpspec.net/", + "keywords": [ + "BDD", + "SpecBDD", + "TDD", + "spec", + "specification", + "testing", + "tests" + ], + "time": "2015-05-30 15:21:40" + }, + { + "name": "symfony/console", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e", + "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2015-07-28 15:18:12" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/9310b5f9a87ec2ea75d20fec0b0017c77c66dac3", + "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.6", + "symfony/expression-language": "~2.6", + "symfony/phpunit-bridge": "~2.7", + "symfony/stopwatch": "~2.3" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2015-06-18 19:21:56" + }, + { + "name": "symfony/finder", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/ae0f363277485094edc04c9f3cbe595b183b78e4", + "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2015-07-09 16:07:40" + }, + { + "name": "symfony/process", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Process.git", + "reference": "48aeb0e48600321c272955132d7606ab0a49adb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Process/zipball/48aeb0e48600321c272955132d7606ab0a49adb3", + "reference": "48aeb0e48600321c272955132d7606ab0a49adb3", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2015-07-01 11:25:50" + }, + { + "name": "symfony/yaml", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "71340e996171474a53f3d29111d046be4ad8a0ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff", + "reference": "71340e996171474a53f3d29111d046be4ad8a0ff", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2015-07-28 14:07:07" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/ArgumentsWildcardSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/ArgumentsWildcardSpec.php new file mode 100644 index 0000000..5d6a2da --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/ArgumentsWildcardSpec.php @@ -0,0 +1,146 @@ +beConstructedWith(array(42, 'zet', $object)); + + $class = get_class($object->getWrappedObject()); + $hash = spl_object_hash($object->getWrappedObject()); + + $this->__toString()->shouldReturn("exact(42), exact(\"zet\"), exact($class:$hash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_generates_string_representation_from_all_tokens_imploded($token1, $token2, $token3) + { + $token1->__toString()->willReturn('token_1'); + $token2->__toString()->willReturn('token_2'); + $token3->__toString()->willReturn('token_3'); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->__toString()->shouldReturn('token_1, token_2, token_3'); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token + */ + function it_exposes_list_of_tokens($token) + { + $this->beConstructedWith(array($token)); + + $this->getTokens()->shouldReturn(array($token)); + } + + function it_returns_score_of_1_if_there_are_no_tokens_and_arguments() + { + $this->beConstructedWith(array()); + + $this->scoreArguments(array())->shouldReturn(1); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_should_return_match_score_based_on_all_tokens_score($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(18); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_returns_false_if_there_is_less_arguments_than_tokens($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument(null)->willReturn(false); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2))->shouldReturn(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_returns_false_if_there_is_less_tokens_than_arguments($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj, 4))->shouldReturn(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_should_return_false_if_one_of_the_tokens_returns_false($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(false); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_should_calculate_score_until_last_token($token1, $token2, $token3) + { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + + $token2->scoreArgument(2)->willReturn(7); + $token2->isLast()->willReturn(true); + + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(10); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php new file mode 100644 index 0000000..a43e923 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php @@ -0,0 +1,28 @@ +shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function its_string_representation_is_star() + { + $this->__toString()->shouldReturn('*'); + } + + function it_scores_any_argument_as_3() + { + $this->scoreArgument(42)->shouldReturn(3); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php new file mode 100644 index 0000000..c29076f --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php @@ -0,0 +1,28 @@ +shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_last() + { + $this->shouldBeLast(); + } + + function its_string_representation_is_star_with_followup() + { + $this->__toString()->shouldReturn('* [, ...]'); + } + + function it_scores_any_argument_as_2() + { + $this->scoreArgument(42)->shouldReturn(2); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php new file mode 100644 index 0000000..5d040d5 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php @@ -0,0 +1,64 @@ +beConstructedWith(2); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_6_if_argument_array_has_proper_count() + { + $this->scoreArgument(array(1,2))->shouldReturn(6); + } + + /** + * @param \Countable $countable + */ + function it_scores_6_if_argument_countable_object_has_proper_count($countable) + { + $countable->count()->willReturn(2); + $this->scoreArgument($countable)->shouldReturn(6); + } + + function it_does_not_score_if_argument_is_neither_array_nor_countable_object() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(5)->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_if_argument_array_has_wrong_count() + { + $this->scoreArgument(array(1))->shouldReturn(false); + } + + /** + * @param \Countable $countable + */ + function it_does_not_score_if_argument_countable_object_has_wrong_count($countable) + { + $countable->count()->willReturn(3); + $this->scoreArgument($countable)->shouldReturn(false); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldBe('count(2)'); + } + +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php new file mode 100644 index 0000000..8ff0f15 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php @@ -0,0 +1,229 @@ +beConstructedWith($key, $value); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_key_and_value($key, $value) + { + $this->getKey()->shouldBe($key); + $this->getValue()->shouldBe($value); + } + + function its_string_representation_tells_that_its_an_array_containing_the_key_value_pair($key, $value) + { + $key->__toString()->willReturn('key'); + $value->__toString()->willReturn('value'); + $this->__toString()->shouldBe('[..., key => value, ...]'); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $key + * @param \stdClass $object + */ + function it_wraps_non_token_value_into_ExactValueToken($key, $object) + { + $this->beConstructedWith($key, $object); + $this->getValue()->shouldHaveType('\Prophecy\Argument\Token\ExactValueToken'); + } + + /** + * @param \stdClass $object + * @param \Prophecy\Argument\Token\TokenInterface $value + */ + function it_wraps_non_token_key_into_ExactValueToken($object, $value) + { + $this->beConstructedWith($object, $value); + $this->getKey()->shouldHaveType('\Prophecy\Argument\Token\ExactValueToken'); + } + + function it_scores_array_half_of_combined_scores_from_key_and_value_tokens($key, $value) + { + $key->scoreArgument('key')->willReturn(4); + $value->scoreArgument('value')->willReturn(6); + $this->scoreArgument(array('key'=>'value'))->shouldBe(5); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \Iterator $object + */ + function it_scores_traversable_object_half_of_combined_scores_from_key_and_value_tokens($key, $value, $object) + { + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $key->scoreArgument('key')->willReturn(6); + $value->scoreArgument('value')->willReturn(2); + $this->scoreArgument($object)->shouldBe(4); + } + + /** + * @param \Prophecy\Argument\Token\AnyValuesToken $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \ArrayAccess $object + */ + function it_throws_exception_during_scoring_of_array_accessible_object_if_key_is_not_ExactValueToken($key, $value, $object) + { + $key->__toString()->willReturn('any_token'); + $this->beConstructedWith($key,$value); + $errorMessage = 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL. + 'But you used `any_token`.'; + $this->shouldThrow(new InvalidArgumentException($errorMessage))->duringScoreArgument($object); + } + + /** + * @param \Prophecy\Argument\Token\ExactValueToken $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \ArrayAccess $object + */ + function it_scores_array_accessible_object_half_of_combined_scores_from_key_and_value_tokens($key, $value, $object) + { + $object->offsetExists('key')->willReturn(true); + $object->offsetGet('key')->willReturn('value'); + $key->getValue()->willReturn('key'); + $key->scoreArgument('key')->willReturn(3); + $value->scoreArgument('value')->willReturn(1); + $this->scoreArgument($object)->shouldBe(2); + } + + /** + * @param \Prophecy\Argument\Token\AnyValuesToken $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \ArrayIterator $object + */ + function it_accepts_any_key_token_type_to_score_object_that_is_both_traversable_and_array_accessible($key, $value, $object) + { + $this->beConstructedWith($key, $value); + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $this->shouldNotThrow(new InvalidArgumentException)->duringScoreArgument($object); + } + + function it_does_not_score_if_argument_is_neither_array_nor_traversable_nor_array_accessible() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_empty_array() + { + $this->scoreArgument(array())->shouldBe(false); + } + + function it_does_not_score_array_if_key_and_value_tokens_do_not_score_same_entry($key, $value) + { + $argument = array(1 => 'foo', 2 => 'bar'); + $key->scoreArgument(1)->willReturn(true); + $key->scoreArgument(2)->willReturn(false); + $value->scoreArgument('foo')->willReturn(false); + $value->scoreArgument('bar')->willReturn(true); + $this->scoreArgument($argument)->shouldBe(false); + } + + /** + * @param \Iterator $object + */ + function it_does_not_score_traversable_object_without_entries($object) + { + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(false); + $this->scoreArgument($object)->shouldBe(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \Iterator $object + */ + function it_does_not_score_traversable_object_if_key_and_value_tokens_do_not_score_same_entry($key, $value, $object) + { + $object->current()->willReturn('foo'); + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'bar'; + }); + $object->key()->willReturn(1); + $object->key()->willReturn(2); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $key->scoreArgument(1)->willReturn(true); + $key->scoreArgument(2)->willReturn(false); + $value->scoreArgument('foo')->willReturn(false); + $value->scoreArgument('bar')->willReturn(true); + $this->scoreArgument($object)->shouldBe(false); + } + + /** + * @param \Prophecy\Argument\Token\ExactValueToken $key + * @param \ArrayAccess $object + */ + function it_does_not_score_array_accessible_object_if_it_has_no_offset_with_key_token_value($key, $object) + { + $object->offsetExists('key')->willReturn(false); + $key->getValue()->willReturn('key'); + $this->scoreArgument($object)->shouldBe(false); + } + + /** + * @param \Prophecy\Argument\Token\ExactValueToken $key + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \ArrayAccess $object + */ + function it_does_not_score_array_accessible_object_if_key_and_value_tokens_do_not_score_same_entry($key, $value, $object) + { + $object->offsetExists('key')->willReturn(true); + $object->offsetGet('key')->willReturn('value'); + $key->getValue()->willReturn('key'); + $value->scoreArgument('value')->willReturn(false); + $key->scoreArgument('key')->willReturn(true); + $this->scoreArgument($object)->shouldBe(false); + } + + function its_score_is_capped_at_8($key, $value) + { + $key->scoreArgument('key')->willReturn(10); + $value->scoreArgument('value')->willReturn(10); + $this->scoreArgument(array('key'=>'value'))->shouldBe(8); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php new file mode 100644 index 0000000..8662e7d --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php @@ -0,0 +1,109 @@ +beConstructedWith($value); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_value($value) + { + $this->getValue()->shouldBe($value); + } + + function its_string_representation_tells_that_its_an_array_containing_only_value($value) + { + $value->__toString()->willReturn('value'); + $this->__toString()->shouldBe('[value, ..., value]'); + } + + /** + * @param \stdClass $stdClass + */ + function it_wraps_non_token_value_into_ExactValueToken($stdClass) + { + $this->beConstructedWith($stdClass); + $this->getValue()->shouldHaveType('Prophecy\Argument\Token\ExactValueToken'); + } + + function it_does_not_score_if_argument_is_neither_array_nor_traversable() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_empty_array() + { + $this->scoreArgument(array())->shouldBe(false); + } + + /** + * @param \Iterator $object + */ + function it_does_not_score_traversable_object_without_entries($object) + { + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(false); + $this->scoreArgument($object)->shouldBe(false); + } + + function it_scores_avg_of_scores_from_value_tokens($value) + { + $value->scoreArgument('value1')->willReturn(6); + $value->scoreArgument('value2')->willReturn(3); + $this->scoreArgument(array('value1', 'value2'))->shouldBe(4.5); + } + + function it_scores_false_if_entry_scores_false($value) + { + $value->scoreArgument('value1')->willReturn(6); + $value->scoreArgument('value2')->willReturn(false); + $this->scoreArgument(array('value1', 'value2'))->shouldBe(false); + } + + function it_does_not_score_array_keys($value) + { + $value->scoreArgument('value')->willReturn(6); + $value->scoreArgument('key')->shouldNotBeCalled(0); + $this->scoreArgument(array('key' => 'value'))->shouldBe(6); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $value + * @param \Iterator $object + */ + function it_scores_traversable_object_from_value_token($value, $object) + { + $object->current()->will(function ($args, $object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $value->scoreArgument('value')->willReturn(2); + $this->scoreArgument($object)->shouldBe(2); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/CallbackTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/CallbackTokenSpec.php new file mode 100644 index 0000000..4395bf0 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/CallbackTokenSpec.php @@ -0,0 +1,42 @@ +beConstructedWith('get_class'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_7_if_argument_matches_callback() + { + $this->beConstructedWith(function ($argument) { return 2 === $argument; }); + + $this->scoreArgument(2)->shouldReturn(7); + } + + function it_does_not_scores_if_argument_does_not_match_callback() + { + $this->beConstructedWith(function ($argument) { return 2 === $argument; }); + + $this->scoreArgument(5)->shouldReturn(false); + } + + function its_string_representation_should_tell_that_its_callback() + { + $this->__toString()->shouldReturn('callback()'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php new file mode 100644 index 0000000..9e46e02 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php @@ -0,0 +1,155 @@ +beConstructedWith(42); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_value() + { + $this->getValue()->shouldReturn(42); + } + + function it_scores_10_if_value_is_equal_to_argument() + { + $this->scoreArgument(42)->shouldReturn(10); + $this->scoreArgument('42')->shouldReturn(10); + } + + function it_scores_10_if_value_is_an_object_and_equal_to_argument() + { + $value = new \DateTime(); + $value2 = clone $value; + + $this->beConstructedWith($value); + $this->scoreArgument($value2)->shouldReturn(10); + } + + function it_does_not_scores_if_value_is_not_equal_to_argument() + { + $this->scoreArgument(50)->shouldReturn(false); + $this->scoreArgument(new \stdClass())->shouldReturn(false); + } + + function it_does_not_scores_if_value_an_object_and_is_not_equal_to_argument() + { + $value = new ExactValueTokenFixtureB('ABC'); + $value2 = new ExactValueTokenFixtureB('CBA'); + + $this->beConstructedWith($value); + $this->scoreArgument($value2)->shouldReturn(false); + } + + function it_does_not_scores_if_value_type_and_is_not_equal_to_argument() + { + $this->beConstructedWith(false); + $this->scoreArgument(0)->shouldReturn(false); + } + + function it_generates_proper_string_representation_for_integer() + { + $this->beConstructedWith(42); + $this->__toString()->shouldReturn('exact(42)'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->beConstructedWith('some string'); + $this->__toString()->shouldReturn('exact("some string")'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->beConstructedWith("some\nstring"); + $this->__toString()->shouldReturn('exact("some\\nstring")'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->beConstructedWith(42.3); + $this->__toString()->shouldReturn('exact(42.3)'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->beConstructedWith(true); + $this->__toString()->shouldReturn('exact(true)'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->beConstructedWith(false); + $this->__toString()->shouldReturn('exact(false)'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->beConstructedWith(null); + $this->__toString()->shouldReturn('exact(null)'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->beConstructedWith(array()); + $this->__toString()->shouldReturn('exact([])'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->beConstructedWith(array('zet', 42)); + $this->__toString()->shouldReturn('exact(["zet", 42])'); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->beConstructedWith($resource); + $this->__toString()->shouldReturn('exact(stream:'.$resource.')'); + } + + /** + * @param \stdClass $object + */ + function it_generates_proper_string_representation_for_object($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->beConstructedWith($object); + $this->__toString()->shouldReturn("exact($objHash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } +} + +class ExactValueTokenFixtureA +{ + public $errors; +} + +class ExactValueTokenFixtureB extends ExactValueTokenFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php new file mode 100644 index 0000000..00c3a21 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php @@ -0,0 +1,152 @@ +beConstructedWith(42); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Argument\Token\IdenticalValueToken'); + } + + function it_scores_11_if_string_value_is_identical_to_argument() + { + $this->beConstructedWith('foo'); + $this->scoreArgument('foo')->shouldReturn(11); + } + + function it_scores_11_if_boolean_value_is_identical_to_argument() + { + $this->beConstructedWith(false); + $this->scoreArgument(false)->shouldReturn(11); + } + + function it_scores_11_if_integer_value_is_identical_to_argument() + { + $this->beConstructedWith(31); + $this->scoreArgument(31)->shouldReturn(11); + } + + function it_scores_11_if_float_value_is_identical_to_argument() + { + $this->beConstructedWith(31.12); + $this->scoreArgument(31.12)->shouldReturn(11); + } + + function it_scores_11_if_array_value_is_identical_to_argument() + { + $this->beConstructedWith(array('foo' => 'bar')); + $this->scoreArgument(array('foo' => 'bar'))->shouldReturn(11); + } + + function it_scores_11_if_object_value_is_identical_to_argument() + { + $object = new \stdClass(); + + $this->beConstructedWith($object); + $this->scoreArgument($object)->shouldReturn(11); + } + + function it_scores_false_if_value_is_not_identical_to_argument() + { + $this->beConstructedWith(new \stdClass()); + $this->scoreArgument('foo')->shouldReturn(false); + } + + function it_scores_false_if_object_value_is_not_the_same_instance_than_argument() + { + $this->beConstructedWith(new \stdClass()); + $this->scoreArgument(new \stdClass())->shouldReturn(false); + } + + function it_scores_false_if_integer_value_is_not_identical_to_boolean_argument() + { + $this->beConstructedWith(1); + $this->scoreArgument(true)->shouldReturn(false); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_generates_proper_string_representation_for_integer() + { + $this->beConstructedWith(42); + $this->__toString()->shouldReturn('identical(42)'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->beConstructedWith('some string'); + $this->__toString()->shouldReturn('identical("some string")'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->beConstructedWith("some\nstring"); + $this->__toString()->shouldReturn('identical("some\\nstring")'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->beConstructedWith(42.3); + $this->__toString()->shouldReturn('identical(42.3)'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->beConstructedWith(true); + $this->__toString()->shouldReturn('identical(true)'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->beConstructedWith(false); + $this->__toString()->shouldReturn('identical(false)'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->beConstructedWith(null); + $this->__toString()->shouldReturn('identical(null)'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->beConstructedWith(array()); + $this->__toString()->shouldReturn('identical([])'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->beConstructedWith(array('zet', 42)); + $this->__toString()->shouldReturn('identical(["zet", 42])'); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->beConstructedWith($resource); + $this->__toString()->shouldReturn('identical(stream:'.$resource.')'); + } + + function it_generates_proper_string_representation_for_object($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->beConstructedWith($object); + $this->__toString()->shouldReturn("identical($objHash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php new file mode 100644 index 0000000..bb5e384 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php @@ -0,0 +1,78 @@ +beConstructedWith(array()); + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->beConstructedWith(array()); + $this->shouldNotBeLast(); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + * @param \Prophecy\Argument\Token\TokenInterface $token3 + */ + function it_generates_string_representation_from_all_tokens_imploded($token1, $token2, $token3) + { + $token1->__toString()->willReturn('token_1'); + $token2->__toString()->willReturn('token_2'); + $token3->__toString()->willReturn('token_3'); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->__toString()->shouldReturn('bool(token_1 AND token_2 AND token_3)'); + } + + function it_wraps_non_token_arguments_into_ExactValueToken() + { + $this->beConstructedWith(array(15, '1985')); + $this->__toString()->shouldReturn("bool(exact(15) AND exact(\"1985\"))"); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + */ + function it_scores_the_maximum_score_from_all_scores_returned_by_tokens($token1, $token2) + { + $token1->scoreArgument(1)->willReturn(10); + $token2->scoreArgument(1)->willReturn(5); + $this->beConstructedWith(array($token1, $token2)); + $this->scoreArgument(1)->shouldReturn(10); + } + + function it_does_not_score_if_there_are_no_arguments_or_tokens() + { + $this->beConstructedWith(array()); + $this->scoreArgument('any')->shouldReturn(false); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $token1 + * @param \Prophecy\Argument\Token\TokenInterface $token2 + */ + function it_does_not_score_if_either_of_tokens_does_not_score($token1, $token2) + { + $token1->scoreArgument(1)->willReturn(10); + $token1->scoreArgument(2)->willReturn(false); + + $token2->scoreArgument(1)->willReturn(false); + $token2->scoreArgument(2)->willReturn(10); + + $this->beConstructedWith(array($token1, $token2)); + + $this->scoreArgument(1)->shouldReturn(false); + $this->scoreArgument(2)->shouldReturn(false); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php new file mode 100644 index 0000000..7ce7f3d --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php @@ -0,0 +1,65 @@ +beConstructedWith($token); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_holds_originating_token($token) + { + $this->getOriginatingToken()->shouldReturn($token); + } + + function it_has_simple_string_representation($token) + { + $token->__toString()->willReturn('value'); + $this->__toString()->shouldBe('not(value)'); + } + + function it_wraps_non_token_argument_into_ExactValueToken() + { + $this->beConstructedWith(5); + $token = $this->getOriginatingToken(); + $token->shouldhaveType('Prophecy\Argument\Token\ExactValueToken'); + $token->getValue()->shouldBe(5); + } + + function it_scores_4_if_preset_token_does_not_match_the_argument($token) + { + $token->scoreArgument('argument')->willReturn(false); + $this->scoreArgument('argument')->shouldBe(4); + } + + function it_does_not_score_if_preset_token_matches_argument($token) + { + $token->scoreArgument('argument')->willReturn(5); + $this->scoreArgument('argument')->shouldBe(false); + } + + function it_is_last_if_preset_token_is_last($token) + { + $token->isLast()->willReturn(true); + $this->shouldBeLast(); + } + + function it_is_not_last_if_preset_token_is_not_last($token) + { + $token->isLast()->willReturn(false); + $this->shouldNotBeLast(); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php new file mode 100644 index 0000000..a783a15 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php @@ -0,0 +1,101 @@ +beConstructedWith('getName', 'stdClass'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + /** + * @param \ReflectionClass $reflection + */ + function it_scores_8_if_argument_object_has_specific_method_state($reflection) + { + $reflection->getName()->willReturn('stdClass'); + + $this->scoreArgument($reflection)->shouldReturn(8); + } + + /** + * @param \stdClass $class + */ + function it_scores_8_if_argument_object_has_specific_property_state($class) + { + $class->getName = 'stdClass'; + + $this->scoreArgument($class)->shouldReturn(8); + } + + function it_does_not_score_if_argument_method_state_does_not_match() + { + $value = new ObjectStateTokenFixtureB('ABC'); + $value2 = new ObjectStateTokenFixtureB('CBA'); + + $this->beConstructedWith('getSelf', $value); + $this->scoreArgument($value2)->shouldReturn(false); + } + + /** + * @param \stdClass $class + */ + function it_does_not_score_if_argument_property_state_does_not_match($class) + { + $class->getName = 'SplFileInfo'; + + $this->scoreArgument($class)->shouldReturn(false); + } + + /** + * @param \spec\Prophecy\Argument\Token\ObjectStateTokenFixtureA $class + */ + function it_does_not_score_if_argument_object_does_not_have_method_or_property($class) + { + $this->scoreArgument($class)->shouldReturn(false); + } + + function it_does_not_score_if_argument_is_not_object() + { + $this->scoreArgument(42)->shouldReturn(false); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldReturn('state(getName(), "stdClass")'); + } +} + +class ObjectStateTokenFixtureA +{ + public $errors; +} + +class ObjectStateTokenFixtureB extends ObjectStateTokenFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } + + public function getSelf() + { + return $this; + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php new file mode 100644 index 0000000..c7fd265 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php @@ -0,0 +1,49 @@ +beConstructedWith('a substring'); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Argument\Token\StringContainsToken'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_holds_value() + { + $this->getValue()->shouldReturn('a substring'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_6_if_the_argument_contains_the_value() + { + $this->scoreArgument('Argument containing a substring')->shouldReturn(6); + } + + function it_does_not_score_if_the_argument_does_not_contain_the_value() + { + $this->scoreArgument('Argument will not match')->shouldReturn(false); + } + + function its_string_representation_shows_substring() + { + $this->__toString()->shouldReturn('contains("a substring")'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/TypeTokenSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/TypeTokenSpec.php new file mode 100644 index 0000000..ae3e26e --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Argument/Token/TypeTokenSpec.php @@ -0,0 +1,62 @@ +beConstructedWith('integer'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_5_if_argument_matches_simple_type() + { + $this->beConstructedWith('integer'); + + $this->scoreArgument(42)->shouldReturn(5); + } + + function it_does_not_scores_if_argument_does_not_match_simple_type() + { + $this->beConstructedWith('integer'); + + $this->scoreArgument(42.0)->shouldReturn(false); + } + + /** + * @param \ReflectionObject $object + */ + function it_scores_5_if_argument_is_an_instance_of_specified_class($object) + { + $this->beConstructedWith('ReflectionClass'); + + $this->scoreArgument($object)->shouldReturn(5); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldReturn('type(integer)'); + } + + /** + * @param \Prophecy\Argument\Token\TokenInterface $interface + */ + function it_scores_5_if_argument_is_an_instance_of_specified_interface($interface) + { + $this->beConstructedWith('Prophecy\Argument\Token\TokenInterface'); + + $this->scoreArgument($interface)->shouldReturn(5); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/ArgumentSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/ArgumentSpec.php new file mode 100644 index 0000000..990aa80 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/ArgumentSpec.php @@ -0,0 +1,101 @@ +exact(42); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ExactValueToken'); + $token->getValue()->shouldReturn(42); + } + + function it_has_a_shortcut_for_any_argument_token() + { + $token = $this->any(); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_multiple_arguments_token() + { + $token = $this->cetera(); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\AnyValuesToken'); + } + + function it_has_a_shortcut_for_type_token() + { + $token = $this->type('integer'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\TypeToken'); + } + + function it_has_a_shortcut_for_callback_token() + { + $token = $this->that('get_class'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\CallbackToken'); + } + + function it_has_a_shortcut_for_object_state_token() + { + $token = $this->which('getName', 'everzet'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ObjectStateToken'); + } + + function it_has_a_shortcut_for_logical_and_token() + { + $token = $this->allOf('integer', 5); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\LogicalAndToken'); + } + + function it_has_a_shortcut_for_array_count_token() + { + $token = $this->size(5); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayCountToken'); + } + + function it_has_a_shortcut_for_array_entry_token() + { + $token = $this->withEntry('key', 'value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + } + + function it_has_a_shortcut_for_array_every_entry_token() + { + $token = $this->withEveryEntry('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEveryEntryToken'); + } + + function it_has_a_shortcut_for_identical_value_token() + { + $token = $this->is('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\IdenticalValueToken'); + } + + function it_has_a_shortcut_for_array_entry_token_matching_any_key() + { + $token = $this->containing('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + $token->getKey()->shouldHaveType('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_array_entry_token_matching_any_value() + { + $token = $this->withKey('key'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + $token->getValue()->shouldHaveType('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_logical_not_token() + { + $token = $this->not('kagux'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\LogicalNotToken'); + } + + function it_has_a_shortcut_for_string_contains_token() + { + $token = $this->containingString('string'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\StringContainsToken'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Call/CallCenterSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Call/CallCenterSpec.php new file mode 100644 index 0000000..acf8d78 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Call/CallCenterSpec.php @@ -0,0 +1,195 @@ +scoreArguments(array(5, 2, 3))->willReturn(10); + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'setValues', array(5, 2, 3)); + + $calls = $this->findCalls('setValues', $wildcard); + $calls->shouldHaveCount(1); + + $calls[0]->shouldBeAnInstanceOf('Prophecy\Call\Call'); + $calls[0]->getMethodName()->shouldReturn('setValues'); + $calls[0]->getArguments()->shouldReturn(array(5, 2, 3)); + $calls[0]->getReturnValue()->shouldReturn(null); + } + + function it_returns_null_for_any_call_through_makeCall_if_no_method_prophecies_added( + $objectProphecy + ) + { + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'setValues', array(5, 2, 3))->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method1 + * @param \Prophecy\Prophecy\MethodProphecy $method2 + * @param \Prophecy\Prophecy\MethodProphecy $method3 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments1 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments2 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments3 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_executes_promise_of_method_prophecy_that_matches_signature_passed_to_makeCall( + $objectProphecy, $method1, $method2, $method3, $arguments1, $arguments2, $arguments3, + $promise + ) + { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $arguments1->scoreArguments(array('world', 'everything'))->willReturn(false); + + $method2->getMethodName()->willReturn('setTitle'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $arguments2->scoreArguments(array('world', 'everything'))->willReturn(false); + + $method3->getMethodName()->willReturn('getName'); + $method3->getArgumentsWildcard()->willReturn($arguments3); + $method3->getPromise()->willReturn($promise); + $arguments3->scoreArguments(array('world', 'everything'))->willReturn(200); + + $objectProphecy->getMethodProphecies()->willReturn(array( + 'method1' => array($method1), + 'method2' => array($method2, $method3) + )); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method1, $method3)); + $objectProphecy->reveal()->willReturn(new \stdClass()); + + $promise->execute(array('world', 'everything'), $objectProphecy->getWrappedObject(), $method3)->willReturn(42); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything'))->shouldReturn(42); + + $calls = $this->findCalls('getName', $arguments3); + $calls->shouldHaveCount(1); + $calls[0]->getReturnValue()->shouldReturn(42); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method1 + * @param \Prophecy\Prophecy\MethodProphecy $method2 + * @param \Prophecy\Prophecy\MethodProphecy $method3 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments1 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments2 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments3 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_executes_promise_of_method_prophecy_that_matches_with_highest_score_to_makeCall( + $objectProphecy, $method1, $method2, $method3, $arguments1, $arguments2, $arguments3, + $promise + ) + { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $arguments1->scoreArguments(array('world', 'everything'))->willReturn(50); + + $method2->getMethodName()->willReturn('getName'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $method2->getPromise()->willReturn($promise); + $arguments2->scoreArguments(array('world', 'everything'))->willReturn(300); + + $method3->getMethodName()->willReturn('getName'); + $method3->getArgumentsWildcard()->willReturn($arguments3); + $arguments3->scoreArguments(array('world', 'everything'))->willReturn(200); + + $objectProphecy->getMethodProphecies()->willReturn(array( + 'method1' => array($method1), + 'method2' => array($method2, $method3) + )); + $objectProphecy->getMethodProphecies('getName')->willReturn(array( + $method1, $method2, $method3 + )); + $objectProphecy->reveal()->willReturn(new \stdClass()); + + $promise->execute(array('world', 'everything'), $objectProphecy->getWrappedObject(), $method2) + ->willReturn('second'); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything')) + ->shouldReturn('second'); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_throws_exception_if_call_does_not_match_any_of_defined_method_prophecies( + $objectProphecy, $method, $arguments + ) + { + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->scoreArguments(array('world', 'everything'))->willReturn(false); + $arguments->__toString()->willReturn('arg1, arg2'); + + $objectProphecy->getMethodProphecies()->willReturn(array('method1' => array($method))); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method)); + + $this->shouldThrow('Prophecy\Exception\Call\UnexpectedCallException') + ->duringMakeCall($objectProphecy, 'getName', array('world', 'everything')); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_returns_null_if_method_prophecy_that_matches_makeCall_arguments_has_no_promise( + $objectProphecy, $method, $arguments + ) + { + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $method->getPromise()->willReturn(null); + $arguments->scoreArguments(array('world', 'everything'))->willReturn(100); + + $objectProphecy->getMethodProphecies()->willReturn(array($method)); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method)); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything')) + ->shouldReturn(null); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $wildcard + */ + function it_finds_recorded_calls_by_a_method_name_and_arguments_wildcard( + $objectProphecy, $wildcard + ) + { + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'getName', array('world')); + $this->makeCall($objectProphecy, 'getName', array('everything')); + $this->makeCall($objectProphecy, 'setName', array(42)); + + $wildcard->scoreArguments(array('world'))->willReturn(false); + $wildcard->scoreArguments(array('everything'))->willReturn(10); + + $calls = $this->findCalls('getName', $wildcard); + + $calls->shouldHaveCount(1); + $calls[0]->getMethodName()->shouldReturn('getName'); + $calls[0]->getArguments()->shouldReturn(array('everything')); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Call/CallSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Call/CallSpec.php new file mode 100644 index 0000000..d1a8539 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Call/CallSpec.php @@ -0,0 +1,54 @@ +beConstructedWith('setValues', array(5, 2), 42, $exception, 'some_file.php', 23); + } + + function it_exposes_method_name_through_getter() + { + $this->getMethodName()->shouldReturn('setValues'); + } + + function it_exposes_arguments_through_getter() + { + $this->getArguments()->shouldReturn(array(5, 2)); + } + + function it_exposes_return_value_through_getter() + { + $this->getReturnValue()->shouldReturn(42); + } + + function it_exposes_exception_through_getter($exception) + { + $this->getException()->shouldReturn($exception); + } + + function it_exposes_file_and_line_through_getter() + { + $this->getFile()->shouldReturn('some_file.php'); + $this->getLine()->shouldReturn(23); + } + + function it_returns_shortpath_to_callPlace() + { + $this->getCallPlace()->shouldReturn('some_file.php:23'); + } + + function it_returns_unknown_as_callPlace_if_no_file_or_line_provided() + { + $this->beConstructedWith('setValues', array(), 0, null, null, null); + + $this->getCallPlace()->shouldReturn('unknown'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ClosureComparatorSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ClosureComparatorSpec.php new file mode 100644 index 0000000..c174e73 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Comparator/ClosureComparatorSpec.php @@ -0,0 +1,39 @@ +shouldHaveType('SebastianBergmann\Comparator\Comparator'); + } + + function it_accepts_only_closures() + { + $this->accepts(123, 321)->shouldReturn(false); + $this->accepts('string', 'string')->shouldReturn(false); + $this->accepts(false, true)->shouldReturn(false); + $this->accepts(true, false)->shouldReturn(false); + $this->accepts((object)array(), (object)array())->shouldReturn(false); + $this->accepts(function(){}, (object)array())->shouldReturn(false); + $this->accepts(function(){}, (object)array())->shouldReturn(false); + + $this->accepts(function(){}, function(){})->shouldReturn(true); + } + + function it_asserts_that_all_closures_are_different() + { + $this->shouldThrow()->duringAssertEquals(function(){}, function(){}); + } + + function it_asserts_that_all_closures_are_different_even_if_its_the_same_closure() + { + $closure = function(){}; + + $this->shouldThrow()->duringAssertEquals($closure, $closure); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Comparator/FactorySpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Comparator/FactorySpec.php new file mode 100644 index 0000000..6b13336 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Comparator/FactorySpec.php @@ -0,0 +1,20 @@ +shouldHaveType('SebastianBergmann\Comparator\Factory'); + } + + function it_should_have_ClosureComparator_registered() + { + $comparator = $this->getInstance()->getComparatorFor(function(){}, function(){}); + $comparator->shouldHaveType('Prophecy\Comparator\ClosureComparator'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php new file mode 100644 index 0000000..2d7d934 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php @@ -0,0 +1,59 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_100() + { + $this->getPriority()->shouldReturn(100); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_anything($node) + { + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $arg1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $arg2 + */ + function it_makes_all_constructor_arguments_optional($class, $method, $arg1, $arg2) + { + $class->hasMethod('__construct')->willReturn(true); + $class->getMethod('__construct')->willReturn($method); + $method->getArguments()->willReturn(array($arg1, $arg2)); + + $arg1->setDefault(null)->shouldBeCalled(); + $arg2->setDefault(null)->shouldBeCalled(); + + $method->setCode(Argument::type('string'))->shouldBeCalled(); + + $this->apply($class); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_creates_new_constructor_if_object_has_none($class) + { + $class->hasMethod('__construct')->willReturn(false); + $class->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode')) + ->shouldBeCalled(); + + $this->apply($class); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php new file mode 100644 index 0000000..8c348b8 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php @@ -0,0 +1,37 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_minus_50() + { + $this->getPriority()->shouldReturn(-50); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + * @param \Prophecy\Doubler\Generator\Node\MethodNode $getterMethod + */ + function it_uses_parent_code_for_setTraceOptions($node, $method, $getterMethod) + { + $node->hasMethod('setTraceOptions')->willReturn(true); + $node->getMethod('setTraceOptions')->willReturn($method); + $node->hasMethod('getTraceOptions')->willReturn(true); + $node->getMethod('getTraceOptions')->willReturn($getterMethod); + + $method->useParentCode()->shouldBeCalled(); + $getterMethod->useParentCode()->shouldBeCalled(); + + $this->apply($node); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php new file mode 100644 index 0000000..200d961 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php @@ -0,0 +1,44 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_49() + { + $this->getPriority()->shouldReturn(49); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method1 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method2 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method3 + */ + function it_will_remove_echo_and_eval_methods($node, $method1, $method2, $method3) + { + $node->removeMethod('eval')->shouldBeCalled(); + $node->removeMethod('echo')->shouldBeCalled(); + + $method1->getName()->willReturn('echo'); + $method2->getName()->willReturn('eval'); + $method3->getName()->willReturn('notKeyword'); + + $node->getMethods()->willReturn(array( + 'echo' => $method1, + 'eval' => $method2, + 'notKeyword' => $method3, + )); + + $this->apply($node); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php new file mode 100644 index 0000000..cb1d0f0 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php @@ -0,0 +1,76 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_anything($node) + { + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_discovers_api_using_phpdoc($node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApi'); + + $node->addMethod(new MethodNode('undefinedMethod'))->shouldBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_ignores_existing_methods($node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApiExtended'); + + $node->addMethod(new MethodNode('undefinedMethod'))->shouldBeCalled(); + $node->addMethod(new MethodNode('definedMethod'))->shouldNotBeCalled(); + + $this->apply($node); + } + + function it_has_50_priority() + { + $this->getPriority()->shouldReturn(50); + } +} + +/** + * @method void undefinedMethod() + */ +class MagicalApi +{ + /** + * @return void + */ + public function definedMethod() + { + + } +} + +/** + * @method void undefinedMethod() + * @method void definedMethod() + */ +class MagicalApiExtended extends MagicalApi +{ + +} \ No newline at end of file diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php new file mode 100644 index 0000000..c460814 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php @@ -0,0 +1,83 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function it_has_priority_of_0() + { + $this->getPriority()->shouldReturn(0); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_any_class($node) + { + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_forces_class_to_implement_ProphecySubjectInterface($node) + { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface')->shouldBeCalled(); + + $node->addProperty('objectProphecy', 'private')->willReturn(null); + $node->getMethods()->willReturn(array()); + $node->hasMethod(Argument::any())->willReturn(false); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $constructor + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method1 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method2 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method3 + */ + function it_forces_all_class_methods_except_constructor_to_proxy_calls_into_prophecy_makeCall( + $node, $constructor, $method1, $method2, $method3 + ) + { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface')->willReturn(null); + $node->addProperty('objectProphecy', 'private')->willReturn(null); + $node->hasMethod(Argument::any())->willReturn(false); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + + $constructor->getName()->willReturn('__construct'); + $method1->getName()->willReturn('method1'); + $method2->getName()->willReturn('method2'); + $method3->getName()->willReturn('method3'); + + $node->getMethods()->willReturn(array( + 'method1' => $method1, + 'method2' => $method2, + 'method3' => $method3, + )); + + $constructor->setCode(Argument::any())->shouldNotBeCalled(); + + $method1->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + $method2->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + $method3->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + + $this->apply($node); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php new file mode 100644 index 0000000..4116e4d --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php @@ -0,0 +1,47 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_50() + { + $this->getPriority()->shouldReturn(50); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $reflectionClassNode + * @param \Prophecy\Doubler\Generator\Node\ClassNode $anotherClassNode + */ + function it_supports_ReflectionClass_only($reflectionClassNode, $anotherClassNode) + { + $reflectionClassNode->getParentClass()->willReturn('ReflectionClass'); + $anotherClassNode->getParentClass()->willReturn('stdClass'); + + $this->supports($reflectionClassNode)->shouldReturn(true); + $this->supports($anotherClassNode)->shouldReturn(false); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $arg1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $arg2 + */ + function it_makes_all_newInstance_arguments_optional($class, $method, $arg1, $arg2) + { + $class->getMethod('newInstance')->willReturn($method); + $method->getArguments()->willReturn(array($arg1)); + $arg1->setDefault(null)->shouldBeCalled(); + + $this->apply($class); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php new file mode 100644 index 0000000..37fe82f --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php @@ -0,0 +1,91 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_50() + { + $this->getPriority()->shouldReturn(50); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_does_not_support_nodes_without_parent_class($node) + { + $node->getParentClass()->willReturn('stdClass'); + $this->supports($node)->shouldReturn(false); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_nodes_with_SplFileInfo_as_parent_class($node) + { + $node->getParentClass()->willReturn('SplFileInfo'); + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_nodes_with_derivative_of_SplFileInfo_as_parent_class($node) + { + $node->getParentClass()->willReturn('SplFileInfo'); + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_adds_a_method_to_node_if_not_exists($node) + { + $node->hasMethod('__construct')->willReturn(false); + $node->addMethod(Argument::any())->shouldBeCalled(); + $node->getParentClass()->shouldBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function it_updates_existing_method_if_found($node, $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->shouldBeCalled(); + + $method->useParentCode()->shouldBeCalled(); + + $this->apply($node); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function it_should_not_supply_a_file_for_a_directory_iterator($node, $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->willReturn('DirectoryIterator'); + + $method->setCode(Argument::that(function($value) { + return strpos($value, '.php') === false; + }))->shouldBeCalled(); + + $this->apply($node); + } + +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php new file mode 100644 index 0000000..2279b72 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php @@ -0,0 +1,61 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_supports_class_that_implements_only_Traversable($node) + { + $node->getInterfaces()->willReturn(array('Traversable')); + + $this->supports($node)->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_does_not_support_class_that_implements_Iterator($node) + { + $node->getInterfaces()->willReturn(array('Traversable', 'Iterator')); + + $this->supports($node)->shouldReturn(false); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_does_not_support_class_that_implements_IteratorAggregate($node) + { + $node->getInterfaces()->willReturn(array('Traversable', 'IteratorAggregate')); + + $this->supports($node)->shouldReturn(false); + } + + function it_has_100_priority() + { + $this->getPriority()->shouldReturn(100); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_forces_node_to_implement_IteratorAggregate($node) + { + $node->addInterface('Iterator')->shouldBeCalled(); + + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + + $this->apply($node); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/DoublerSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/DoublerSpec.php new file mode 100644 index 0000000..a39fa87 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/DoublerSpec.php @@ -0,0 +1,122 @@ +beConstructedWith($mirror, $creator, $namer); + } + + function it_does_not_have_patches_by_default() + { + $this->getClassPatches()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $patch + */ + function its_registerClassPatch_adds_a_patch_to_the_doubler($patch) + { + $this->registerClassPatch($patch); + $this->getClassPatches()->shouldReturn(array($patch)); + } + + /** + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt1 + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt2 + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt3 + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt4 + */ + function its_getClassPatches_sorts_patches_by_priority($alt1, $alt2, $alt3, $alt4) + { + $alt1->getPriority()->willReturn(2); + $alt2->getPriority()->willReturn(50); + $alt3->getPriority()->willReturn(10); + $alt4->getPriority()->willReturn(0); + + $this->registerClassPatch($alt1); + $this->registerClassPatch($alt2); + $this->registerClassPatch($alt3); + $this->registerClassPatch($alt4); + + $this->getClassPatches()->shouldReturn(array($alt2, $alt3, $alt1, $alt4)); + } + + /** + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt1 + * @param \Prophecy\Doubler\ClassPatch\ClassPatchInterface $alt2 + * @param \ReflectionClass $class + * @param \ReflectionClass $interface1 + * @param \ReflectionClass $interface2 + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function its_double_mirrors_alterates_and_instantiates_provided_class( + $mirror, $creator, $namer, $alt1, $alt2, $class, $interface1, $interface2, $node + ) + { + $mirror->reflect($class, array($interface1, $interface2))->willReturn($node); + $alt1->supports($node)->willReturn(true); + $alt2->supports($node)->willReturn(false); + $alt1->getPriority()->willReturn(1); + $alt2->getPriority()->willReturn(2); + $namer->name($class, array($interface1, $interface2))->willReturn('SplStack'); + $class->getName()->willReturn('stdClass'); + $interface1->getName()->willReturn('ArrayAccess'); + $interface2->getName()->willReturn('Iterator'); + + $alt1->apply($node)->shouldBeCalled(); + $alt2->apply($node)->shouldNotBeCalled(); + $creator->create('SplStack', $node)->shouldBeCalled(); + + $this->registerClassPatch($alt1); + $this->registerClassPatch($alt2); + + $this->double($class, array($interface1, $interface2)) + ->shouldReturnAnInstanceOf('SplStack'); + } + + /** + * @param \ReflectionClass $class + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_double_instantiates_a_class_with_constructor_argument($mirror, $class, $node, $namer) + { + $class->getName()->willReturn('ReflectionClass'); + $mirror->reflect($class, array())->willReturn($node); + $namer->name($class, array())->willReturn('ReflectionClass'); + + $double = $this->double($class, array(), array('stdClass')); + $double->shouldBeAnInstanceOf('ReflectionClass'); + $double->getName()->shouldReturn('stdClass'); + } + + /** + * @param \ReflectionClass $class + * @param \Prophecy\Doubler\Generator\Node\ClassNode $node + */ + function it_can_instantiate_class_with_final_constructor($mirror, $class, $node, $namer) + { + $class->getName()->willReturn('spec\Prophecy\Doubler\WithFinalConstructor'); + $mirror->reflect($class, array())->willReturn($node); + $namer->name($class, array())->willReturn('spec\Prophecy\Doubler\WithFinalConstructor'); + + $double = $this->double($class, array()); + + $double->shouldBeAnInstanceOf('spec\Prophecy\Doubler\WithFinalConstructor'); + } +} + +class WithFinalConstructor +{ + final public function __construct() {} +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php new file mode 100644 index 0000000..fa65bc1 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php @@ -0,0 +1,191 @@ +getParentClass()->willReturn('RuntimeException'); + $class->getInterfaces()->willReturn(array( + 'Prophecy\Doubler\Generator\MirroredInterface', 'ArrayAccess', 'ArrayIterator' + )); + $class->getProperties()->willReturn(array('name' => 'public', 'email' => 'private')); + $class->getMethods()->willReturn(array($method1, $method2, $method3)); + + $method1->getName()->willReturn('getName'); + $method1->getVisibility()->willReturn('public'); + $method1->returnsReference()->willReturn(false); + $method1->isStatic()->willReturn(true); + $method1->getArguments()->willReturn(array($argument11, $argument12)); + $method1->hasReturnType()->willReturn(true); + $method1->getReturnType()->willReturn('string'); + $method1->getCode()->willReturn('return $this->name;'); + + $method2->getName()->willReturn('getEmail'); + $method2->getVisibility()->willReturn('protected'); + $method2->returnsReference()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method2->getArguments()->willReturn(array($argument21)); + $method2->hasReturnType()->willReturn(false); + $method2->getCode()->willReturn('return $this->email;'); + + $method3->getName()->willReturn('getRefValue'); + $method3->getVisibility()->willReturn('public'); + $method3->returnsReference()->willReturn(true); + $method3->isStatic()->willReturn(false); + $method3->getArguments()->willReturn(array($argument31)); + $method3->hasReturnType()->willReturn(false); + $method3->getCode()->willReturn('return $this->refValue;'); + + $argument11->getName()->willReturn('fullname'); + $argument11->getTypeHint()->willReturn('array'); + $argument11->isOptional()->willReturn(true); + $argument11->getDefault()->willReturn(null); + $argument11->isPassedByReference()->willReturn(false); + + $argument12->getName()->willReturn('class'); + $argument12->getTypeHint()->willReturn('ReflectionClass'); + $argument12->isOptional()->willReturn(false); + $argument12->isPassedByReference()->willReturn(false); + + $argument21->getName()->willReturn('default'); + $argument21->getTypeHint()->willReturn(null); + $argument21->isOptional()->willReturn(true); + $argument21->getDefault()->willReturn('ever.zet@gmail.com'); + $argument21->isPassedByReference()->willReturn(false); + + $argument31->getName()->willReturn('refValue'); + $argument31->getTypeHint()->willReturn(null); + $argument31->isOptional()->willReturn(false); + $argument31->getDefault()->willReturn(); + $argument31->isPassedByReference()->willReturn(false); + + $code = $this->generate('CustomClass', $class); + $expected = <<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface, \ArrayAccess, \ArrayIterator { +public $name; +private $email; + +public static function getName(array $fullname = NULL, \ReflectionClass $class): string { +return $this->name; +} +protected function getEmail( $default = 'ever.zet@gmail.com') { +return $this->email; +} +public function &getRefValue( $refValue) { +return $this->refValue; +} + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument + */ + function it_overrides_properly_methods_with_args_passed_by_reference( + $class, $method, $argument + ) + { + $class->getParentClass()->willReturn('RuntimeException'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array($method)); + + $method->getName()->willReturn('getName'); + $method->getVisibility()->willReturn('public'); + $method->isStatic()->willReturn(false); + $method->getArguments()->willReturn(array($argument)); + $method->hasReturnType()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getCode()->willReturn('return $this->name;'); + + $argument->getName()->willReturn('fullname'); + $argument->getTypeHint()->willReturn('array'); + $argument->isOptional()->willReturn(true); + $argument->getDefault()->willReturn(null); + $argument->isPassedByReference()->willReturn(true); + + $code = $this->generate('CustomClass', $class); + $expected =<<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface { + +public function getName(array &$fullname = NULL) { +return $this->name; +} + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_generates_empty_class_for_empty_ClassNode($class) + { + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array()); + + $code = $this->generate('CustomClass', $class); + $expected =<<<'PHP' +namespace { +class CustomClass extends \stdClass implements \Prophecy\Doubler\Generator\MirroredInterface { + + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_wraps_class_in_namespace_if_it_is_namespaced($class) + { + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array()); + + $code = $this->generate('My\Awesome\CustomClass', $class); + $expected =<<<'PHP' +namespace My\Awesome { +class CustomClass extends \stdClass implements \Prophecy\Doubler\Generator\MirroredInterface { + + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php new file mode 100644 index 0000000..c7b5700 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php @@ -0,0 +1,44 @@ +beConstructedWith($generator); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_evaluates_code_generated_by_ClassCodeGenerator($generator, $class) + { + $generator->generate('stdClass', $class)->shouldBeCalled()->willReturn( + 'return 42;' + ); + + $this->create('stdClass', $class)->shouldReturn(42); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ClassNode $class + */ + function it_throws_an_exception_if_class_does_not_exist_after_evaluation($generator, $class) + { + $generator->generate('CustomClass', $class)->shouldBeCalled()->willReturn( + 'return 42;' + ); + + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Interface1', 'Interface2')); + + $this->shouldThrow('Prophecy\Exception\Doubler\ClassCreatorException') + ->duringCreate('CustomClass', $class); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassMirrorSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassMirrorSpec.php new file mode 100644 index 0000000..161f850 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/ClassMirrorSpec.php @@ -0,0 +1,610 @@ +getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array( + $method1, $method2, $method3 + )); + + $method1->getName()->willReturn('getName'); + $method2->getName()->willReturn('isPublic'); + $method3->getName()->willReturn('isAbstract'); + + $method1->isFinal()->willReturn(false); + $method2->isFinal()->willReturn(false); + $method3->isFinal()->willReturn(false); + + $method1->isProtected()->willReturn(false); + $method2->isProtected()->willReturn(false); + $method3->isProtected()->willReturn(false); + + $method1->isStatic()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method3->isStatic()->willReturn(false); + + $method1->returnsReference()->willReturn(false); + $method2->returnsReference()->willReturn(false); + $method3->returnsReference()->willReturn(false); + + $method1->getParameters()->willReturn(array()); + $method2->getParameters()->willReturn(array()); + $method3->getParameters()->willReturn(array()); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method1->hasReturnType()->willReturn(false); + $method2->hasReturnType()->willReturn(false); + $method3->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('Custom\ClassName'); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(3); + + $classNode->hasMethod('getName')->shouldReturn(true); + $classNode->hasMethod('isPublic')->shouldReturn(true); + $classNode->hasMethod('isAbstract')->shouldReturn(true); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param ReflectionParameter $parameter + */ + function it_changes_argument_names_if_they_are_varying($class, $method, $parameter) + { + + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + + $method->getParameters()->willReturn(array($parameter)); + $method->getName()->willReturn('methodName'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(false); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $parameter->getName()->willReturn('...'); + $parameter->isDefaultValueAvailable()->willReturn(true); + $parameter->getDefaultValue()->willReturn(null); + $parameter->isPassedByReference()->willReturn(false); + $parameter->getClass()->willReturn($class); + + $classNode = $this->reflect($class, array()); + + $methodNodes = $classNode->getMethods(); + + $argumentNodes = $methodNodes['methodName']->getArguments(); + $argumentNode = $argumentNodes[0]; + + $argumentNode->getName()->shouldReturn('__dot_dot_dot__'); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_reflects_protected_abstract_methods($class, $method) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array($method)); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array()); + + $method->isProtected()->willReturn(true); + $method->isStatic()->willReturn(false); + $method->getParameters()->willReturn(array()); + $method->getName()->willReturn('innerDetail'); + $method->returnsReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('Custom\ClassName'); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(1); + + $methodNodes['innerDetail']->getVisibility()->shouldReturn('protected'); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_reflects_public_static_methods($class, $method) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array($method)); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array()); + + $method->isProtected()->willReturn(true); + $method->isStatic()->willReturn(true); + $method->getParameters()->willReturn(array()); + $method->getName()->willReturn('innerDetail'); + $method->returnsReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('Custom\ClassName'); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(1); + + $methodNodes['innerDetail']->getVisibility()->shouldReturn('protected'); + $methodNodes['innerDetail']->isStatic()->shouldReturn(true); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param ReflectionParameter $param1 + * @param ReflectionParameter $param2 + * @param ReflectionClass $typeHint + * @param ReflectionParameter $param3 + */ + function it_properly_reads_methods_arguments_with_types( + $class, $method, $param1, $param2, $typeHint, $param3 + ) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->getName()->willReturn('methodWithArgs'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(true); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getParameters()->willReturn(array($param1, $param2, $param3)); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $param1->getName()->willReturn('arg_1'); + $param1->isArray()->willReturn(true); + $param1->getClass()->willReturn(null); + $param1->isDefaultValueAvailable()->willReturn(true); + $param1->isPassedByReference()->willReturn(false); + $param1->allowsNull()->willReturn(false); + $param1->getDefaultValue()->willReturn(array()); + + $param2->getName()->willReturn('arg2'); + $param2->isArray()->willReturn(false); + $param2->getClass()->willReturn($typeHint); + $param2->isDefaultValueAvailable()->willReturn(false); + $param2->isOptional()->willReturn(false); + $param2->isPassedByReference()->willReturn(false); + $param2->allowsNull()->willReturn(false); + $typeHint->getName()->willReturn('ArrayAccess'); + + $param3->getName()->willReturn('arg_3'); + $param3->isArray()->willReturn(false); + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $param3->isCallable()->willReturn(true); + } + $param3->getClass()->willReturn(null); + $param3->isOptional()->willReturn(false); + $param3->isDefaultValueAvailable()->willReturn(false); + $param3->isPassedByReference()->willReturn(false); + $param3->allowsNull()->willReturn(true); + + $classNode = $this->reflect($class, array()); + $methodNodes = $classNode->getMethods(); + $argNodes = $methodNodes['methodWithArgs']->getArguments(); + + $argNodes[0]->getName()->shouldReturn('arg_1'); + $argNodes[0]->getTypeHint()->shouldReturn('array'); + $argNodes[0]->isOptional()->shouldReturn(true); + $argNodes[0]->getDefault()->shouldReturn(array()); + + $argNodes[1]->getName()->shouldReturn('arg2'); + $argNodes[1]->getTypeHint()->shouldReturn('ArrayAccess'); + $argNodes[1]->isOptional()->shouldReturn(false); + + $argNodes[2]->getName()->shouldReturn('arg_3'); + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $argNodes[2]->getTypeHint()->shouldReturn('callable'); + $argNodes[2]->isOptional()->shouldReturn(true); + $argNodes[2]->getDefault()->shouldReturn(null); + } else { + $argNodes[2]->isOptional()->shouldReturn(false); + } + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param ReflectionParameter $param1 + */ + function it_marks_required_args_without_types_as_not_optional( + $class, $method, $param1 + ) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->getName()->willReturn('methodWithArgs'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(false); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getParameters()->willReturn(array($param1)); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $param1->getName()->willReturn('arg_1'); + $param1->isArray()->willReturn(false); + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $param1->isCallable()->willReturn(false); + } + $param1->getClass()->willReturn(null); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $param1->hasType()->willReturn(false); + } + + $param1->isDefaultValueAvailable()->willReturn(false); + $param1->isOptional()->willReturn(false); + $param1->isPassedByReference()->willReturn(false); + $param1->allowsNull()->willReturn(true); + if (defined('HHVM_VERSION')) { + $param1->getTypehintText()->willReturn(null); + } + + $classNode = $this->reflect($class, array()); + $methodNodes = $classNode->getMethods(); + $argNodes = $methodNodes['methodWithArgs']->getArguments(); + + $argNodes[0]->isOptional()->shouldReturn(false); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + * @param ReflectionParameter $param1 + * @param ReflectionParameter $param2 + * @param ReflectionClass $typeHint + */ + function it_marks_passed_by_reference_args_as_passed_by_reference( + $class, $method, $param1, $param2, $typeHint + ) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->getName()->willReturn('methodWithArgs'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(false); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getParameters()->willReturn(array($param1, $param2)); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $param1->getName()->willReturn('arg_1'); + $param1->isArray()->willReturn(false); + if (version_compare(PHP_VERSION, '5.4', '>=')) { + $param1->isCallable()->willReturn(false); + } + $param1->getClass()->willReturn(null); + $param1->isDefaultValueAvailable()->willReturn(false); + $param1->isOptional()->willReturn(true); + $param1->isPassedByReference()->willReturn(true); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $param1->hasType()->willReturn(false); + } + + $param1->allowsNull()->willReturn(false); + if (defined('HHVM_VERSION')) { + $param1->getTypehintText()->willReturn(null); + } + + $param2->getName()->willReturn('arg2'); + $param2->isArray()->willReturn(false); + $param2->getClass()->willReturn($typeHint); + $param2->isDefaultValueAvailable()->willReturn(false); + $param2->isOptional()->willReturn(false); + $param2->isPassedByReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $param2->hasType()->willReturn(false); + } + + $param2->allowsNull()->willReturn(false); + $typeHint->getName()->willReturn('ArrayAccess'); + + $classNode = $this->reflect($class, array()); + $methodNodes = $classNode->getMethods(); + $argNodes = $methodNodes['methodWithArgs']->getArguments(); + + $argNodes[0]->isPassedByReference()->shouldReturn(true); + $argNodes[1]->isPassedByReference()->shouldReturn(false); + } + + /** + * @param ReflectionClass $class + */ + function it_throws_an_exception_if_class_is_final($class) + { + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(true); + $class->getName()->willReturn('Custom\ClassName'); + + $this->shouldThrow('Prophecy\Exception\Doubler\ClassMirrorException') + ->duringReflect($class, array()); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_ignores_final_methods($class, $method) + { + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->isFinal()->willReturn(true); + $method->getName()->willReturn('finalImplementation'); + + $classNode = $this->reflect($class, array()); + $classNode->getMethods()->shouldHaveCount(0); + } + + /** + * @param ReflectionClass $interface + */ + function it_throws_an_exception_if_interface_provided_instead_of_class($interface) + { + $interface->isInterface()->willReturn(true); + $interface->getName()->willReturn('Custom\ClassName'); + + $this->shouldThrow('Prophecy\Exception\InvalidArgumentException') + ->duringReflect($interface, array()); + } + + /** + * @param ReflectionClass $interface1 + * @param ReflectionClass $interface2 + * @param ReflectionMethod $method1 + * @param ReflectionMethod $method2 + * @param ReflectionMethod $method3 + */ + function it_reflects_all_interfaces_methods( + $interface1, $interface2, $method1, $method2, $method3 + ) + { + $interface1->getName()->willReturn('MyInterface1'); + $interface2->getName()->willReturn('MyInterface2'); + + $interface1->isInterface()->willReturn(true); + $interface2->isInterface()->willReturn(true); + + $interface1->getMethods()->willReturn(array($method1)); + $interface2->getMethods()->willReturn(array($method2, $method3)); + + $method1->getName()->willReturn('getName'); + $method2->getName()->willReturn('isPublic'); + $method3->getName()->willReturn('isAbstract'); + + $method1->isProtected()->willReturn(false); + $method2->isProtected()->willReturn(false); + $method3->isProtected()->willReturn(false); + + $method1->returnsReference()->willReturn(false); + $method2->returnsReference()->willReturn(false); + $method3->returnsReference()->willReturn(false); + + $method1->isStatic()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method3->isStatic()->willReturn(false); + + $method1->getParameters()->willReturn(array()); + $method2->getParameters()->willReturn(array()); + $method3->getParameters()->willReturn(array()); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method1->hasReturnType()->willReturn(false); + $method2->hasReturnType()->willReturn(false); + $method3->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect(null, array($interface1, $interface2)); + + $classNode->shouldBeAnInstanceOf('Prophecy\Doubler\Generator\Node\ClassNode'); + $classNode->getParentClass()->shouldReturn('stdClass'); + $classNode->getInterfaces()->shouldReturn(array( + 'Prophecy\Doubler\Generator\ReflectionInterface', 'MyInterface2', 'MyInterface1', + )); + + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(3); + + $classNode->hasMethod('getName')->shouldReturn(true); + $classNode->hasMethod('isPublic')->shouldReturn(true); + $classNode->hasMethod('isAbstract')->shouldReturn(true); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method1 + * @param ReflectionMethod $method2 + * @param ReflectionMethod $method3 + */ + function it_ignores_virtually_private_methods($class, $method1, $method2, $method3) + { + $class->getName()->willReturn('SomeClass'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method1, $method2, $method3)); + + $method1->getName()->willReturn('_getName'); + $method2->getName()->willReturn('__toString'); + $method3->getName()->willReturn('isAbstract'); + + $method1->isFinal()->willReturn(false); + $method2->isFinal()->willReturn(false); + $method3->isFinal()->willReturn(false); + + $method1->isProtected()->willReturn(false); + $method2->isProtected()->willReturn(false); + $method3->isProtected()->willReturn(false); + + $method1->isStatic()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method3->isStatic()->willReturn(false); + + $method1->returnsReference()->willReturn(false); + $method2->returnsReference()->willReturn(false); + $method3->returnsReference()->willReturn(false); + + $method1->getParameters()->willReturn(array()); + $method2->getParameters()->willReturn(array()); + $method3->getParameters()->willReturn(array()); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method1->hasReturnType()->willReturn(false); + $method2->hasReturnType()->willReturn(false); + $method3->hasReturnType()->willReturn(false); + } + + $classNode = $this->reflect($class, array()); + $methodNodes = $classNode->getMethods(); + $methodNodes->shouldHaveCount(2); + + $classNode->hasMethod('isAbstract')->shouldReturn(true); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + function it_does_not_throw_exception_for_virtually_private_finals($class, $method) + { + $class->getName()->willReturn('SomeClass'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + $class->getMethods(ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + + $method->getName()->willReturn('__toString'); + $method->isFinal()->willReturn(true); + + $this->shouldNotThrow()->duringReflect($class, array()); + } + + /** + * @param ReflectionClass $class + */ + function it_throws_an_exception_if_class_provided_in_interfaces_list($class) + { + $class->getName()->willReturn('MyClass'); + $class->isInterface()->willReturn(false); + + $this->shouldThrow('InvalidArgumentException') + ->duringReflect(null, array($class)); + } + + function it_throws_an_exception_if_not_reflection_provided_as_interface() + { + $this->shouldThrow('InvalidArgumentException') + ->duringReflect(null, array(null)); + } + + function it_doesnt_fail_to_typehint_nonexistent_FQCN() + { + $classNode = $this->reflect(new ReflectionClass('spec\Prophecy\Doubler\Generator\OptionalDepsClass'), array()); + $method = $classNode->getMethod('iHaveAStrangeTypeHintedArg'); + $arguments = $method->getArguments(); + $arguments[0]->getTypeHint()->shouldBe('I\Simply\Am\Nonexistent'); + } + + function it_doesnt_fail_to_typehint_nonexistent_RQCN() + { + $classNode = $this->reflect(new ReflectionClass('spec\Prophecy\Doubler\Generator\OptionalDepsClass'), array()); + $method = $classNode->getMethod('iHaveAnEvenStrangerTypeHintedArg'); + $arguments = $method->getArguments(); + $arguments[0]->getTypeHint()->shouldBe('I\Simply\Am\Not'); + } + + function it_doesnt_use_scalar_typehints() + { + $classNode = $this->reflect(new ReflectionClass('ReflectionMethod'), array()); + $method = $classNode->getMethod('export'); + $arguments = $method->getArguments(); + $arguments[0]->getTypeHint()->shouldReturn(null); + $arguments[1]->getTypeHint()->shouldReturn(null); + $arguments[2]->getTypeHint()->shouldReturn(null); + } +} + +class OptionalDepsClass +{ + public function iHaveAStrangeTypeHintedArg(\I\Simply\Am\Nonexistent $class) + { + } + + public function iHaveAnEvenStrangerTypeHintedArg(Simply\Am\Not $class) + { + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php new file mode 100644 index 0000000..cea578f --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php @@ -0,0 +1,62 @@ +beConstructedWith('name'); + } + + function it_is_not_be_passed_by_reference_by_default() + { + $this->shouldNotBePassedByReference(); + } + + function it_is_passed_by_reference_if_marked() + { + $this->setAsPassedByReference(); + $this->shouldBePassedByReference(); + } + + function it_has_name_with_which_it_was_been_constructed() + { + $this->getName()->shouldReturn('name'); + } + + function it_has_no_typehint_by_default() + { + $this->getTypeHint()->shouldReturn(null); + } + + function its_typeHint_is_mutable() + { + $this->setTypeHint('array'); + $this->getTypeHint()->shouldReturn('array'); + } + + function it_does_not_have_default_value_by_default() + { + $this->getDefault()->shouldReturn(null); + } + + function it_is_not_optional_by_default() + { + $this->isOptional()->shouldReturn(false); + } + + function its_default_is_mutable() + { + $this->setDefault(array()); + $this->getDefault()->shouldReturn(array()); + } + + function it_is_marked_as_optional_when_default_is_set() + { + $this->setDefault(null); + $this->isOptional()->shouldReturn(true); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php new file mode 100644 index 0000000..18f0e1c --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php @@ -0,0 +1,154 @@ +getParentClass()->shouldReturn('stdClass'); + } + + function its_parentClass_is_mutable() + { + $this->setParentClass('Exception'); + $this->getParentClass()->shouldReturn('Exception'); + } + + function its_parentClass_is_set_to_stdClass_if_user_set_null() + { + $this->setParentClass(null); + $this->getParentClass()->shouldReturn('stdClass'); + } + + function it_does_not_implement_any_interface_by_default() + { + $this->getInterfaces()->shouldHaveCount(0); + } + + function its_addInterface_adds_item_to_the_list_of_implemented_interfaces() + { + $this->addInterface('MyInterface'); + $this->getInterfaces()->shouldHaveCount(1); + } + + function its_hasInterface_returns_true_if_class_implements_interface() + { + $this->addInterface('MyInterface'); + $this->hasInterface('MyInterface')->shouldReturn(true); + } + + function its_hasInterface_returns_false_if_class_does_not_implements_interface() + { + $this->hasInterface('MyInterface')->shouldReturn(false); + } + + function it_supports_implementation_of_multiple_interfaces() + { + $this->addInterface('MyInterface'); + $this->addInterface('MySecondInterface'); + $this->getInterfaces()->shouldHaveCount(2); + } + + function it_ignores_same_interfaces_added_twice() + { + $this->addInterface('MyInterface'); + $this->addInterface('MyInterface'); + + $this->getInterfaces()->shouldHaveCount(1); + $this->getInterfaces()->shouldReturn(array('MyInterface')); + } + + function it_does_not_have_methods_by_default() + { + $this->getMethods()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method1 + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method2 + */ + function it_can_has_methods($method1, $method2) + { + $method1->getName()->willReturn('__construct'); + $method2->getName()->willReturn('getName'); + + $this->addMethod($method1); + $this->addMethod($method2); + + $this->getMethods()->shouldReturn(array( + '__construct' => $method1, + 'getName' => $method2 + )); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function its_hasMethod_returns_true_if_method_exists($method) + { + $method->getName()->willReturn('getName'); + + $this->addMethod($method); + + $this->hasMethod('getName')->shouldReturn(true); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function its_getMethod_returns_method_by_name($method) + { + $method->getName()->willReturn('getName'); + + $this->addMethod($method); + + $this->getMethod('getName')->shouldReturn($method); + } + + function its_hasMethod_returns_false_if_method_does_not_exists() + { + $this->hasMethod('getName')->shouldReturn(false); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\MethodNode $method + */ + function its_hasMethod_returns_false_if_method_has_been_removed($method) + { + $method->getName()->willReturn('getName'); + $this->addMethod($method); + $this->removeMethod('getName'); + + $this->hasMethod('getName')->shouldReturn(false); + } + + + function it_does_not_have_properties_by_default() + { + $this->getProperties()->shouldHaveCount(0); + } + + function it_is_able_to_have_properties() + { + $this->addProperty('title'); + $this->addProperty('text', 'private'); + $this->getProperties()->shouldReturn(array( + 'title' => 'public', + 'text' => 'private' + )); + } + + function its_addProperty_does_not_accept_unsupported_visibility() + { + $this->shouldThrow('InvalidArgumentException')->duringAddProperty('title', 'town'); + } + + function its_addProperty_lowercases_visibility_before_setting() + { + $this->addProperty('text', 'PRIVATE'); + $this->getProperties()->shouldReturn(array('text' => 'private')); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php new file mode 100644 index 0000000..d67646d --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php @@ -0,0 +1,138 @@ +beConstructedWith('getTitle'); + } + + function it_has_a_name() + { + $this->getName()->shouldReturn('getTitle'); + } + + function it_has_public_visibility_by_default() + { + $this->getVisibility()->shouldReturn('public'); + } + + function its_visibility_is_mutable() + { + $this->setVisibility('private'); + $this->getVisibility()->shouldReturn('private'); + } + + function it_is_not_static_by_default() + { + $this->shouldNotBeStatic(); + } + + function it_does_not_return_a_reference_by_default() + { + $this->returnsReference()->shouldReturn(false); + } + + function it_should_be_settable_as_returning_a_reference_through_setter() + { + $this->setReturnsReference(); + $this->returnsReference()->shouldReturn(true); + } + + function it_should_be_settable_as_static_through_setter() + { + $this->setStatic(); + $this->shouldBeStatic(); + } + + function it_accepts_only_supported_visibilities() + { + $this->shouldThrow('InvalidArgumentException')->duringSetVisibility('stealth'); + } + + function it_lowercases_visibility_before_setting_it() + { + $this->setVisibility('Public'); + $this->getVisibility()->shouldReturn('public'); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument2 + */ + function its_useParentCode_causes_method_to_call_parent($argument1, $argument2) + { + $argument1->getName()->willReturn('objectName'); + $argument2->getName()->willReturn('default'); + + $this->addArgument($argument1); + $this->addArgument($argument2); + + $this->useParentCode(); + + $this->getCode()->shouldReturn( + 'return parent::getTitle($objectName, $default);' + ); + } + + function its_code_is_mutable() + { + $this->setCode('echo "code";'); + $this->getCode()->shouldReturn('echo "code";'); + } + + function its_reference_returning_methods_will_generate_exceptions() + { + $this->setCode('echo "code";'); + $this->setReturnsReference(); + $this->getCode()->shouldReturn("throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), 'getTitle');"); + } + + function its_setCode_provided_with_null_cleans_method_body() + { + $this->setCode(null); + $this->getCode()->shouldReturn(''); + } + + function it_is_constructable_with_code() + { + $this->beConstructedWith('getTitle', 'die();'); + $this->getCode()->shouldReturn('die();'); + } + + function it_does_not_have_arguments_by_default() + { + $this->getArguments()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument1 + * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument2 + */ + function it_supports_adding_arguments($argument1, $argument2) + { + $this->addArgument($argument1); + $this->addArgument($argument2); + + $this->getArguments()->shouldReturn(array($argument1, $argument2)); + } + + function it_does_not_have_return_type_by_default() + { + $this->hasReturnType()->shouldReturn(false); + } + + function it_setReturnType_sets_return_type() + { + $returnType = 'string'; + + $this->setReturnType($returnType); + + $this->hasReturnType()->shouldReturn(true); + $this->getReturnType()->shouldReturn($returnType); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/LazyDoubleSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/LazyDoubleSpec.php new file mode 100644 index 0000000..7026126 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/LazyDoubleSpec.php @@ -0,0 +1,96 @@ +beConstructedWith($doubler); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double + */ + function it_returns_anonymous_double_instance_by_default($doubler, $double) + { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance()->shouldReturn($double); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double + * @param \ReflectionClass $class + */ + function it_returns_class_double_instance_if_set($doubler, $double, $class) + { + $doubler->double($class, array())->willReturn($double); + + $this->setParentClass($class); + + $this->getInstance()->shouldReturn($double); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double1 + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double2 + */ + function it_returns_same_double_instance_if_called_2_times( + $doubler, $double1, $double2 + ) + { + $doubler->double(null, array())->willReturn($double1); + $doubler->double(null, array())->willReturn($double2); + + $this->getInstance()->shouldReturn($double2); + $this->getInstance()->shouldReturn($double2); + } + + function its_setParentClass_throws_ClassNotFoundException_if_class_not_found() + { + $this->shouldThrow('Prophecy\Exception\Doubler\ClassNotFoundException') + ->duringSetParentClass('SomeUnexistingClass'); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double + */ + function its_setParentClass_throws_exception_if_prophecy_is_already_created( + $doubler, $double + ) + { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance(); + + $this->shouldThrow('Prophecy\Exception\Doubler\DoubleException') + ->duringSetParentClass('stdClass'); + } + + function its_addInterface_throws_InterfaceNotFoundException_if_no_interface_found() + { + $this->shouldThrow('Prophecy\Exception\Doubler\InterfaceNotFoundException') + ->duringAddInterface('SomeUnexistingInterface'); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $double + */ + function its_addInterface_throws_exception_if_prophecy_is_already_created( + $doubler, $double + ) + { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance(); + + $this->shouldThrow('Prophecy\Exception\Doubler\DoubleException') + ->duringAddInterface('ArrayAccess'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Doubler/NameGeneratorSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/NameGeneratorSpec.php new file mode 100644 index 0000000..a3e7491 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Doubler/NameGeneratorSpec.php @@ -0,0 +1,72 @@ +getName()->willReturn('stdClass'); + $this->name($class, array())->shouldStartWith('Double\stdClass\\'); + } + + /** + * @param \ReflectionClass $class + */ + function its_name_generates_name_based_on_namespaced_class_reflection($class) + { + $class->getName()->willReturn('Some\Custom\Class'); + $this->name($class, array())->shouldStartWith('Double\Some\Custom\Class\P'); + } + + /** + * @param \ReflectionClass $interface1 + * @param \ReflectionClass $interface2 + */ + function its_name_generates_name_based_on_interface_shortnames($interface1, $interface2) + { + $interface1->getShortName()->willReturn('HandlerInterface'); + $interface2->getShortName()->willReturn('LoaderInterface'); + + $this->name(null, array($interface1, $interface2))->shouldStartWith( + 'Double\HandlerInterface\LoaderInterface\P' + ); + } + + function it_generates_proper_name_for_no_class_and_interfaces_list() + { + $this->name(null, array())->shouldStartWith('Double\stdClass\P'); + } + + /** + * @param \ReflectionClass $class + * @param \ReflectionClass $interface1 + * @param \ReflectionClass $interface2 + */ + function its_name_generates_name_based_only_on_class_if_its_available( + $class, $interface1, $interface2 + ) + { + $class->getName()->willReturn('Some\Custom\Class'); + $interface1->getShortName()->willReturn('HandlerInterface'); + $interface2->getShortName()->willReturn('LoaderInterface'); + + $this->name($class, array($interface1, $interface2))->shouldStartWith( + 'Double\Some\Custom\Class\P' + ); + } + + public function getMatchers() + { + return array( + 'startWith' => function ($subject, $string) { + return 0 === strpos($subject, $string); + }, + ); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php new file mode 100644 index 0000000..6fd1a5c --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php @@ -0,0 +1,32 @@ +beConstructedWith('msg', $objectProphecy, 'getName', array('arg1', 'arg2')); + } + + function it_is_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ObjectProphecyException'); + } + + function it_exposes_method_name_through_getter() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_exposes_arguments_through_getter() + { + $this->getArguments()->shouldReturn(array('arg1', 'arg2')); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php new file mode 100644 index 0000000..5824138 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php @@ -0,0 +1,28 @@ +beConstructedWith('', $node); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } + + function it_contains_a_reflected_node($node) + { + $this->getClassNode()->shouldReturn($node); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php new file mode 100644 index 0000000..21e31a3 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php @@ -0,0 +1,27 @@ +beConstructedWith('', $class); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } + + function it_contains_a_reflected_class_link($class) + { + $this->getReflectedClass()->shouldReturn($class); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php new file mode 100644 index 0000000..251512b --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php @@ -0,0 +1,25 @@ +beConstructedWith('msg', 'CustomClass'); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoubleException'); + } + + function its_getClassname_returns_classname() + { + $this->getClassname()->shouldReturn('CustomClass'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php new file mode 100644 index 0000000..6fe5a19 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php @@ -0,0 +1,14 @@ +shouldBeAnInstanceOf('RuntimeException'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php new file mode 100644 index 0000000..ad1a439 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php @@ -0,0 +1,24 @@ +beConstructedWith('msg', 'CustomInterface'); + } + + function it_extends_ClassNotFoundException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\ClassNotFoundException'); + } + + function its_getClassname_returns_classname() + { + $this->getClassname()->shouldReturn('CustomInterface'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php new file mode 100644 index 0000000..a889dd7 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php @@ -0,0 +1,40 @@ +beConstructedWith('', 'User', 'getName', array(1, 2, 3)); + } + + function it_is_DoubleException() + { + $this->shouldHaveType('Prophecy\Exception\Doubler\DoubleException'); + } + + function it_has_MethodName() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_has_classnamej() + { + $this->getClassname()->shouldReturn('User'); + } + + function it_has_an_arguments_list() + { + $this->getArguments()->shouldReturn(array(1, 2, 3)); + } + + function it_has_a_default_null_argument_list() + { + $this->beConstructedWith('', 'User', 'getName'); + $this->getArguments()->shouldReturn(null); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php new file mode 100644 index 0000000..22a5ebd --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php @@ -0,0 +1,57 @@ +beConstructedWith(null); + } + + function it_is_prediction_exception() + { + $this->shouldBeAnInstanceOf('RuntimeException'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prediction\PredictionException'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + */ + function it_can_store_objectProphecy_link($object) + { + $this->setObjectProphecy($object); + $this->getObjectProphecy()->shouldReturn($object); + } + + function it_should_not_have_exceptions_at_the_beginning() + { + $this->getExceptions()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Exception\Prediction\PredictionException $exception + */ + function it_should_append_exception_through_append_method($exception) + { + $exception->getMessage()->willReturn('Exception #1'); + + $this->append($exception); + + $this->getExceptions()->shouldReturn(array($exception)); + } + + /** + * @param \Prophecy\Exception\Prediction\PredictionException $exception + */ + function it_should_update_message_during_append($exception) + { + $exception->getMessage()->willReturn('Exception #1'); + + $this->append($exception); + + $this->getMessage()->shouldReturn(" Exception #1"); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php new file mode 100644 index 0000000..473f1a2 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php @@ -0,0 +1,29 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy); + } + + function it_is_PredictionException() + { + $this->shouldHaveType('Prophecy\Exception\Prediction\PredictionException'); + } + + function it_extends_MethodProphecyException() + { + $this->shouldHaveType('Prophecy\Exception\Prophecy\MethodProphecyException'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php new file mode 100644 index 0000000..adad975 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php @@ -0,0 +1,31 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy, 5, array($call1, $call2)); + } + + function it_extends_UnexpectedCallsException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prediction\UnexpectedCallsException'); + } + + function it_should_expose_expectedCount_through_getter() + { + $this->getExpectedCount()->shouldReturn(5); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php new file mode 100644 index 0000000..c0fe24d --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php @@ -0,0 +1,36 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy, array($call1, $call2)); + } + + function it_is_PredictionException() + { + $this->shouldHaveType('Prophecy\Exception\Prediction\PredictionException'); + } + + function it_extends_MethodProphecyException() + { + $this->shouldHaveType('Prophecy\Exception\Prophecy\MethodProphecyException'); + } + + function it_should_expose_calls_list_through_getter($call1, $call2) + { + $this->getCalls()->shouldReturn(array($call1, $call2)); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php new file mode 100644 index 0000000..97cf9e1 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php @@ -0,0 +1,30 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy); + } + + function it_extends_DoubleException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ObjectProphecyException'); + } + + function it_holds_a_stub_reference($methodProphecy) + { + $this->getMethodProphecy()->shouldReturn($methodProphecy); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php new file mode 100644 index 0000000..bcacfed --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php @@ -0,0 +1,27 @@ +beConstructedWith('message', $objectProphecy); + } + + function it_should_be_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ProphecyException'); + } + + function it_holds_double_reference($objectProphecy) + { + $this->getObjectProphecy()->shouldReturn($objectProphecy); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallPredictionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallPredictionSpec.php new file mode 100644 index 0000000..3da8c59 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallPredictionSpec.php @@ -0,0 +1,42 @@ +shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call + */ + function it_does_nothing_if_there_is_more_than_one_call_been_made($object, $method, $call) + { + $this->check(array($call), $object, $method)->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_throws_NoCallsException_if_no_calls_found($object, $method, $arguments) + { + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + $object->reveal()->willReturn(new \stdClass()); + $object->findProphecyMethodCalls('getName', Argument::any())->willReturn(array()); + + $this->shouldThrow('Prophecy\Exception\Prediction\NoCallsException') + ->duringCheck(array(), $object, $method); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallTimesPredictionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallTimesPredictionSpec.php new file mode 100644 index 0000000..c670892 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallTimesPredictionSpec.php @@ -0,0 +1,54 @@ +beConstructedWith(2); + } + + function it_is_prediction() + { + $this->shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_does_nothing_if_there_were_exact_amount_of_calls_being_made( + $object, $method, $call1, $call2 + ) + { + $this->check(array($call1, $call2), $object, $method)->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_throws_UnexpectedCallsCountException_if_calls_found( + $object, $method, $call, $arguments + ) + { + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + + $call->getMethodName()->willReturn('getName'); + $call->getArguments()->willReturn(array(5, 4, 'three')); + $call->getCallPlace()->willReturn('unknown'); + + $this->shouldThrow('Prophecy\Exception\Prediction\UnexpectedCallsCountException') + ->duringCheck(array($call), $object, $method); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallbackPredictionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallbackPredictionSpec.php new file mode 100644 index 0000000..7fe475e --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Prediction/CallbackPredictionSpec.php @@ -0,0 +1,36 @@ +beConstructedWith('get_class'); + } + + function it_is_prediction() + { + $this->shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call + */ + function it_proxies_call_to_callback($object, $method, $call) + { + $returnFirstCallCallback = function ($calls, $object, $method) { + throw new RuntimeException; + }; + + $this->beConstructedWith($returnFirstCallCallback); + + $this->shouldThrow('RuntimeException')->duringCheck(array($call), $object, $method); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Prediction/NoCallsPredictionSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Prediction/NoCallsPredictionSpec.php new file mode 100644 index 0000000..a3ef9bc --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Prediction/NoCallsPredictionSpec.php @@ -0,0 +1,43 @@ +shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_does_nothing_if_there_is_no_calls_made($object, $method) + { + $this->check(array(), $object, $method)->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + * @param \Prophecy\Call\Call $call + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_throws_UnexpectedCallsException_if_calls_found($object, $method, $call, $arguments) + { + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + + $call->getMethodName()->willReturn('getName'); + $call->getArguments()->willReturn(array(5, 4, 'three')); + $call->getCallPlace()->willReturn('unknown'); + + $this->shouldThrow('Prophecy\Exception\Prediction\UnexpectedCallsException') + ->duringCheck(array($call), $object, $method); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Promise/CallbackPromiseSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Promise/CallbackPromiseSpec.php new file mode 100644 index 0000000..5d99b1b --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Promise/CallbackPromiseSpec.php @@ -0,0 +1,110 @@ +beConstructedWith('get_class'); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_execute_closure_callback($object, $method) + { + $firstArgumentCallback = function ($args) { + return $args[0]; + }; + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_execute_static_array_callback($object, $method) + { + $firstArgumentCallback = array('spec\Prophecy\Promise\ClassCallback', 'staticCallbackMethod'); + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_execute_instance_array_callback($object, $method) + { + $class = new ClassCallback(); + $firstArgumentCallback = array($class, 'callbackMethod'); + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_execute_string_function_callback($object, $method) + { + $firstArgumentCallback = 'spec\Prophecy\Promise\functionCallbackFirstArgument'; + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + +} + +/** + * Class used to test callbackpromise + * + * @param array + * @return string + */ +class ClassCallback +{ + /** + * @param array $args + */ + function callbackMethod($args) + { + return $args[0]; + } + + /** + * @param array $args + */ + static function staticCallbackMethod($args) + { + return $args[0]; + } +} + +/** + * Callback function used to test callbackpromise + * + * @param array + * @return string + */ +function functionCallbackFirstArgument($args) +{ + return $args[0]; +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php new file mode 100644 index 0000000..4acb7bb --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php @@ -0,0 +1,41 @@ +shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_return_first_argument_if_provided($object, $method) + { + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_return_null_if_no_arguments_provided($object, $method) + { + $this->execute(array(), $object, $method)->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_should_return_nth_argument_if_provided($object, $method) + { + $this->beConstructedWith(1); + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('two'); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnPromiseSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnPromiseSpec.php new file mode 100644 index 0000000..18bfd87 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Promise/ReturnPromiseSpec.php @@ -0,0 +1,61 @@ +beConstructedWith(array(42)); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_returns_value_it_was_constructed_with($object, $method) + { + $this->execute(array(), $object, $method)->shouldReturn(42); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_always_returns_last_value_left_in_the_return_values($object, $method) + { + $this->execute(array(), $object, $method)->shouldReturn(42); + $this->execute(array(), $object, $method)->shouldReturn(42); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_consequently_returns_multiple_values_it_was_constructed_with($object, $method) + { + $this->beConstructedWith(array(42, 24, 12)); + + $this->execute(array(), $object, $method)->shouldReturn(42); + $this->execute(array(), $object, $method)->shouldReturn(24); + $this->execute(array(), $object, $method)->shouldReturn(12); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_returns_null_if_constructed_with_empty_array($object, $method) + { + $this->beConstructedWith(array()); + + $this->execute(array(), $object, $method)->shouldReturn(null); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Promise/ThrowPromiseSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Promise/ThrowPromiseSpec.php new file mode 100644 index 0000000..5f44897 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Promise/ThrowPromiseSpec.php @@ -0,0 +1,58 @@ +beConstructedWith('RuntimeException'); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_instantiates_and_throws_exception_from_provided_classname($object, $method) + { + $this->beConstructedWith('InvalidArgumentException'); + + $this->shouldThrow('InvalidArgumentException') + ->duringExecute(array(), $object, $method); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_instantiates_exceptions_with_required_arguments($object, $method) + { + $this->beConstructedWith('spec\Prophecy\Promise\RequiredArgumentException'); + + $this->shouldThrow('spec\Prophecy\Promise\RequiredArgumentException') + ->duringExecute(array(), $object, $method); + } + + /** + * @param \Prophecy\Prophecy\ObjectProphecy $object + * @param \Prophecy\Prophecy\MethodProphecy $method + */ + function it_throws_provided_exception($object, $method) + { + $this->beConstructedWith($exc = new \RuntimeException('Some exception')); + + $this->shouldThrow($exc)->duringExecute(array(), $object, $method); + } +} + +class RequiredArgumentException extends \Exception +{ + final public function __construct($message, $code) {} +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/MethodProphecySpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/MethodProphecySpec.php new file mode 100644 index 0000000..41ee8cd --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/MethodProphecySpec.php @@ -0,0 +1,384 @@ +reveal()->willReturn($reflection); + + $this->beConstructedWith($objectProphecy, 'getName', null); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Prophecy\MethodProphecy'); + } + + function its_constructor_throws_MethodNotFoundException_for_unexisting_method($objectProphecy) + { + $this->shouldThrow('Prophecy\Exception\Doubler\MethodNotFoundException')->during( + '__construct', array($objectProphecy, 'getUnexisting', null) + ); + } + + /** + * @param ClassWithFinalMethod $subject + */ + function its_constructor_throws_MethodProphecyException_for_final_methods($objectProphecy, $subject) + { + $objectProphecy->reveal()->willReturn($subject); + + $this->shouldThrow('Prophecy\Exception\Prophecy\MethodProphecyException')->during( + '__construct', array($objectProphecy, 'finalMethod', null) + ); + } + + function its_constructor_transforms_array_passed_as_3rd_argument_to_ArgumentsWildcard( + $objectProphecy + ) + { + $this->beConstructedWith($objectProphecy, 'getName', array(42, 33)); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldNotBe(null); + $wildcard->__toString()->shouldReturn('exact(42), exact(33)'); + } + + function its_constructor_does_not_touch_third_argument_if_it_is_null($objectProphecy) + { + $this->beConstructedWith($objectProphecy, 'getName', null); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldBe(null); + } + + /** + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_records_promise_through_will_method($promise, $objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->will($promise); + $this->getPromise()->shouldReturn($promise); + } + + /** + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_adds_itself_to_ObjectProphecy_during_call_to_will($objectProphecy, $promise) + { + $objectProphecy->addMethodProphecy($this)->shouldBeCalled(); + + $this->will($promise); + } + + function it_adds_ReturnPromise_during_willReturn_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturn(42); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ReturnPromise'); + } + + function it_adds_ThrowPromise_during_willThrow_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willThrow('RuntimeException'); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ThrowPromise'); + } + + function it_adds_ReturnArgumentPromise_during_willReturnArgument_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturnArgument(); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ReturnArgumentPromise'); + } + + function it_adds_ReturnArgumentPromise_during_willReturnArgument_call_with_index_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturnArgument(1); + $promise = $this->getPromise(); + $promise->shouldBeAnInstanceOf('Prophecy\Promise\ReturnArgumentPromise'); + $promise->execute(array('one', 'two'), $objectProphecy, $this)->shouldReturn('two'); + } + + function it_adds_CallbackPromise_during_will_call_with_callback_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $callback = function () {}; + + $this->will($callback); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\CallbackPromise'); + } + + /** + * @param \Prophecy\Prediction\PredictionInterface $prediction + */ + function it_records_prediction_through_should_method($prediction, $objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('should', array($prediction)); + $this->getPrediction()->shouldReturn($prediction); + } + + function it_adds_CallbackPrediction_during_should_call_with_callback_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $callback = function () {}; + + $this->callOnWrappedObject('should', array($callback)); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallbackPrediction'); + } + + /** + * @param \Prophecy\Prediction\PredictionInterface $prediction + */ + function it_adds_itself_to_ObjectProphecy_during_call_to_should($objectProphecy, $prediction) + { + $objectProphecy->addMethodProphecy($this)->shouldBeCalled(); + + $this->callOnWrappedObject('should', array($prediction)); + } + + function it_adds_CallPrediction_during_shouldBeCalled_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldBeCalled', array()); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallPrediction'); + } + + function it_adds_NoCallsPrediction_during_shouldNotBeCalled_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldNotBeCalled', array()); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\NoCallsPrediction'); + } + + function it_adds_CallTimesPrediction_during_shouldBeCalledTimes_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldBeCalledTimes', array(5)); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallTimesPrediction'); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_checks_prediction_via_shouldHave_method_call( + $objectProphecy, $arguments, $prediction, $call1, $call2 + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_sets_return_promise_during_shouldHave_call_if_none_was_set_before( + $objectProphecy, $arguments, $prediction, $call1, $call2 + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + + $this->getPromise()->shouldReturnAnInstanceOf('Prophecy\Promise\ReturnPromise'); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_does_not_set_return_promise_during_shouldHave_call_if_it_was_set_before( + $objectProphecy, $arguments, $prediction, $call1, $call2, $promise + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + + $this->getPromise()->shouldReturn($promise); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction1 + * @param \Prophecy\Prediction\PredictionInterface $prediction2 + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_records_checked_predictions( + $objectProphecy, $arguments, $prediction1, $prediction2, $call1, $call2, $promise + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction1->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willReturn(); + $prediction2->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willReturn(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction1)); + $this->callOnWrappedObject('shouldHave', array($prediction2)); + + $this->getCheckedPredictions()->shouldReturn(array($prediction1, $prediction2)); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + * @param \Prophecy\Promise\PromiseInterface $promise + */ + function it_records_even_failed_checked_predictions( + $objectProphecy, $arguments, $prediction, $call1, $call2, $promise + ) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willThrow(new \RuntimeException()); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + + try { + $this->callOnWrappedObject('shouldHave', array($prediction)); + } catch (\Exception $e) {} + + $this->getCheckedPredictions()->shouldReturn(array($prediction)); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_checks_prediction_via_shouldHave_method_call_with_callback( + $objectProphecy, $arguments, $prediction, $call1, $call2 + ) + { + $callback = function ($calls, $object, $method) { + throw new \RuntimeException; + }; + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->shouldThrow('RuntimeException')->duringShouldHave($callback); + } + + function it_does_nothing_during_checkPrediction_if_no_prediction_set() + { + $this->checkPrediction()->shouldReturn(null); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + * @param \Prophecy\Prediction\PredictionInterface $prediction + * @param \Prophecy\Call\Call $call1 + * @param \Prophecy\Call\Call $call2 + */ + function it_checks_set_prediction_during_checkPrediction( + $objectProphecy, $arguments, $prediction, $call1, $call2 + ) + { + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->withArguments($arguments); + $this->callOnWrappedObject('should', array($prediction)); + $this->checkPrediction(); + } + + function it_links_back_to_ObjectProphecy_through_getter($objectProphecy) + { + $this->getObjectProphecy()->shouldReturn($objectProphecy); + } + + function it_has_MethodName() + { + $this->getMethodName()->shouldReturn('getName'); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $wildcard + */ + function it_contains_ArgumentsWildcard_it_was_constructed_with($objectProphecy, $wildcard) + { + $this->beConstructedWith($objectProphecy, 'getName', $wildcard); + + $this->getArgumentsWildcard()->shouldReturn($wildcard); + } + + /** + * @param \Prophecy\Argument\ArgumentsWildcard $wildcard + */ + function its_ArgumentWildcard_is_mutable_through_setter($wildcard) + { + $this->withArguments($wildcard); + + $this->getArgumentsWildcard()->shouldReturn($wildcard); + } + + function its_withArguments_transforms_passed_array_into_ArgumentsWildcard() + { + $this->withArguments(array(42, 33)); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldNotBe(null); + $wildcard->__toString()->shouldReturn('exact(42), exact(33)'); + } + + function its_withArguments_throws_exception_if_wrong_arguments_provided() + { + $this->shouldThrow('Prophecy\Exception\InvalidArgumentException')->duringWithArguments(42); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/ObjectProphecySpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/ObjectProphecySpec.php new file mode 100644 index 0000000..7e249d9 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/ObjectProphecySpec.php @@ -0,0 +1,319 @@ +beConstructedWith($lazyDouble); + + $lazyDouble->getInstance()->willReturn($double); + } + + function it_implements_ProphecyInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Prophecy\ProphecyInterface'); + } + + function it_sets_parentClass_during_willExtend_call($lazyDouble) + { + $lazyDouble->setParentClass('123')->shouldBeCalled(); + + $this->willExtend('123'); + } + + function it_adds_interface_during_willImplement_call($lazyDouble) + { + $lazyDouble->addInterface('222')->shouldBeCalled(); + + $this->willImplement('222'); + } + + function it_sets_constructor_arguments_during_willBeConstructedWith_call($lazyDouble) + { + $lazyDouble->setArguments(array(1, 2, 5))->shouldBeCalled(); + + $this->willBeConstructedWith(array(1, 2, 5)); + } + + function it_does_not_have_method_prophecies_by_default() + { + $this->getMethodProphecies()->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method1 + * @param \Prophecy\Prophecy\MethodProphecy $method2 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments + */ + function it_should_get_method_prophecies_by_method_name($method1, $method2, $arguments) + { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments); + $method2->getMethodName()->willReturn('setName'); + $method2->getArgumentsWildcard()->willReturn($arguments); + + $this->addMethodProphecy($method1); + $this->addMethodProphecy($method2); + + $methods = $this->getMethodProphecies('setName'); + $methods->shouldHaveCount(1); + $methods[0]->getMethodName()->shouldReturn('setName'); + } + + function it_should_return_empty_array_if_no_method_prophecies_found() + { + $methods = $this->getMethodProphecies('setName'); + $methods->shouldHaveCount(0); + } + + /** + * @param \Prophecy\Call\CallCenter $callCenter + */ + function it_should_proxy_makeProphecyMethodCall_to_CallCenter($lazyDouble, $callCenter) + { + $this->beConstructedWith($lazyDouble, $callCenter); + + $callCenter->makeCall($this->getWrappedObject(), 'setName', array('everzet'))->willReturn(42); + + $this->makeProphecyMethodCall('setName', array('everzet'))->shouldReturn(42); + } + + /** + * @param \Prophecy\Call\CallCenter $callCenter + * @param \Prophecy\Prophecy\RevealerInterface $revealer + */ + function it_should_reveal_arguments_and_return_values_from_callCenter( + $lazyDouble, $callCenter, $revealer + ) + { + $this->beConstructedWith($lazyDouble, $callCenter, $revealer); + + $revealer->reveal(array('question'))->willReturn(array('life')); + $revealer->reveal('answer')->willReturn(42); + + $callCenter->makeCall($this->getWrappedObject(), 'setName', array('life'))->willReturn('answer'); + + $this->makeProphecyMethodCall('setName', array('question'))->shouldReturn(42); + } + + /** + * @param \Prophecy\Call\CallCenter $callCenter + * @param \Prophecy\Argument\ArgumentsWildcard $wildcard + * @param \Prophecy\Call\Call $call + */ + function it_should_proxy_getProphecyMethodCalls_to_CallCenter( + $lazyDouble, $callCenter, $wildcard, $call + ) + { + $this->beConstructedWith($lazyDouble, $callCenter); + + $callCenter->findCalls('setName', $wildcard)->willReturn(array($call)); + + $this->findProphecyMethodCalls('setName', $wildcard)->shouldReturn(array($call)); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard + */ + function its_addMethodProphecy_adds_method_prophecy( + $methodProphecy, $argumentsWildcard + ) + { + $methodProphecy->getArgumentsWildcard()->willReturn($argumentsWildcard); + $methodProphecy->getMethodName()->willReturn('getUsername'); + + $this->addMethodProphecy($methodProphecy); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array($methodProphecy) + )); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy1 + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy2 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard1 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard2 + */ + function its_addMethodProphecy_handles_prophecies_with_different_arguments( + $methodProphecy1, $methodProphecy2, $argumentsWildcard1, $argumentsWildcard2 + ) + { + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->getMethodName()->willReturn('getUsername'); + + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->getMethodName()->willReturn('getUsername'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array( + $methodProphecy1, + $methodProphecy2, + ) + )); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy1 + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy2 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard1 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard2 + */ + function its_addMethodProphecy_handles_prophecies_for_different_methods( + $methodProphecy1, $methodProphecy2, $argumentsWildcard1, $argumentsWildcard2 + ) + { + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->getMethodName()->willReturn('getUsername'); + + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->getMethodName()->willReturn('isUsername'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array( + $methodProphecy1 + ), + 'isUsername' => array( + $methodProphecy2 + ) + )); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy + */ + function its_addMethodProphecy_throws_exception_when_method_has_no_ArgumentsWildcard( + $methodProphecy + ) + { + $methodProphecy->getArgumentsWildcard()->willReturn(null); + $methodProphecy->getObjectProphecy()->willReturn($this); + $methodProphecy->getMethodName()->willReturn('getTitle'); + + $this->shouldThrow('Prophecy\Exception\Prophecy\MethodProphecyException')->duringAddMethodProphecy( + $methodProphecy + ); + } + + function it_returns_null_after_checkPredictions_call_if_there_is_no_method_prophecies() + { + $this->checkProphecyMethodsPredictions()->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy1 + * @param \Prophecy\Prophecy\MethodProphecy $methodProphecy2 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard1 + * @param \Prophecy\Argument\ArgumentsWildcard $argumentsWildcard2 + */ + function it_throws_AggregateException_during_checkPredictions_if_predictions_fail( + $methodProphecy1, $methodProphecy2, $argumentsWildcard1, $argumentsWildcard2 + ) + { + $methodProphecy1->getMethodName()->willReturn('getName'); + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->checkPrediction() + ->willThrow('Prophecy\Exception\Prediction\AggregateException'); + + $methodProphecy2->getMethodName()->willReturn('setName'); + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->checkPrediction() + ->willThrow('Prophecy\Exception\Prediction\AggregateException'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->shouldThrow('Prophecy\Exception\Prediction\AggregateException') + ->duringCheckProphecyMethodsPredictions(); + } + + /** + * @param \Prophecy\Doubler\Doubler $doubler + * @param \Prophecy\Prophecy\ProphecySubjectInterface $reflection + */ + function it_returns_new_MethodProphecy_instance_for_arbitrary_call($doubler, $reflection) + { + $doubler->double(Argument::any())->willReturn($reflection); + + $return = $this->getProphecy(); + $return->shouldBeAnInstanceOf('Prophecy\Prophecy\MethodProphecy'); + $return->getMethodName()->shouldReturn('getProphecy'); + } + + /** + * @param \Prophecy\Doubler\Doubler $doubler + * @param \Prophecy\Prophecy\ProphecySubjectInterface $reflection + */ + function it_returns_same_MethodProphecy_for_same_registered_signature($doubler, $reflection) + { + $doubler->double(Argument::any())->willReturn($reflection); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(1, 2, 3)); + $methodProphecy2 = $this->getProphecy(1, 2, 3); + + $methodProphecy2->shouldBe($methodProphecy1); + } + + /** + * @param \Prophecy\Doubler\Doubler $doubler + * @param \Prophecy\Prophecy\ProphecySubjectInterface $reflection + */ + function it_returns_new_MethodProphecy_for_different_signatures($doubler, $reflection) + { + $doubler->double(Argument::any())->willReturn($reflection); + + $value = new ObjectProphecySpecFixtureB('ABC'); + $value2 = new ObjectProphecySpecFixtureB('CBA'); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(1, 2, 3, $value)); + $methodProphecy2 = $this->getProphecy(1, 2, 3, $value2); + + $methodProphecy2->shouldNotBe($methodProphecy1); + } + + /** + * @param \Prophecy\Doubler\Doubler $doubler + * @param \Prophecy\Prophecy\ProphecySubjectInterface $reflection + */ + function it_returns_new_MethodProphecy_for_all_callback_signatures($doubler, $reflection) + { + $doubler->double(Argument::any())->willReturn($reflection); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(function(){})); + $methodProphecy2 = $this->getProphecy(function(){}); + + $methodProphecy2->shouldNotBe($methodProphecy1); + } +} + +class ObjectProphecySpecFixtureA +{ + public $errors; +} + +class ObjectProphecySpecFixtureB extends ObjectProphecySpecFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/RevealerSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/RevealerSpec.php new file mode 100644 index 0000000..4d83d73 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Prophecy/RevealerSpec.php @@ -0,0 +1,51 @@ +shouldBeAnInstanceOf('Prophecy\Prophecy\RevealerInterface'); + } + + /** + * @param \Prophecy\Prophecy\ProphecyInterface $prophecy + * @param \stdClass $object + */ + function it_reveals_single_instance_of_ProphecyInterface($prophecy, $object) + { + $prophecy->reveal()->willReturn($object); + + $this->reveal($prophecy)->shouldReturn($object); + } + + /** + * @param \Prophecy\Prophecy\ProphecyInterface $prophecy1 + * @param \Prophecy\Prophecy\ProphecyInterface $prophecy2 + * @param \stdClass $object1 + * @param \stdClass $object2 + */ + function it_reveals_instances_of_ProphecyInterface_inside_array( + $prophecy1, $prophecy2, $object1, $object2 + ) + { + $prophecy1->reveal()->willReturn($object1); + $prophecy2->reveal()->willReturn($object2); + + $this->reveal(array( + array('item' => $prophecy2), + $prophecy1 + ))->shouldReturn(array( + array('item' => $object2), + $object1 + )); + } + + function it_does_not_touch_non_prophecy_interface() + { + $this->reveal(42)->shouldReturn(42); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/ProphetSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/ProphetSpec.php new file mode 100644 index 0000000..74d5976 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/ProphetSpec.php @@ -0,0 +1,91 @@ +double(null, array())->willReturn($double); + + $this->beConstructedWith($doubler); + } + + function it_constructs_new_prophecy_on_prophesize_call() + { + $prophecy = $this->prophesize(); + $prophecy->shouldBeAnInstanceOf('Prophecy\Prophecy\ObjectProphecy'); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $newDouble + */ + function it_constructs_new_prophecy_with_parent_class_if_specified($doubler, $newDouble) + { + $doubler->double(Argument::any(), array())->willReturn($newDouble); + + $this->prophesize('Prophecy\Prophet')->reveal()->shouldReturn($newDouble); + } + + /** + * @param \Prophecy\Prophecy\ProphecySubjectInterface $newDouble + */ + function it_constructs_new_prophecy_with_interface_if_specified($doubler, $newDouble) + { + $doubler->double(null, Argument::any())->willReturn($newDouble); + + $this->prophesize('ArrayAccess')->reveal()->shouldReturn($newDouble); + } + + function it_exposes_all_created_prophecies_through_getter() + { + $prophecy1 = $this->prophesize(); + $prophecy2 = $this->prophesize(); + + $this->getProphecies()->shouldReturn(array($prophecy1, $prophecy2)); + } + + function it_does_nothing_during_checkPredictions_call_if_no_predictions_defined() + { + $this->checkPredictions()->shouldReturn(null); + } + + /** + * @param \Prophecy\Prophecy\MethodProphecy $method1 + * @param \Prophecy\Prophecy\MethodProphecy $method2 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments1 + * @param \Prophecy\Argument\ArgumentsWildcard $arguments2 + */ + function it_throws_AggregateException_if_defined_predictions_fail( + $method1, $method2, $arguments1, $arguments2 + ) + { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $method1->checkPrediction()->willReturn(null); + + $method2->getMethodName()->willReturn('isSet'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $method2->checkPrediction()->willThrow( + 'Prophecy\Exception\Prediction\AggregateException' + ); + + $this->prophesize()->addMethodProphecy($method1); + $this->prophesize()->addMethodProphecy($method2); + + $this->shouldThrow('Prophecy\Exception\Prediction\AggregateException') + ->duringCheckPredictions(); + } + + function it_exposes_doubler_through_getter($doubler) + { + $this->getDoubler()->shouldReturn($doubler); + } +} diff --git a/vendor/phpspec/prophecy/spec/Prophecy/Util/StringUtilSpec.php b/vendor/phpspec/prophecy/spec/Prophecy/Util/StringUtilSpec.php new file mode 100644 index 0000000..a4eef59 --- /dev/null +++ b/vendor/phpspec/prophecy/spec/Prophecy/Util/StringUtilSpec.php @@ -0,0 +1,97 @@ +stringify(42)->shouldReturn('42'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->stringify('some string')->shouldReturn('"some string"'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->stringify("some\nstring")->shouldReturn('"some\\nstring"'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->stringify(42.3)->shouldReturn('42.3'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->stringify(true)->shouldReturn('true'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->stringify(false)->shouldReturn('false'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->stringify(null)->shouldReturn('null'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->stringify(array())->shouldReturn('[]'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->stringify(array('zet', 42))->shouldReturn('["zet", 42]'); + } + + function it_generates_proper_string_representation_for_hash_containing_one_value() + { + $this->stringify(array('ever' => 'zet'))->shouldReturn('["ever" => "zet"]'); + } + + function it_generates_proper_string_representation_for_hash() + { + $this->stringify(array('ever' => 'zet', 52 => 'hey', 'num' => 42))->shouldReturn( + '["ever" => "zet", 52 => "hey", "num" => 42]' + ); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->stringify($resource)->shouldReturn('stream:'.$resource); + } + + /** + * @param \stdClass $object + */ + function it_generates_proper_string_representation_for_object($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ) . " Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n)"; + + $this->stringify($object)->shouldReturn("$objHash"); + } + + /** + * @param stdClass $object + */ + function it_generates_proper_string_representation_for_object_without_exporting($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->stringify($object, false)->shouldReturn("$objHash"); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument.php b/vendor/phpspec/prophecy/src/Prophecy/Argument.php new file mode 100644 index 0000000..f2b3364 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument.php @@ -0,0 +1,198 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy; + +use Prophecy\Argument\Token; + +/** + * Argument tokens shortcuts. + * + * @author Konstantin Kudryashov + */ +class Argument +{ + /** + * Checks that argument is exact value or object. + * + * @param mixed $value + * + * @return Token\ExactValueToken + */ + public static function exact($value) + { + return new Token\ExactValueToken($value); + } + + /** + * Checks that argument is of specific type or instance of specific class. + * + * @param string $type Type name (`integer`, `string`) or full class name + * + * @return Token\TypeToken + */ + public static function type($type) + { + return new Token\TypeToken($type); + } + + /** + * Checks that argument object has specific state. + * + * @param string $methodName + * @param mixed $value + * + * @return Token\ObjectStateToken + */ + public static function which($methodName, $value) + { + return new Token\ObjectStateToken($methodName, $value); + } + + /** + * Checks that argument matches provided callback. + * + * @param callable $callback + * + * @return Token\CallbackToken + */ + public static function that($callback) + { + return new Token\CallbackToken($callback); + } + + /** + * Matches any single value. + * + * @return Token\AnyValueToken + */ + public static function any() + { + return new Token\AnyValueToken; + } + + /** + * Matches all values to the rest of the signature. + * + * @return Token\AnyValuesToken + */ + public static function cetera() + { + return new Token\AnyValuesToken; + } + + /** + * Checks that argument matches all tokens + * + * @param mixed ... a list of tokens + * + * @return Token\LogicalAndToken + */ + public static function allOf() + { + return new Token\LogicalAndToken(func_get_args()); + } + + /** + * Checks that argument array or countable object has exact number of elements. + * + * @param integer $value array elements count + * + * @return Token\ArrayCountToken + */ + public static function size($value) + { + return new Token\ArrayCountToken($value); + } + + /** + * Checks that argument array contains (key, value) pair + * + * @param mixed $key exact value or token + * @param mixed $value exact value or token + * + * @return Token\ArrayEntryToken + */ + public static function withEntry($key, $value) + { + return new Token\ArrayEntryToken($key, $value); + } + + /** + * Checks that arguments array entries all match value + * + * @param mixed $value + * + * @return Token\ArrayEveryEntryToken + */ + public static function withEveryEntry($value) + { + return new Token\ArrayEveryEntryToken($value); + } + + /** + * Checks that argument array contains value + * + * @param mixed $value + * + * @return Token\ArrayEntryToken + */ + public static function containing($value) + { + return new Token\ArrayEntryToken(self::any(), $value); + } + + /** + * Checks that argument array has key + * + * @param mixed $key exact value or token + * + * @return Token\ArrayEntryToken + */ + public static function withKey($key) + { + return new Token\ArrayEntryToken($key, self::any()); + } + + /** + * Checks that argument does not match the value|token. + * + * @param mixed $value either exact value or argument token + * + * @return Token\LogicalNotToken + */ + public static function not($value) + { + return new Token\LogicalNotToken($value); + } + + /** + * @param string $value + * + * @return Token\StringContainsToken + */ + public static function containingString($value) + { + return new Token\StringContainsToken($value); + } + + /** + * Checks that argument is identical value. + * + * @param mixed $value + * + * @return Token\IdenticalValueToken + */ + public static function is($value) + { + return new Token\IdenticalValueToken($value); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php new file mode 100644 index 0000000..a088f21 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php @@ -0,0 +1,101 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument; + +/** + * Arguments wildcarding. + * + * @author Konstantin Kudryashov + */ +class ArgumentsWildcard +{ + /** + * @var Token\TokenInterface[] + */ + private $tokens = array(); + private $string; + + /** + * Initializes wildcard. + * + * @param array $arguments Array of argument tokens or values + */ + public function __construct(array $arguments) + { + foreach ($arguments as $argument) { + if (!$argument instanceof Token\TokenInterface) { + $argument = new Token\ExactValueToken($argument); + } + + $this->tokens[] = $argument; + } + } + + /** + * Calculates wildcard match score for provided arguments. + * + * @param array $arguments + * + * @return false|int False OR integer score (higher - better) + */ + public function scoreArguments(array $arguments) + { + if (0 == count($arguments) && 0 == count($this->tokens)) { + return 1; + } + + $arguments = array_values($arguments); + $totalScore = 0; + foreach ($this->tokens as $i => $token) { + $argument = isset($arguments[$i]) ? $arguments[$i] : null; + if (1 >= $score = $token->scoreArgument($argument)) { + return false; + } + + $totalScore += $score; + + if (true === $token->isLast()) { + return $totalScore; + } + } + + if (count($arguments) > count($this->tokens)) { + return false; + } + + return $totalScore; + } + + /** + * Returns string representation for wildcard. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = implode(', ', array_map(function ($token) { + return (string) $token; + }, $this->tokens)); + } + + return $this->string; + } + + /** + * @return array + */ + public function getTokens() + { + return $this->tokens; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php new file mode 100644 index 0000000..5098811 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Any single value token. + * + * @author Konstantin Kudryashov + */ +class AnyValueToken implements TokenInterface +{ + /** + * Always scores 3 for any argument. + * + * @param $argument + * + * @return int + */ + public function scoreArgument($argument) + { + return 3; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return '*'; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php new file mode 100644 index 0000000..f76b17b --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Any values token. + * + * @author Konstantin Kudryashov + */ +class AnyValuesToken implements TokenInterface +{ + /** + * Always scores 2 for any argument. + * + * @param $argument + * + * @return int + */ + public function scoreArgument($argument) + { + return 2; + } + + /** + * Returns true to stop wildcard from processing other tokens. + * + * @return bool + */ + public function isLast() + { + return true; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return '* [, ...]'; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php new file mode 100644 index 0000000..96b4bef --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php @@ -0,0 +1,86 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Array elements count token. + * + * @author Boris Mikhaylov + */ + +class ArrayCountToken implements TokenInterface +{ + private $count; + + /** + * @param integer $value + */ + public function __construct($value) + { + $this->count = $value; + } + + /** + * Scores 6 when argument has preset number of elements. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return $this->isCountable($argument) && $this->hasProperCount($argument) ? 6 : false; + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('count(%s)', $this->count); + } + + /** + * Returns true if object is either array or instance of \Countable + * + * @param $argument + * @return bool + */ + private function isCountable($argument) + { + return (is_array($argument) || $argument instanceof \Countable); + } + + /** + * Returns true if $argument has expected number of elements + * + * @param array|\Countable $argument + * + * @return bool + */ + private function hasProperCount($argument) + { + return $this->count === count($argument); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php new file mode 100644 index 0000000..0305fc7 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php @@ -0,0 +1,143 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Array entry token. + * + * @author Boris Mikhaylov + */ +class ArrayEntryToken implements TokenInterface +{ + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $key; + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $value; + + /** + * @param mixed $key exact value or token + * @param mixed $value exact value or token + */ + public function __construct($key, $value) + { + $this->key = $this->wrapIntoExactValueToken($key); + $this->value = $this->wrapIntoExactValueToken($value); + } + + /** + * Scores half of combined scores from key and value tokens for same entry. Capped at 8. + * If argument implements \ArrayAccess without \Traversable, then key token is restricted to ExactValueToken. + * + * @param array|\ArrayAccess|\Traversable $argument + * + * @throws \Prophecy\Exception\InvalidArgumentException + * @return bool|int + */ + public function scoreArgument($argument) + { + if ($argument instanceof \Traversable) { + $argument = iterator_to_array($argument); + } + + if ($argument instanceof \ArrayAccess) { + $argument = $this->convertArrayAccessToEntry($argument); + } + + if (!is_array($argument) || empty($argument)) { + return false; + } + + $keyScores = array_map(array($this->key,'scoreArgument'), array_keys($argument)); + $valueScores = array_map(array($this->value,'scoreArgument'), $argument); + $scoreEntry = function ($value, $key) { + return $value && $key ? min(8, ($key + $value) / 2) : false; + }; + + return max(array_map($scoreEntry, $valueScores, $keyScores)); + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('[..., %s => %s, ...]', $this->key, $this->value); + } + + /** + * Returns key + * + * @return TokenInterface + */ + public function getKey() + { + return $this->key; + } + + /** + * Returns value + * + * @return TokenInterface + */ + public function getValue() + { + return $this->value; + } + + /** + * Wraps non token $value into ExactValueToken + * + * @param $value + * @return TokenInterface + */ + private function wrapIntoExactValueToken($value) + { + return $value instanceof TokenInterface ? $value : new ExactValueToken($value); + } + + /** + * Converts instance of \ArrayAccess to key => value array entry + * + * @param \ArrayAccess $object + * + * @return array|null + * @throws \Prophecy\Exception\InvalidArgumentException + */ + private function convertArrayAccessToEntry(\ArrayAccess $object) + { + if (!$this->key instanceof ExactValueToken) { + throw new InvalidArgumentException(sprintf( + 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL. + 'But you used `%s`.', + $this->key + )); + } + + $key = $this->key->getValue(); + + return $object->offsetExists($key) ? array($key => $object[$key]) : array(); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php new file mode 100644 index 0000000..5d41fa4 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php @@ -0,0 +1,82 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Array every entry token. + * + * @author Adrien Brault + */ +class ArrayEveryEntryToken implements TokenInterface +{ + /** + * @var TokenInterface + */ + private $value; + + /** + * @param mixed $value exact value or token + */ + public function __construct($value) + { + if (!$value instanceof TokenInterface) { + $value = new ExactValueToken($value); + } + + $this->value = $value; + } + + /** + * {@inheritdoc} + */ + public function scoreArgument($argument) + { + if (!$argument instanceof \Traversable && !is_array($argument)) { + return false; + } + + $scores = array(); + foreach ($argument as $key => $argumentEntry) { + $scores[] = $this->value->scoreArgument($argumentEntry); + } + + if (empty($scores) || in_array(false, $scores, true)) { + return false; + } + + return array_sum($scores) / count($scores); + } + + /** + * {@inheritdoc} + */ + public function isLast() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return sprintf('[%s, ..., %s]', $this->value, $this->value); + } + + /** + * @return TokenInterface + */ + public function getValue() + { + return $this->value; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php new file mode 100644 index 0000000..f45ba20 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php @@ -0,0 +1,75 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Callback-verified token. + * + * @author Konstantin Kudryashov + */ +class CallbackToken implements TokenInterface +{ + private $callback; + + /** + * Initializes token. + * + * @param callable $callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackToken, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Scores 7 if callback returns true, false otherwise. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return call_user_func($this->callback, $argument) ? 7 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return 'callback()'; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php new file mode 100644 index 0000000..aa960f3 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php @@ -0,0 +1,116 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Util\StringUtil; + +/** + * Exact value token. + * + * @author Konstantin Kudryashov + */ +class ExactValueToken implements TokenInterface +{ + private $value; + private $string; + private $util; + private $comparatorFactory; + + /** + * Initializes token. + * + * @param mixed $value + * @param StringUtil $util + * @param ComparatorFactory $comparatorFactory + */ + public function __construct($value, StringUtil $util = null, ComparatorFactory $comparatorFactory = null) + { + $this->value = $value; + $this->util = $util ?: new StringUtil(); + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Scores 10 if argument matches preset value. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (is_object($argument) && is_object($this->value)) { + $comparator = $this->comparatorFactory->getComparatorFor( + $argument, $this->value + ); + + try { + $comparator->assertEquals($argument, $this->value); + return 10; + } catch (ComparisonFailure $failure) {} + } + + // If either one is an object it should be castable to a string + if (is_object($argument) xor is_object($this->value)) { + if (is_object($argument) && !method_exists($argument, '__toString')) { + return false; + } + + if (is_object($this->value) && !method_exists($this->value, '__toString')) { + return false; + } + } elseif (is_numeric($argument) && is_numeric($this->value)) { + // noop + } elseif (gettype($argument) !== gettype($this->value)) { + return false; + } + + return $argument == $this->value ? 10 : false; + } + + /** + * Returns preset value against which token checks arguments. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = sprintf('exact(%s)', $this->util->stringify($this->value)); + } + + return $this->string; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php new file mode 100644 index 0000000..0b6d23a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php @@ -0,0 +1,74 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Util\StringUtil; + +/** + * Identical value token. + * + * @author Florian Voutzinos + */ +class IdenticalValueToken implements TokenInterface +{ + private $value; + private $string; + private $util; + + /** + * Initializes token. + * + * @param mixed $value + * @param StringUtil $util + */ + public function __construct($value, StringUtil $util = null) + { + $this->value = $value; + $this->util = $util ?: new StringUtil(); + } + + /** + * Scores 11 if argument matches preset value. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return $argument === $this->value ? 11 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = sprintf('identical(%s)', $this->util->stringify($this->value)); + } + + return $this->string; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php new file mode 100644 index 0000000..4ee1b25 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php @@ -0,0 +1,80 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Logical AND token. + * + * @author Boris Mikhaylov + */ +class LogicalAndToken implements TokenInterface +{ + private $tokens = array(); + + /** + * @param array $arguments exact values or tokens + */ + public function __construct(array $arguments) + { + foreach ($arguments as $argument) { + if (!$argument instanceof TokenInterface) { + $argument = new ExactValueToken($argument); + } + $this->tokens[] = $argument; + } + } + + /** + * Scores maximum score from scores returned by tokens for this argument if all of them score. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (0 === count($this->tokens)) { + return false; + } + + $maxScore = 0; + foreach ($this->tokens as $token) { + $score = $token->scoreArgument($argument); + if (false === $score) { + return false; + } + $maxScore = max($score, $maxScore); + } + + return $maxScore; + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('bool(%s)', implode(' AND ', $this->tokens)); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php new file mode 100644 index 0000000..623efa5 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php @@ -0,0 +1,73 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Logical NOT token. + * + * @author Boris Mikhaylov + */ +class LogicalNotToken implements TokenInterface +{ + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $token; + + /** + * @param mixed $value exact value or token + */ + public function __construct($value) + { + $this->token = $value instanceof TokenInterface? $value : new ExactValueToken($value); + } + + /** + * Scores 4 when preset token does not match the argument. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return false === $this->token->scoreArgument($argument) ? 4 : false; + } + + /** + * Returns true if preset token is last. + * + * @return bool|int + */ + public function isLast() + { + return $this->token->isLast(); + } + + /** + * Returns originating token. + * + * @return TokenInterface + */ + public function getOriginatingToken() + { + return $this->token; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('not(%s)', $this->token); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php new file mode 100644 index 0000000..8d93bfd --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php @@ -0,0 +1,104 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Util\StringUtil; + +/** + * Object state-checker token. + * + * @author Konstantin Kudryashov + */ +class ObjectStateToken implements TokenInterface +{ + private $name; + private $value; + private $util; + private $comparatorFactory; + + /** + * Initializes token. + * + * @param string $methodName + * @param mixed $value Expected return value + * @param null|StringUtil $util + * @param ComparatorFactory $comparatorFactory + */ + public function __construct( + $methodName, + $value, + StringUtil $util = null, + ComparatorFactory $comparatorFactory = null + ) { + $this->name = $methodName; + $this->value = $value; + $this->util = $util ?: new StringUtil; + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Scores 8 if argument is an object, which method returns expected value. + * + * @param mixed $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (is_object($argument) && method_exists($argument, $this->name)) { + $actual = call_user_func(array($argument, $this->name)); + + $comparator = $this->comparatorFactory->getComparatorFor( + $actual, $this->value + ); + + try { + $comparator->assertEquals($actual, $this->value); + return 8; + } catch (ComparisonFailure $failure) { + return false; + } + } + + if (is_object($argument) && property_exists($argument, $this->name)) { + return $argument->{$this->name} === $this->value ? 8 : false; + } + + return false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('state(%s(), %s)', + $this->name, + $this->util->stringify($this->value) + ); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php new file mode 100644 index 0000000..24ff8c2 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php @@ -0,0 +1,67 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * String contains token. + * + * @author Peter Mitchell + */ +class StringContainsToken implements TokenInterface +{ + private $value; + + /** + * Initializes token. + * + * @param string $value + */ + public function __construct($value) + { + $this->value = $value; + } + + public function scoreArgument($argument) + { + return strpos($argument, $this->value) !== false ? 6 : false; + } + + /** + * Returns preset value against which token checks arguments. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('contains("%s")', $this->value); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php new file mode 100644 index 0000000..625d3ba --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php @@ -0,0 +1,43 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Argument token interface. + * + * @author Konstantin Kudryashov + */ +interface TokenInterface +{ + /** + * Calculates token match score for provided argument. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument); + + /** + * Returns true if this token prevents check of other tokens (is last one). + * + * @return bool|int + */ + public function isLast(); + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php new file mode 100644 index 0000000..cb65132 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php @@ -0,0 +1,76 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Value type token. + * + * @author Konstantin Kudryashov + */ +class TypeToken implements TokenInterface +{ + private $type; + + /** + * @param string $type + */ + public function __construct($type) + { + $checker = "is_{$type}"; + if (!function_exists($checker) && !interface_exists($type) && !class_exists($type)) { + throw new InvalidArgumentException(sprintf( + 'Type or class name expected as an argument to TypeToken, but got %s.', $type + )); + } + + $this->type = $type; + } + + /** + * Scores 5 if argument has the same type this token was constructed with. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + $checker = "is_{$this->type}"; + if (function_exists($checker)) { + return call_user_func($checker, $argument) ? 5 : false; + } + + return $argument instanceof $this->type ? 5 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('type(%s)', $this->type); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php b/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php new file mode 100644 index 0000000..2f3fbad --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php @@ -0,0 +1,127 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Call; + +use Exception; + +/** + * Call object. + * + * @author Konstantin Kudryashov + */ +class Call +{ + private $methodName; + private $arguments; + private $returnValue; + private $exception; + private $file; + private $line; + + /** + * Initializes call. + * + * @param string $methodName + * @param array $arguments + * @param mixed $returnValue + * @param Exception $exception + * @param null|string $file + * @param null|int $line + */ + public function __construct($methodName, array $arguments, $returnValue, + Exception $exception = null, $file, $line) + { + $this->methodName = $methodName; + $this->arguments = $arguments; + $this->returnValue = $returnValue; + $this->exception = $exception; + + if ($file) { + $this->file = $file; + $this->line = intval($line); + } + } + + /** + * Returns called method name. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * Returns called method arguments. + * + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Returns called method return value. + * + * @return null|mixed + */ + public function getReturnValue() + { + return $this->returnValue; + } + + /** + * Returns exception that call thrown. + * + * @return null|Exception + */ + public function getException() + { + return $this->exception; + } + + /** + * Returns callee filename. + * + * @return string + */ + public function getFile() + { + return $this->file; + } + + /** + * Returns callee line number. + * + * @return int + */ + public function getLine() + { + return $this->line; + } + + /** + * Returns short notation for callee place. + * + * @return string + */ + public function getCallPlace() + { + if (null === $this->file) { + return 'unknown'; + } + + return sprintf('%s:%d', $this->file, $this->line); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php b/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php new file mode 100644 index 0000000..7495855 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php @@ -0,0 +1,152 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Call; + +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Call\UnexpectedCallException; + +/** + * Calls receiver & manager. + * + * @author Konstantin Kudryashov + */ +class CallCenter +{ + private $util; + + /** + * @var Call[] + */ + private $recordedCalls = array(); + + /** + * Initializes call center. + * + * @param StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + } + + /** + * Makes and records specific method call for object prophecy. + * + * @param ObjectProphecy $prophecy + * @param string $methodName + * @param array $arguments + * + * @return mixed Returns null if no promise for prophecy found or promise return value. + * + * @throws \Prophecy\Exception\Call\UnexpectedCallException If no appropriate method prophecy found + */ + public function makeCall(ObjectProphecy $prophecy, $methodName, array $arguments) + { + $backtrace = debug_backtrace(); + + $file = $line = null; + if (isset($backtrace[2]) && isset($backtrace[2]['file'])) { + $file = $backtrace[2]['file']; + $line = $backtrace[2]['line']; + } + + // If no method prophecies defined, then it's a dummy, so we'll just return null + if ('__destruct' === $methodName || 0 == count($prophecy->getMethodProphecies())) { + $this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line); + + return null; + } + + // There are method prophecies, so it's a fake/stub. Searching prophecy for this call + $matches = array(); + foreach ($prophecy->getMethodProphecies($methodName) as $methodProphecy) { + if (0 < $score = $methodProphecy->getArgumentsWildcard()->scoreArguments($arguments)) { + $matches[] = array($score, $methodProphecy); + } + } + + // If fake/stub doesn't have method prophecy for this call - throw exception + if (!count($matches)) { + throw $this->createUnexpectedCallException($prophecy, $methodName, $arguments); + } + + // Sort matches by their score value + @usort($matches, function ($match1, $match2) { return $match2[0] - $match1[0]; }); + + // If Highest rated method prophecy has a promise - execute it or return null instead + $returnValue = null; + $exception = null; + if ($promise = $matches[0][1]->getPromise()) { + try { + $returnValue = $promise->execute($arguments, $prophecy, $matches[0][1]); + } catch (\Exception $e) { + $exception = $e; + } + } + + $this->recordedCalls[] = new Call( + $methodName, $arguments, $returnValue, $exception, $file, $line + ); + + if (null !== $exception) { + throw $exception; + } + + return $returnValue; + } + + /** + * Searches for calls by method name & arguments wildcard. + * + * @param string $methodName + * @param ArgumentsWildcard $wildcard + * + * @return Call[] + */ + public function findCalls($methodName, ArgumentsWildcard $wildcard) + { + return array_values( + array_filter($this->recordedCalls, function (Call $call) use ($methodName, $wildcard) { + return $methodName === $call->getMethodName() + && 0 < $wildcard->scoreArguments($call->getArguments()) + ; + }) + ); + } + + private function createUnexpectedCallException(ObjectProphecy $prophecy, $methodName, + array $arguments) + { + $classname = get_class($prophecy->reveal()); + $argstring = implode(', ', array_map(array($this->util, 'stringify'), $arguments)); + $expected = implode("\n", array_map(function (MethodProphecy $methodProphecy) { + return sprintf(' - %s(%s)', + $methodProphecy->getMethodName(), + $methodProphecy->getArgumentsWildcard() + ); + }, call_user_func_array('array_merge', $prophecy->getMethodProphecies()))); + + return new UnexpectedCallException( + sprintf( + "Method call:\n". + " - %s(%s)\n". + "on %s was not expected, expected calls were:\n%s", + + $methodName, $argstring, $classname, $expected + ), + $prophecy, $methodName, $arguments + ); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php new file mode 100644 index 0000000..874e474 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php @@ -0,0 +1,42 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Comparator; + +use SebastianBergmann\Comparator\Comparator; +use SebastianBergmann\Comparator\ComparisonFailure; + +/** + * Closure comparator. + * + * @author Konstantin Kudryashov + */ +final class ClosureComparator extends Comparator +{ + public function accepts($expected, $actual) + { + return is_object($expected) && $expected instanceof \Closure + && is_object($actual) && $actual instanceof \Closure; + } + + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false) + { + throw new ComparisonFailure( + $expected, + $actual, + // we don't need a diff + '', + '', + false, + 'all closures are born different' + ); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php b/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php new file mode 100644 index 0000000..a7a1200 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php @@ -0,0 +1,46 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Comparator; + +use SebastianBergmann\Comparator\Factory as BaseFactory; + +/** + * Prophecy comparator factory. + * + * @author Konstantin Kudryashov + */ +final class Factory extends BaseFactory +{ + /** + * @var Factory + */ + private static $instance; + + public function __construct() + { + parent::__construct(); + + $this->register(new ClosureComparator()); + } + + /** + * @return Factory + */ + public static function getInstance() + { + if (self::$instance === null) { + self::$instance = new Factory; + } + + return self::$instance; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php new file mode 100644 index 0000000..d6b6b1a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php @@ -0,0 +1,68 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use ReflectionClass; + +/** + * Cached class doubler. + * Prevents mirroring/creation of the same structure twice. + * + * @author Konstantin Kudryashov + */ +class CachedDoubler extends Doubler +{ + private $classes = array(); + + /** + * {@inheritdoc} + */ + public function registerClassPatch(ClassPatch\ClassPatchInterface $patch) + { + $this->classes[] = array(); + + parent::registerClassPatch($patch); + } + + /** + * {@inheritdoc} + */ + protected function createDoubleClass(ReflectionClass $class = null, array $interfaces) + { + $classId = $this->generateClassId($class, $interfaces); + if (isset($this->classes[$classId])) { + return $this->classes[$classId]; + } + + return $this->classes[$classId] = parent::createDoubleClass($class, $interfaces); + } + + /** + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + private function generateClassId(ReflectionClass $class = null, array $interfaces) + { + $parts = array(); + if (null !== $class) { + $parts[] = $class->getName(); + } + foreach ($interfaces as $interface) { + $parts[] = $interface->getName(); + } + sort($parts); + + return md5(implode('', $parts)); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php new file mode 100644 index 0000000..d6d1968 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php @@ -0,0 +1,48 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Class patch interface. + * Class patches extend doubles functionality or help + * Prophecy to avoid some internal PHP bugs. + * + * @author Konstantin Kudryashov + */ +interface ClassPatchInterface +{ + /** + * Checks if patch supports specific class node. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node); + + /** + * Applies patch to the specific class node. + * + * @param ClassNode $node + * @return void + */ + public function apply(ClassNode $node); + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php new file mode 100644 index 0000000..61998fc --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php @@ -0,0 +1,72 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * Disable constructor. + * Makes all constructor arguments optional. + * + * @author Konstantin Kudryashov + */ +class DisableConstructorPatch implements ClassPatchInterface +{ + /** + * Checks if class has `__construct` method. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Makes all class constructor arguments optional. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + if (!$node->hasMethod('__construct')) { + $node->addMethod(new MethodNode('__construct', '')); + + return; + } + + $constructor = $node->getMethod('__construct'); + foreach ($constructor->getArguments() as $argument) { + $argument->setDefault(null); + } + + $constructor->setCode(<< + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Exception patch for HHVM to remove the stubs from special methods + * + * @author Christophe Coevoet + */ +class HhvmExceptionPatch implements ClassPatchInterface +{ + /** + * Supports exceptions on HHVM. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (!defined('HHVM_VERSION')) { + return false; + } + + return 'Exception' === $node->getParentClass() || is_subclass_of($node->getParentClass(), 'Exception'); + } + + /** + * Removes special exception static methods from the doubled methods. + * + * @param ClassNode $node + * + * @return void + */ + public function apply(ClassNode $node) + { + if ($node->hasMethod('setTraceOptions')) { + $node->getMethod('setTraceOptions')->useParentCode(); + } + if ($node->hasMethod('getTraceOptions')) { + $node->getMethod('getTraceOptions')->useParentCode(); + } + } + + /** + * {@inheritdoc} + */ + public function getPriority() + { + return -50; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php new file mode 100644 index 0000000..b0d9793 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php @@ -0,0 +1,135 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Remove method functionality from the double which will clash with php keywords. + * + * @author Milan Magudia + */ +class KeywordPatch implements ClassPatchInterface +{ + /** + * Support any class + * + * @param ClassNode $node + * + * @return boolean + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Remove methods that clash with php keywords + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $methodNames = array_keys($node->getMethods()); + $methodsToRemove = array_intersect($methodNames, $this->getKeywords()); + foreach ($methodsToRemove as $methodName) { + $node->removeMethod($methodName); + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() { + return 49; + } + + /** + * Returns array of php keywords. + * + * @return array + */ + private function getKeywords() { + + return array( + '__halt_compiler', + 'abstract', + 'and', + 'array', + 'as', + 'break', + 'callable', + 'case', + 'catch', + 'class', + 'clone', + 'const', + 'continue', + 'declare', + 'default', + 'die', + 'do', + 'echo', + 'else', + 'elseif', + 'empty', + 'enddeclare', + 'endfor', + 'endforeach', + 'endif', + 'endswitch', + 'endwhile', + 'eval', + 'exit', + 'extends', + 'final', + 'finally', + 'for', + 'foreach', + 'function', + 'global', + 'goto', + 'if', + 'implements', + 'include', + 'include_once', + 'instanceof', + 'insteadof', + 'interface', + 'isset', + 'list', + 'namespace', + 'new', + 'or', + 'print', + 'private', + 'protected', + 'public', + 'require', + 'require_once', + 'return', + 'static', + 'switch', + 'throw', + 'trait', + 'try', + 'unset', + 'use', + 'var', + 'while', + 'xor', + 'yield', + ); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php new file mode 100644 index 0000000..da45450 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php @@ -0,0 +1,73 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use phpDocumentor\Reflection\DocBlock; +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * Discover Magical API using "@method" PHPDoc format. + * + * @author Thomas Tourlourat + */ +class MagicCallPatch implements ClassPatchInterface +{ + /** + * Support any class + * + * @param ClassNode $node + * + * @return boolean + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Discover Magical API + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $parentClass = $node->getParentClass(); + $reflectionClass = new \ReflectionClass($parentClass); + + $phpdoc = new DocBlock($reflectionClass->getDocComment()); + + $tagList = $phpdoc->getTagsByName('method'); + + foreach($tagList as $tag) { + $methodName = $tag->getMethodName(); + + if (!$reflectionClass->hasMethod($methodName)) { + $methodNode = new MethodNode($tag->getMethodName()); + $methodNode->setStatic($tag->isStatic()); + + $node->addMethod($methodNode); + } + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return integer Priority number (higher - earlier) + */ + public function getPriority() + { + return 50; + } +} + diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php new file mode 100644 index 0000000..ab0bb7c --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php @@ -0,0 +1,98 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; +use Prophecy\Doubler\Generator\Node\ArgumentNode; + +/** + * Add Prophecy functionality to the double. + * This is a core class patch for Prophecy. + * + * @author Konstantin Kudryashov + */ +class ProphecySubjectPatch implements ClassPatchInterface +{ + /** + * Always returns true. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Apply Prophecy functionality to class node. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface'); + $node->addProperty('objectProphecy', 'private'); + + foreach ($node->getMethods() as $name => $method) { + if ('__construct' === strtolower($name)) { + continue; + } + + $method->setCode( + 'return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());' + ); + } + + $prophecySetter = new MethodNode('setProphecy'); + $prophecyArgument = new ArgumentNode('prophecy'); + $prophecyArgument->setTypeHint('Prophecy\Prophecy\ProphecyInterface'); + $prophecySetter->addArgument($prophecyArgument); + $prophecySetter->setCode('$this->objectProphecy = $prophecy;'); + + $prophecyGetter = new MethodNode('getProphecy'); + $prophecyGetter->setCode('return $this->objectProphecy;'); + + if ($node->hasMethod('__call')) { + $__call = $node->getMethod('__call'); + } else { + $__call = new MethodNode('__call'); + $__call->addArgument(new ArgumentNode('name')); + $__call->addArgument(new ArgumentNode('arguments')); + + $node->addMethod($__call); + } + + $__call->setCode(<<getProphecy(), func_get_arg(0) +); +PHP + ); + + $node->addMethod($prophecySetter); + $node->addMethod($prophecyGetter); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 0; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php new file mode 100644 index 0000000..9166aee --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php @@ -0,0 +1,57 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * ReflectionClass::newInstance patch. + * Makes first argument of newInstance optional, since it works but signature is misleading + * + * @author Florian Klein + */ +class ReflectionClassNewInstancePatch implements ClassPatchInterface +{ + /** + * Supports ReflectionClass + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return 'ReflectionClass' === $node->getParentClass(); + } + + /** + * Updates newInstance's first argument to make it optional + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + foreach ($node->getMethod('newInstance')->getArguments() as $argument) { + $argument->setDefault(null); + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher = earlier) + */ + public function getPriority() + { + return 50; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php new file mode 100644 index 0000000..8401159 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php @@ -0,0 +1,85 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * SplFileInfo patch. + * Makes SplFileInfo and derivative classes usable with Prophecy. + * + * @author Konstantin Kudryashov + */ +class SplFileInfoPatch implements ClassPatchInterface +{ + /** + * Supports everything that extends SplFileInfo. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (null === $node->getParentClass()) { + return false; + } + + return 'SplFileInfo' === $node->getParentClass() + || is_subclass_of($node->getParentClass(), 'SplFileInfo') + ; + } + + /** + * Updated constructor code to call parent one with dummy file argument. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + if ($node->hasMethod('__construct')) { + $constructor = $node->getMethod('__construct'); + } else { + $constructor = new MethodNode('__construct'); + $node->addMethod($constructor); + } + + if ($this->nodeIsDirectoryIterator($node)) { + $constructor->setCode('return parent::__construct("' . __DIR__ . '");'); + return; + } + + $constructor->useParentCode(); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 50; + } + + /** + * @param ClassNode $node + * @return boolean + */ + private function nodeIsDirectoryIterator(ClassNode $node) + { + $parent = $node->getParentClass(); + return 'DirectoryIterator' === $parent + || is_subclass_of($parent, 'DirectoryIterator'); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php new file mode 100644 index 0000000..eea0202 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php @@ -0,0 +1,83 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * Traversable interface patch. + * Forces classes that implement interfaces, that extend Traversable to also implement Iterator. + * + * @author Konstantin Kudryashov + */ +class TraversablePatch implements ClassPatchInterface +{ + /** + * Supports nodetree, that implement Traversable, but not Iterator or IteratorAggregate. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (in_array('Iterator', $node->getInterfaces())) { + return false; + } + if (in_array('IteratorAggregate', $node->getInterfaces())) { + return false; + } + + foreach ($node->getInterfaces() as $interface) { + if ('Traversable' !== $interface && !is_subclass_of($interface, 'Traversable')) { + continue; + } + if ('Iterator' === $interface || is_subclass_of($interface, 'Iterator')) { + continue; + } + if ('IteratorAggregate' === $interface || is_subclass_of($interface, 'IteratorAggregate')) { + continue; + } + + return true; + } + + return false; + } + + /** + * Forces class to implement Iterator interface. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $node->addInterface('Iterator'); + + $node->addMethod(new MethodNode('current')); + $node->addMethod(new MethodNode('key')); + $node->addMethod(new MethodNode('next')); + $node->addMethod(new MethodNode('rewind')); + $node->addMethod(new MethodNode('valid')); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 100; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php new file mode 100644 index 0000000..699be3a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php @@ -0,0 +1,22 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +/** + * Core double interface. + * All doubled classes will implement this one. + * + * @author Konstantin Kudryashov + */ +interface DoubleInterface +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php new file mode 100644 index 0000000..a378ae2 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php @@ -0,0 +1,146 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use Doctrine\Instantiator\Instantiator; +use Prophecy\Doubler\ClassPatch\ClassPatchInterface; +use Prophecy\Doubler\Generator\ClassMirror; +use Prophecy\Doubler\Generator\ClassCreator; +use Prophecy\Exception\InvalidArgumentException; +use ReflectionClass; + +/** + * Cached class doubler. + * Prevents mirroring/creation of the same structure twice. + * + * @author Konstantin Kudryashov + */ +class Doubler +{ + private $mirror; + private $creator; + private $namer; + + /** + * @var ClassPatchInterface[] + */ + private $patches = array(); + + /** + * @var \Doctrine\Instantiator\Instantiator + */ + private $instantiator; + + /** + * Initializes doubler. + * + * @param ClassMirror $mirror + * @param ClassCreator $creator + * @param NameGenerator $namer + */ + public function __construct(ClassMirror $mirror = null, ClassCreator $creator = null, + NameGenerator $namer = null) + { + $this->mirror = $mirror ?: new ClassMirror; + $this->creator = $creator ?: new ClassCreator; + $this->namer = $namer ?: new NameGenerator; + } + + /** + * Returns list of registered class patches. + * + * @return ClassPatchInterface[] + */ + public function getClassPatches() + { + return $this->patches; + } + + /** + * Registers new class patch. + * + * @param ClassPatchInterface $patch + */ + public function registerClassPatch(ClassPatchInterface $patch) + { + $this->patches[] = $patch; + + @usort($this->patches, function (ClassPatchInterface $patch1, ClassPatchInterface $patch2) { + return $patch2->getPriority() - $patch1->getPriority(); + }); + } + + /** + * Creates double from specific class or/and list of interfaces. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces Array of ReflectionClass instances + * @param array $args Constructor arguments + * + * @return DoubleInterface + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function double(ReflectionClass $class = null, array $interfaces, array $args = null) + { + foreach ($interfaces as $interface) { + if (!$interface instanceof ReflectionClass) { + throw new InvalidArgumentException(sprintf( + "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n". + "a second argument to `Doubler::double(...)`, but got %s.", + is_object($interface) ? get_class($interface).' class' : gettype($interface) + )); + } + } + + $classname = $this->createDoubleClass($class, $interfaces); + $reflection = new ReflectionClass($classname); + + if (null !== $args) { + return $reflection->newInstanceArgs($args); + } + if ((null === $constructor = $reflection->getConstructor()) + || ($constructor->isPublic() && !$constructor->isFinal())) { + return $reflection->newInstance(); + } + + if (!$this->instantiator) { + $this->instantiator = new Instantiator(); + } + + return $this->instantiator->instantiate($classname); + } + + /** + * Creates double class and returns its FQN. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + protected function createDoubleClass(ReflectionClass $class = null, array $interfaces) + { + $name = $this->namer->name($class, $interfaces); + $node = $this->mirror->reflect($class, $interfaces); + + foreach ($this->patches as $patch) { + if ($patch->supports($node)) { + $patch->apply($node); + } + } + + $this->creator->create($name, $node); + + return $name; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php new file mode 100644 index 0000000..4d474e5 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php @@ -0,0 +1,92 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +/** + * Class code creator. + * Generates PHP code for specific class node tree. + * + * @author Konstantin Kudryashov + */ +class ClassCodeGenerator +{ + /** + * Generates PHP code for class node. + * + * @param string $classname + * @param Node\ClassNode $class + * + * @return string + */ + public function generate($classname, Node\ClassNode $class) + { + $parts = explode('\\', $classname); + $classname = array_pop($parts); + $namespace = implode('\\', $parts); + + $code = sprintf("class %s extends \%s implements %s {\n", + $classname, $class->getParentClass(), implode(', ', + array_map(function ($interface) {return '\\'.$interface;}, $class->getInterfaces()) + ) + ); + + foreach ($class->getProperties() as $name => $visibility) { + $code .= sprintf("%s \$%s;\n", $visibility, $name); + } + $code .= "\n"; + + foreach ($class->getMethods() as $method) { + $code .= $this->generateMethod($method)."\n"; + } + $code .= "\n}"; + + return sprintf("namespace %s {\n%s\n}", $namespace, $code); + } + + private function generateMethod(Node\MethodNode $method) + { + $php = sprintf("%s %s function %s%s(%s)%s {\n", + $method->getVisibility(), + $method->isStatic() ? 'static' : '', + $method->returnsReference() ? '&':'', + $method->getName(), + implode(', ', $this->generateArguments($method->getArguments())), + $method->hasReturnType() ? sprintf(': %s', $method->getReturnType()) : '' + ); + $php .= $method->getCode()."\n"; + + return $php.'}'; + } + + private function generateArguments(array $arguments) + { + return array_map(function (Node\ArgumentNode $argument) { + $php = ''; + + if ($hint = $argument->getTypeHint()) { + if ('array' === $hint || 'callable' === $hint) { + $php .= $hint; + } else { + $php .= '\\'.$hint; + } + } + + $php .= ' '.($argument->isPassedByReference() ? '&' : '').'$'.$argument->getName(); + + if ($argument->isOptional()) { + $php .= ' = '.var_export($argument->getDefault(), true); + } + + return $php; + }, $arguments); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php new file mode 100644 index 0000000..882a4a4 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php @@ -0,0 +1,67 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +use Prophecy\Exception\Doubler\ClassCreatorException; + +/** + * Class creator. + * Creates specific class in current environment. + * + * @author Konstantin Kudryashov + */ +class ClassCreator +{ + private $generator; + + /** + * Initializes creator. + * + * @param ClassCodeGenerator $generator + */ + public function __construct(ClassCodeGenerator $generator = null) + { + $this->generator = $generator ?: new ClassCodeGenerator; + } + + /** + * Creates class. + * + * @param string $classname + * @param Node\ClassNode $class + * + * @return mixed + * + * @throws \Prophecy\Exception\Doubler\ClassCreatorException + */ + public function create($classname, Node\ClassNode $class) + { + $code = $this->generator->generate($classname, $class); + $return = eval($code); + + if (!class_exists($classname, false)) { + if (count($class->getInterfaces())) { + throw new ClassCreatorException(sprintf( + 'Could not double `%s` and implement interfaces: [%s].', + $class->getParentClass(), implode(', ', $class->getInterfaces()) + ), $class); + } + + throw new ClassCreatorException( + sprintf('Could not double `%s`.', $class->getParentClass()), + $class + ); + } + + return $return; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php new file mode 100644 index 0000000..6a4ebde --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php @@ -0,0 +1,210 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Exception\Doubler\ClassMirrorException; +use ReflectionClass; +use ReflectionMethod; +use ReflectionParameter; + +/** + * Class mirror. + * Core doubler class. Mirrors specific class and/or interfaces into class node tree. + * + * @author Konstantin Kudryashov + */ +class ClassMirror +{ + private static $reflectableMethods = array( + '__construct', + '__destruct', + '__sleep', + '__wakeup', + '__toString', + '__call', + ); + + /** + * Reflects provided arguments into class node. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return Node\ClassNode + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function reflect(ReflectionClass $class = null, array $interfaces) + { + $node = new Node\ClassNode; + + if (null !== $class) { + if (true === $class->isInterface()) { + throw new InvalidArgumentException(sprintf( + "Could not reflect %s as a class, because it\n". + "is interface - use the second argument instead.", + $class->getName() + )); + } + + $this->reflectClassToNode($class, $node); + } + + foreach ($interfaces as $interface) { + if (!$interface instanceof ReflectionClass) { + throw new InvalidArgumentException(sprintf( + "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n". + "a second argument to `ClassMirror::reflect(...)`, but got %s.", + is_object($interface) ? get_class($interface).' class' : gettype($interface) + )); + } + if (false === $interface->isInterface()) { + throw new InvalidArgumentException(sprintf( + "Could not reflect %s as an interface, because it\n". + "is class - use the first argument instead.", + $interface->getName() + )); + } + + $this->reflectInterfaceToNode($interface, $node); + } + + $node->addInterface('Prophecy\Doubler\Generator\ReflectionInterface'); + + return $node; + } + + private function reflectClassToNode(ReflectionClass $class, Node\ClassNode $node) + { + if (true === $class->isFinal()) { + throw new ClassMirrorException(sprintf( + 'Could not reflect class %s as it is marked final.', $class->getName() + ), $class); + } + + $node->setParentClass($class->getName()); + + foreach ($class->getMethods(ReflectionMethod::IS_ABSTRACT) as $method) { + if (false === $method->isProtected()) { + continue; + } + + $this->reflectMethodToNode($method, $node); + } + + foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { + if (0 === strpos($method->getName(), '_') + && !in_array($method->getName(), self::$reflectableMethods)) { + continue; + } + + if (true === $method->isFinal()) { + continue; + } + + $this->reflectMethodToNode($method, $node); + } + } + + private function reflectInterfaceToNode(ReflectionClass $interface, Node\ClassNode $node) + { + $node->addInterface($interface->getName()); + + foreach ($interface->getMethods() as $method) { + $this->reflectMethodToNode($method, $node); + } + } + + private function reflectMethodToNode(ReflectionMethod $method, Node\ClassNode $classNode) + { + $node = new Node\MethodNode($method->getName()); + + if (true === $method->isProtected()) { + $node->setVisibility('protected'); + } + + if (true === $method->isStatic()) { + $node->setStatic(); + } + + if (true === $method->returnsReference()) { + $node->setReturnsReference(); + } + + if (version_compare(PHP_VERSION, '7.0', '>=') && true === $method->hasReturnType()) { + $node->setReturnType((string) $method->getReturnType()); + } + + if (is_array($params = $method->getParameters()) && count($params)) { + foreach ($params as $param) { + $this->reflectArgumentToNode($param, $node); + } + } + + $classNode->addMethod($node); + } + + private function reflectArgumentToNode(ReflectionParameter $parameter, Node\MethodNode $methodNode) + { + $name = $parameter->getName() == '...' ? '__dot_dot_dot__' : $parameter->getName(); + $node = new Node\ArgumentNode($name); + + $typeHint = $this->getTypeHint($parameter); + $node->setTypeHint($typeHint); + + if (true === $parameter->isDefaultValueAvailable()) { + $node->setDefault($parameter->getDefaultValue()); + } elseif (true === $parameter->isOptional() + || (true === $parameter->allowsNull() && $typeHint)) { + $node->setDefault(null); + } + + if (true === $parameter->isPassedByReference()) { + $node->setAsPassedByReference(); + } + + $methodNode->addArgument($node); + } + + private function getTypeHint(ReflectionParameter $parameter) + { + if (null !== $className = $this->getParameterClassName($parameter)) { + return $className; + } + + if (true === $parameter->isArray()) { + return 'array'; + } + + if (version_compare(PHP_VERSION, '5.4', '>=') && true === $parameter->isCallable()) { + return 'callable'; + } + + if (version_compare(PHP_VERSION, '7.0', '>=') && true === $parameter->hasType()) { + return (string) $parameter->getType(); + } + + return null; + } + + private function getParameterClassName(ReflectionParameter $parameter) + { + try { + return $parameter->getClass() ? $parameter->getClass()->getName() : null; + } catch (\ReflectionException $e) { + preg_match('/\[\s\<\w+?>\s([\w,\\\]+)/s', $parameter, $matches); + + return isset($matches[1]) ? $matches[1] : null; + } + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php new file mode 100644 index 0000000..a6c42a3 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php @@ -0,0 +1,75 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +/** + * Argument node. + * + * @author Konstantin Kudryashov + */ +class ArgumentNode +{ + private $name; + private $typeHint; + private $default; + private $optional = false; + private $byReference = false; + + /** + * @param string $name + */ + public function __construct($name) + { + $this->name = $name; + } + + public function getName() + { + return $this->name; + } + + public function getTypeHint() + { + return $this->typeHint; + } + + public function setTypeHint($typeHint = null) + { + $this->typeHint = $typeHint; + } + + public function getDefault() + { + return $this->default; + } + + public function setDefault($default = null) + { + $this->optional = true; + $this->default = $default; + } + + public function isOptional() + { + return $this->optional; + } + + public function setAsPassedByReference($byReference = true) + { + $this->byReference = $byReference; + } + + public function isPassedByReference() + { + return $this->byReference; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php new file mode 100644 index 0000000..b38cb4e --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php @@ -0,0 +1,130 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Class node. + * + * @author Konstantin Kudryashov + */ +class ClassNode +{ + private $parentClass = 'stdClass'; + private $interfaces = array(); + private $properties = array(); + + /** + * @var MethodNode[] + */ + private $methods = array(); + + public function getParentClass() + { + return $this->parentClass; + } + + /** + * @param string $class + */ + public function setParentClass($class) + { + $this->parentClass = $class ?: 'stdClass'; + } + + /** + * @return string[] + */ + public function getInterfaces() + { + return $this->interfaces; + } + + /** + * @param string $interface + */ + public function addInterface($interface) + { + if ($this->hasInterface($interface)) { + return; + } + + array_unshift($this->interfaces, $interface); + } + + /** + * @param string $interface + * + * @return bool + */ + public function hasInterface($interface) + { + return in_array($interface, $this->interfaces); + } + + public function getProperties() + { + return $this->properties; + } + + public function addProperty($name, $visibility = 'public') + { + $visibility = strtolower($visibility); + + if (!in_array($visibility, array('public', 'private', 'protected'))) { + throw new InvalidArgumentException(sprintf( + '`%s` property visibility is not supported.', $visibility + )); + } + + $this->properties[$name] = $visibility; + } + + /** + * @return MethodNode[] + */ + public function getMethods() + { + return $this->methods; + } + + public function addMethod(MethodNode $method) + { + $this->methods[$method->getName()] = $method; + } + + public function removeMethod($name) + { + unset($this->methods[$name]); + } + + /** + * @param string $name + * + * @return MethodNode|null + */ + public function getMethod($name) + { + return $this->hasMethod($name) ? $this->methods[$name] : null; + } + + /** + * @param string $name + * + * @return bool + */ + public function hasMethod($name) + { + return isset($this->methods[$name]); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php new file mode 100644 index 0000000..eb95352 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php @@ -0,0 +1,177 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Method node. + * + * @author Konstantin Kudryashov + */ +class MethodNode +{ + private $name; + private $code; + private $visibility = 'public'; + private $static = false; + private $returnsReference = false; + private $returnType; + + /** + * @var ArgumentNode[] + */ + private $arguments = array(); + + /** + * @param string $name + * @param string $code + */ + public function __construct($name, $code = null) + { + $this->name = $name; + $this->code = $code; + } + + public function getVisibility() + { + return $this->visibility; + } + + /** + * @param string $visibility + */ + public function setVisibility($visibility) + { + $visibility = strtolower($visibility); + + if (!in_array($visibility, array('public', 'private', 'protected'))) { + throw new InvalidArgumentException(sprintf( + '`%s` method visibility is not supported.', $visibility + )); + } + + $this->visibility = $visibility; + } + + public function isStatic() + { + return $this->static; + } + + public function setStatic($static = true) + { + $this->static = (bool) $static; + } + + public function returnsReference() + { + return $this->returnsReference; + } + + public function setReturnsReference() + { + $this->returnsReference = true; + } + + public function getName() + { + return $this->name; + } + + public function addArgument(ArgumentNode $argument) + { + $this->arguments[] = $argument; + } + + /** + * @return ArgumentNode[] + */ + public function getArguments() + { + return $this->arguments; + } + + public function hasReturnType() + { + return null !== $this->returnType; + } + + /** + * @param string $type + */ + public function setReturnType($type = null) + { + switch ($type) { + case '': + $this->returnType = null; + break; + + case 'string'; + case 'float': + case 'int': + case 'bool': + case 'array': + case 'callable': + $this->returnType = $type; + break; + + case 'double': + case 'real': + $this->returnType = 'float'; + break; + + case 'boolean': + $this->returnType = 'bool'; + break; + + case 'integer': + $this->returnType = 'int'; + break; + + default: + $this->returnType = '\\' . ltrim($type, '\\'); + } + } + + public function getReturnType() + { + return $this->returnType; + } + + /** + * @param string $code + */ + public function setCode($code) + { + $this->code = $code; + } + + public function getCode() + { + if ($this->returnsReference) + { + return "throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), '{$this->name}');"; + } + + return (string) $this->code; + } + + public function useParentCode() + { + $this->code = sprintf( + 'return parent::%s(%s);', $this->getName(), implode(', ', + array_map(function (ArgumentNode $arg) { return '$'.$arg->getName(); }, $this->arguments) + ) + ); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php new file mode 100644 index 0000000..d720b15 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php @@ -0,0 +1,22 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +/** + * Reflection interface. + * All reflected classes implement this interface. + * + * @author Konstantin Kudryashov + */ +interface ReflectionInterface +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php new file mode 100644 index 0000000..8a99c4c --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php @@ -0,0 +1,127 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use Prophecy\Exception\Doubler\DoubleException; +use Prophecy\Exception\Doubler\ClassNotFoundException; +use Prophecy\Exception\Doubler\InterfaceNotFoundException; +use ReflectionClass; + +/** + * Lazy double. + * Gives simple interface to describe double before creating it. + * + * @author Konstantin Kudryashov + */ +class LazyDouble +{ + private $doubler; + private $class; + private $interfaces = array(); + private $arguments = null; + private $double; + + /** + * Initializes lazy double. + * + * @param Doubler $doubler + */ + public function __construct(Doubler $doubler) + { + $this->doubler = $doubler; + } + + /** + * Tells doubler to use specific class as parent one for double. + * + * @param string|ReflectionClass $class + * + * @throws \Prophecy\Exception\Doubler\ClassNotFoundException + * @throws \Prophecy\Exception\Doubler\DoubleException + */ + public function setParentClass($class) + { + if (null !== $this->double) { + throw new DoubleException('Can not extend class with already instantiated double.'); + } + + if (!$class instanceof ReflectionClass) { + if (!class_exists($class)) { + throw new ClassNotFoundException(sprintf('Class %s not found.', $class), $class); + } + + $class = new ReflectionClass($class); + } + + $this->class = $class; + } + + /** + * Tells doubler to implement specific interface with double. + * + * @param string|ReflectionClass $interface + * + * @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException + * @throws \Prophecy\Exception\Doubler\DoubleException + */ + public function addInterface($interface) + { + if (null !== $this->double) { + throw new DoubleException( + 'Can not implement interface with already instantiated double.' + ); + } + + if (!$interface instanceof ReflectionClass) { + if (!interface_exists($interface)) { + throw new InterfaceNotFoundException( + sprintf('Interface %s not found.', $interface), + $interface + ); + } + + $interface = new ReflectionClass($interface); + } + + $this->interfaces[] = $interface; + } + + /** + * Sets constructor arguments. + * + * @param array $arguments + */ + public function setArguments(array $arguments = null) + { + $this->arguments = $arguments; + } + + /** + * Creates double instance or returns already created one. + * + * @return DoubleInterface + */ + public function getInstance() + { + if (null === $this->double) { + if (null !== $this->arguments) { + return $this->double = $this->doubler->double( + $this->class, $this->interfaces, $this->arguments + ); + } + + $this->double = $this->doubler->double($this->class, $this->interfaces); + } + + return $this->double; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php new file mode 100644 index 0000000..d67ec6a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use ReflectionClass; + +/** + * Name generator. + * Generates classname for double. + * + * @author Konstantin Kudryashov + */ +class NameGenerator +{ + private static $counter = 1; + + /** + * Generates name. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + public function name(ReflectionClass $class = null, array $interfaces) + { + $parts = array(); + + if (null !== $class) { + $parts[] = $class->getName(); + } else { + foreach ($interfaces as $interface) { + $parts[] = $interface->getShortName(); + } + } + + if (!count($parts)) { + $parts[] = 'stdClass'; + } + + return sprintf('Double\%s\P%d', implode('\\', $parts), self::$counter++); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php new file mode 100644 index 0000000..48ed225 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php @@ -0,0 +1,40 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Call; + +use Prophecy\Exception\Prophecy\ObjectProphecyException; +use Prophecy\Prophecy\ObjectProphecy; + +class UnexpectedCallException extends ObjectProphecyException +{ + private $methodName; + private $arguments; + + public function __construct($message, ObjectProphecy $objectProphecy, + $methodName, array $arguments) + { + parent::__construct($message, $objectProphecy); + + $this->methodName = $methodName; + $this->arguments = $arguments; + } + + public function getMethodName() + { + return $this->methodName; + } + + public function getArguments() + { + return $this->arguments; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php new file mode 100644 index 0000000..822918a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +class ClassCreatorException extends \RuntimeException implements DoublerException +{ + private $node; + + public function __construct($message, ClassNode $node) + { + parent::__construct($message); + + $this->node = $node; + } + + public function getClassNode() + { + return $this->node; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php new file mode 100644 index 0000000..8fc53b8 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use ReflectionClass; + +class ClassMirrorException extends \RuntimeException implements DoublerException +{ + private $class; + + public function __construct($message, ReflectionClass $class) + { + parent::__construct($message); + + $this->class = $class; + } + + public function getReflectedClass() + { + return $this->class; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php new file mode 100644 index 0000000..5bc826d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php @@ -0,0 +1,33 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class ClassNotFoundException extends DoubleException +{ + private $classname; + + /** + * @param string $message + * @param string $classname + */ + public function __construct($message, $classname) + { + parent::__construct($message); + + $this->classname = $classname; + } + + public function getClassname() + { + return $this->classname; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php new file mode 100644 index 0000000..6642a58 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use RuntimeException; + +class DoubleException extends RuntimeException implements DoublerException +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php new file mode 100644 index 0000000..9d6be17 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use Prophecy\Exception\Exception; + +interface DoublerException extends Exception +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php new file mode 100644 index 0000000..e344dea --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php @@ -0,0 +1,20 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class InterfaceNotFoundException extends ClassNotFoundException +{ + public function getInterfaceName() + { + return $this->getClassname(); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php new file mode 100644 index 0000000..b113941 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php @@ -0,0 +1,60 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class MethodNotFoundException extends DoubleException +{ + /** + * @var string + */ + private $classname; + + /** + * @var string + */ + private $methodName; + + /** + * @var array + */ + private $arguments; + + /** + * @param string $message + * @param string $classname + * @param string $methodName + * @param null|Argument\ArgumentsWildcard|array $arguments + */ + public function __construct($message, $classname, $methodName, $arguments = null) + { + parent::__construct($message); + + $this->classname = $classname; + $this->methodName = $methodName; + $this->arguments = $arguments; + } + + public function getClassname() + { + return $this->classname; + } + + public function getMethodName() + { + return $this->methodName; + } + + public function getArguments() + { + return $this->arguments; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php new file mode 100644 index 0000000..6303049 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php @@ -0,0 +1,41 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class ReturnByReferenceException extends DoubleException +{ + private $classname; + private $methodName; + + /** + * @param string $message + * @param string $classname + * @param string $methodName + */ + public function __construct($message, $classname, $methodName) + { + parent::__construct($message); + + $this->classname = $classname; + $this->methodName = $methodName; + } + + public function getClassname() + { + return $this->classname; + } + + public function getMethodName() + { + return $this->methodName; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php new file mode 100644 index 0000000..ac9fe4d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php @@ -0,0 +1,26 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception; + +/** + * Core Prophecy exception interface. + * All Prophecy exceptions implement it. + * + * @author Konstantin Kudryashov + */ +interface Exception +{ + /** + * @return string + */ + public function getMessage(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..bc91c69 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php @@ -0,0 +1,16 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception; + +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php new file mode 100644 index 0000000..44b598a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php @@ -0,0 +1,50 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\ObjectProphecy; + +class AggregateException extends \RuntimeException implements PredictionException +{ + private $exceptions = array(); + private $objectProphecy; + + public function append(PredictionException $exception) + { + $message = $exception->getMessage(); + $message = ' '.strtr($message, array("\n" => "\n "))."\n"; + + $this->message = rtrim($this->message.$message); + $this->exceptions[] = $exception; + } + + /** + * @return PredictionException[] + */ + public function getExceptions() + { + return $this->exceptions; + } + + public function setObjectProphecy(ObjectProphecy $objectProphecy) + { + $this->objectProphecy = $objectProphecy; + } + + /** + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php new file mode 100644 index 0000000..bbbbc3d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php @@ -0,0 +1,24 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use RuntimeException; + +/** + * Basic failed prediction exception. + * Use it for custom prediction failures. + * + * @author Konstantin Kudryashov + */ +class FailedPredictionException extends RuntimeException implements PredictionException +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php new file mode 100644 index 0000000..05ea4aa --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Exception\Prophecy\MethodProphecyException; + +class NoCallsException extends MethodProphecyException implements PredictionException +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php new file mode 100644 index 0000000..2596b1e --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Exception\Exception; + +interface PredictionException extends Exception +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php new file mode 100644 index 0000000..9d90543 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\MethodProphecy; + +class UnexpectedCallsCountException extends UnexpectedCallsException +{ + private $expectedCount; + + public function __construct($message, MethodProphecy $methodProphecy, $count, array $calls) + { + parent::__construct($message, $methodProphecy, $calls); + + $this->expectedCount = intval($count); + } + + public function getExpectedCount() + { + return $this->expectedCount; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php new file mode 100644 index 0000000..7a99c2d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php @@ -0,0 +1,32 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\Prophecy\MethodProphecyException; + +class UnexpectedCallsException extends MethodProphecyException implements PredictionException +{ + private $calls = array(); + + public function __construct($message, MethodProphecy $methodProphecy, array $calls) + { + parent::__construct($message, $methodProphecy); + + $this->calls = $calls; + } + + public function getCalls() + { + return $this->calls; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php new file mode 100644 index 0000000..1b03eaf --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Prophecy\MethodProphecy; + +class MethodProphecyException extends ObjectProphecyException +{ + private $methodProphecy; + + public function __construct($message, MethodProphecy $methodProphecy) + { + parent::__construct($message, $methodProphecy->getObjectProphecy()); + + $this->methodProphecy = $methodProphecy; + } + + /** + * @return MethodProphecy + */ + public function getMethodProphecy() + { + return $this->methodProphecy; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php new file mode 100644 index 0000000..e345402 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Prophecy\ObjectProphecy; + +class ObjectProphecyException extends \RuntimeException implements ProphecyException +{ + private $objectProphecy; + + public function __construct($message, ObjectProphecy $objectProphecy) + { + parent::__construct($message); + + $this->objectProphecy = $objectProphecy; + } + + /** + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php new file mode 100644 index 0000000..9157332 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Exception\Exception; + +interface ProphecyException extends Exception +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php new file mode 100644 index 0000000..b478736 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php @@ -0,0 +1,86 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Argument\Token\AnyValuesToken; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\NoCallsException; + +/** + * Call prediction. + * + * @author Konstantin Kudryashov + */ +class CallPrediction implements PredictionInterface +{ + private $util; + + /** + * Initializes prediction. + * + * @param StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there was at least one call. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\NoCallsException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if (count($calls)) { + return; + } + + $methodCalls = $object->findProphecyMethodCalls( + $method->getMethodName(), + new ArgumentsWildcard(array(new AnyValuesToken)) + ); + + if (count($methodCalls)) { + throw new NoCallsException(sprintf( + "No calls have been made that match:\n". + " %s->%s(%s)\n". + "but expected at least one.\n". + "Recorded `%s(...)` calls:\n%s", + + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + $method->getMethodName(), + $this->util->stringifyCalls($methodCalls) + ), $method); + } + + throw new NoCallsException(sprintf( + "No calls have been made that match:\n". + " %s->%s(%s)\n". + "but expected at least one.", + + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard() + ), $method); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php new file mode 100644 index 0000000..31c6c57 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php @@ -0,0 +1,107 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Argument\Token\AnyValuesToken; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\UnexpectedCallsCountException; + +/** + * Prediction interface. + * Predictions are logical test blocks, tied to `should...` keyword. + * + * @author Konstantin Kudryashov + */ +class CallTimesPrediction implements PredictionInterface +{ + private $times; + private $util; + + /** + * Initializes prediction. + * + * @param int $times + * @param StringUtil $util + */ + public function __construct($times, StringUtil $util = null) + { + $this->times = intval($times); + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there was exact amount of calls made. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\UnexpectedCallsCountException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if ($this->times == count($calls)) { + return; + } + + $methodCalls = $object->findProphecyMethodCalls( + $method->getMethodName(), + new ArgumentsWildcard(array(new AnyValuesToken)) + ); + + if (count($calls)) { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but %d were made:\n%s", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + count($calls), + $this->util->stringifyCalls($calls) + ); + } elseif (count($methodCalls)) { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but none were made.\n". + "Recorded `%s(...)` calls:\n%s", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + $method->getMethodName(), + $this->util->stringifyCalls($methodCalls) + ); + } else { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but none were made.", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard() + ); + } + + throw new UnexpectedCallsCountException($message, $method, $this->times, $calls); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php new file mode 100644 index 0000000..44bc782 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php @@ -0,0 +1,65 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use Closure; + +/** + * Callback prediction. + * + * @author Konstantin Kudryashov + */ +class CallbackPrediction implements PredictionInterface +{ + private $callback; + + /** + * Initializes callback prediction. + * + * @param callable $callback Custom callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackPrediction, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Executes preset callback. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + $callback = $this->callback; + + if ($callback instanceof Closure && method_exists('Closure', 'bind')) { + $callback = Closure::bind($callback, $object); + } + + call_user_func($callback, $calls, $object, $method); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php new file mode 100644 index 0000000..46ac5bf --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php @@ -0,0 +1,68 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\UnexpectedCallsException; + +/** + * No calls prediction. + * + * @author Konstantin Kudryashov + */ +class NoCallsPrediction implements PredictionInterface +{ + private $util; + + /** + * Initializes prediction. + * + * @param null|StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there were no calls made. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\UnexpectedCallsException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if (!count($calls)) { + return; + } + + $verb = count($calls) === 1 ? 'was' : 'were'; + + throw new UnexpectedCallsException(sprintf( + "No calls expected that match:\n". + " %s->%s(%s)\n". + "but %d %s made:\n%s", + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + count($calls), + $verb, + $this->util->stringifyCalls($calls) + ), $method, $calls); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php new file mode 100644 index 0000000..f7fb06a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php @@ -0,0 +1,37 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Prediction interface. + * Predictions are logical test blocks, tied to `should...` keyword. + * + * @author Konstantin Kudryashov + */ +interface PredictionInterface +{ + /** + * Tests that double fulfilled prediction. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws object + * @return void + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php new file mode 100644 index 0000000..5f406bf --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php @@ -0,0 +1,66 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use Closure; + +/** + * Callback promise. + * + * @author Konstantin Kudryashov + */ +class CallbackPromise implements PromiseInterface +{ + private $callback; + + /** + * Initializes callback promise. + * + * @param callable $callback Custom callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackPromise, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Evaluates promise callback. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + $callback = $this->callback; + + if ($callback instanceof Closure && method_exists('Closure', 'bind')) { + $callback = Closure::bind($callback, $object); + } + + return call_user_func($callback, $args, $object, $method); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php new file mode 100644 index 0000000..382537b --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php @@ -0,0 +1,35 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Promise interface. + * Promises are logical blocks, tied to `will...` keyword. + * + * @author Konstantin Kudryashov + */ +interface PromiseInterface +{ + /** + * Evaluates promise. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php new file mode 100644 index 0000000..a06724b --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php @@ -0,0 +1,61 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Return argument promise. + * + * @author Konstantin Kudryashov + */ +class ReturnArgumentPromise implements PromiseInterface +{ + /** + * @var int + */ + private $index; + + /** + * Initializes callback promise. + * + * @param int $index The zero-indexed number of the argument to return + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($index = 0) + { + if (!is_int($index) || $index < 0) { + throw new InvalidArgumentException( + 'Zero-based index expected as argument to ReturnArgumentPromise, but got %s.', + $index + ); + } + $this->index = $index; + } + + /** + * Returns nth argument if has one, null otherwise. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return null|mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + return count($args) > $this->index ? $args[$this->index] : null; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php new file mode 100644 index 0000000..c7d5ac5 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php @@ -0,0 +1,55 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Return promise. + * + * @author Konstantin Kudryashov + */ +class ReturnPromise implements PromiseInterface +{ + private $returnValues = array(); + + /** + * Initializes promise. + * + * @param array $returnValues Array of values + */ + public function __construct(array $returnValues) + { + $this->returnValues = $returnValues; + } + + /** + * Returns saved values one by one until last one, then continuously returns last value. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + $value = array_shift($this->returnValues); + + if (!count($this->returnValues)) { + $this->returnValues[] = $value; + } + + return $value; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php new file mode 100644 index 0000000..8007330 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php @@ -0,0 +1,91 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Doctrine\Instantiator\Instantiator; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use ReflectionClass; + +/** + * Throw promise. + * + * @author Konstantin Kudryashov + */ +class ThrowPromise implements PromiseInterface +{ + private $exception; + + /** + * @var \Doctrine\Instantiator\Instantiator + */ + private $instantiator; + + /** + * Initializes promise. + * + * @param string|\Exception $exception Exception class name or instance + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($exception) + { + if (is_string($exception)) { + if (!class_exists($exception) + && 'Exception' !== $exception + && !is_subclass_of($exception, 'Exception')) { + throw new InvalidArgumentException(sprintf( + 'Exception class or instance expected as argument to ThrowPromise, but got %s.', + gettype($exception) + )); + } + } elseif (!$exception instanceof \Exception) { + throw new InvalidArgumentException(sprintf( + 'Exception class or instance expected as argument to ThrowPromise, but got %s.', + gettype($exception) + )); + } + + $this->exception = $exception; + } + + /** + * Throws predefined exception. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws object + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + if (is_string($this->exception)) { + $classname = $this->exception; + $reflection = new ReflectionClass($classname); + $constructor = $reflection->getConstructor(); + + if ($constructor->isPublic() && 0 == $constructor->getNumberOfRequiredParameters()) { + throw $reflection->newInstance(); + } + + if (!$this->instantiator) { + $this->instantiator = new Instantiator(); + } + + throw $this->instantiator->instantiate($classname); + } + + throw $this->exception; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php new file mode 100644 index 0000000..426df32 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php @@ -0,0 +1,437 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +use Prophecy\Argument; +use Prophecy\Prophet; +use Prophecy\Promise; +use Prophecy\Prediction; +use Prophecy\Exception\Doubler\MethodNotFoundException; +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Exception\Prophecy\MethodProphecyException; + +/** + * Method prophecy. + * + * @author Konstantin Kudryashov + */ +class MethodProphecy +{ + private $objectProphecy; + private $methodName; + private $argumentsWildcard; + private $promise; + private $prediction; + private $checkedPredictions = array(); + private $bound = false; + + /** + * Initializes method prophecy. + * + * @param ObjectProphecy $objectProphecy + * @param string $methodName + * @param null|Argument\ArgumentsWildcard|array $arguments + * + * @throws \Prophecy\Exception\Doubler\MethodNotFoundException If method not found + */ + public function __construct(ObjectProphecy $objectProphecy, $methodName, $arguments = null) + { + $double = $objectProphecy->reveal(); + if (!method_exists($double, $methodName)) { + throw new MethodNotFoundException(sprintf( + 'Method `%s::%s()` is not defined.', get_class($double), $methodName + ), get_class($double), $methodName, $arguments); + } + + $this->objectProphecy = $objectProphecy; + $this->methodName = $methodName; + + $reflectedMethod = new \ReflectionMethod($double, $methodName); + if ($reflectedMethod->isFinal()) { + throw new MethodProphecyException(sprintf( + "Can not add prophecy for a method `%s::%s()`\n". + "as it is a final method.", + get_class($double), + $methodName + ), $this); + } + + if (null !== $arguments) { + $this->withArguments($arguments); + } + + if (version_compare(PHP_VERSION, '7.0', '>=') && true === $reflectedMethod->hasReturnType()) { + $type = (string) $reflectedMethod->getReturnType(); + $this->will(function () use ($type) { + switch ($type) { + case 'string': return ''; + case 'float': return 0.0; + case 'int': return 0; + case 'bool': return false; + case 'array': return array(); + + case 'callable': + case 'Closure': + return function () {}; + + case 'Traversable': + case 'Generator': + // Remove eval() when minimum version >=5.5 + $generator = eval('return function () { yield; };'); + return $generator(); + + default: + $prophet = new Prophet; + return $prophet->prophesize($type)->reveal(); + } + }); + } + } + + /** + * Sets argument wildcard. + * + * @param array|Argument\ArgumentsWildcard $arguments + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function withArguments($arguments) + { + if (is_array($arguments)) { + $arguments = new Argument\ArgumentsWildcard($arguments); + } + + if (!$arguments instanceof Argument\ArgumentsWildcard) { + throw new InvalidArgumentException(sprintf( + "Either an array or an instance of ArgumentsWildcard expected as\n". + 'a `MethodProphecy::withArguments()` argument, but got %s.', + gettype($arguments) + )); + } + + $this->argumentsWildcard = $arguments; + + return $this; + } + + /** + * Sets custom promise to the prophecy. + * + * @param callable|Promise\PromiseInterface $promise + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function will($promise) + { + if (is_callable($promise)) { + $promise = new Promise\CallbackPromise($promise); + } + + if (!$promise instanceof Promise\PromiseInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PromiseInterface, but got %s.', + gettype($promise) + )); + } + + $this->bindToObjectProphecy(); + $this->promise = $promise; + + return $this; + } + + /** + * Sets return promise to the prophecy. + * + * @see Prophecy\Promise\ReturnPromise + * + * @return $this + */ + public function willReturn() + { + return $this->will(new Promise\ReturnPromise(func_get_args())); + } + + /** + * Sets return argument promise to the prophecy. + * + * @param int $index The zero-indexed number of the argument to return + * + * @see Prophecy\Promise\ReturnArgumentPromise + * + * @return $this + */ + public function willReturnArgument($index = 0) + { + return $this->will(new Promise\ReturnArgumentPromise($index)); + } + + /** + * Sets throw promise to the prophecy. + * + * @see Prophecy\Promise\ThrowPromise + * + * @param string|\Exception $exception Exception class or instance + * + * @return $this + */ + public function willThrow($exception) + { + return $this->will(new Promise\ThrowPromise($exception)); + } + + /** + * Sets custom prediction to the prophecy. + * + * @param callable|Prediction\PredictionInterface $prediction + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function should($prediction) + { + if (is_callable($prediction)) { + $prediction = new Prediction\CallbackPrediction($prediction); + } + + if (!$prediction instanceof Prediction\PredictionInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PredictionInterface, but got %s.', + gettype($prediction) + )); + } + + $this->bindToObjectProphecy(); + $this->prediction = $prediction; + + return $this; + } + + /** + * Sets call prediction to the prophecy. + * + * @see Prophecy\Prediction\CallPrediction + * + * @return $this + */ + public function shouldBeCalled() + { + return $this->should(new Prediction\CallPrediction); + } + + /** + * Sets no calls prediction to the prophecy. + * + * @see Prophecy\Prediction\NoCallsPrediction + * + * @return $this + */ + public function shouldNotBeCalled() + { + return $this->should(new Prediction\NoCallsPrediction); + } + + /** + * Sets call times prediction to the prophecy. + * + * @see Prophecy\Prediction\CallTimesPrediction + * + * @param $count + * + * @return $this + */ + public function shouldBeCalledTimes($count) + { + return $this->should(new Prediction\CallTimesPrediction($count)); + } + + /** + * Checks provided prediction immediately. + * + * @param callable|Prediction\PredictionInterface $prediction + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function shouldHave($prediction) + { + if (is_callable($prediction)) { + $prediction = new Prediction\CallbackPrediction($prediction); + } + + if (!$prediction instanceof Prediction\PredictionInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PredictionInterface, but got %s.', + gettype($prediction) + )); + } + + if (null === $this->promise) { + $this->willReturn(); + } + + $calls = $this->getObjectProphecy()->findProphecyMethodCalls( + $this->getMethodName(), + $this->getArgumentsWildcard() + ); + + try { + $prediction->check($calls, $this->getObjectProphecy(), $this); + $this->checkedPredictions[] = $prediction; + } catch (\Exception $e) { + $this->checkedPredictions[] = $prediction; + + throw $e; + } + + return $this; + } + + /** + * Checks call prediction. + * + * @see Prophecy\Prediction\CallPrediction + * + * @return $this + */ + public function shouldHaveBeenCalled() + { + return $this->shouldHave(new Prediction\CallPrediction); + } + + /** + * Checks no calls prediction. + * + * @see Prophecy\Prediction\NoCallsPrediction + * + * @return $this + */ + public function shouldNotHaveBeenCalled() + { + return $this->shouldHave(new Prediction\NoCallsPrediction); + } + + /** + * Checks no calls prediction. + * + * @see Prophecy\Prediction\NoCallsPrediction + * @deprecated + * + * @return $this + */ + public function shouldNotBeenCalled() + { + return $this->shouldNotHaveBeenCalled(); + } + + /** + * Checks call times prediction. + * + * @see Prophecy\Prediction\CallTimesPrediction + * + * @param int $count + * + * @return $this + */ + public function shouldHaveBeenCalledTimes($count) + { + return $this->shouldHave(new Prediction\CallTimesPrediction($count)); + } + + /** + * Checks currently registered [with should(...)] prediction. + */ + public function checkPrediction() + { + if (null === $this->prediction) { + return; + } + + $this->shouldHave($this->prediction); + } + + /** + * Returns currently registered promise. + * + * @return null|Promise\PromiseInterface + */ + public function getPromise() + { + return $this->promise; + } + + /** + * Returns currently registered prediction. + * + * @return null|Prediction\PredictionInterface + */ + public function getPrediction() + { + return $this->prediction; + } + + /** + * Returns predictions that were checked on this object. + * + * @return Prediction\PredictionInterface[] + */ + public function getCheckedPredictions() + { + return $this->checkedPredictions; + } + + /** + * Returns object prophecy this method prophecy is tied to. + * + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } + + /** + * Returns method name. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * Returns arguments wildcard. + * + * @return Argument\ArgumentsWildcard + */ + public function getArgumentsWildcard() + { + return $this->argumentsWildcard; + } + + private function bindToObjectProphecy() + { + if ($this->bound) { + return; + } + + $this->getObjectProphecy()->addMethodProphecy($this); + $this->bound = true; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php new file mode 100644 index 0000000..43dba46 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php @@ -0,0 +1,279 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Call\Call; +use Prophecy\Doubler\LazyDouble; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Call\CallCenter; +use Prophecy\Exception\Prophecy\ObjectProphecyException; +use Prophecy\Exception\Prophecy\MethodProphecyException; +use Prophecy\Exception\Prediction\AggregateException; +use Prophecy\Exception\Prediction\PredictionException; + +/** + * Object prophecy. + * + * @author Konstantin Kudryashov + */ +class ObjectProphecy implements ProphecyInterface +{ + private $lazyDouble; + private $callCenter; + private $revealer; + private $comparatorFactory; + + /** + * @var MethodProphecy[][] + */ + private $methodProphecies = array(); + + /** + * Initializes object prophecy. + * + * @param LazyDouble $lazyDouble + * @param CallCenter $callCenter + * @param RevealerInterface $revealer + * @param ComparatorFactory $comparatorFactory + */ + public function __construct( + LazyDouble $lazyDouble, + CallCenter $callCenter = null, + RevealerInterface $revealer = null, + ComparatorFactory $comparatorFactory = null + ) { + $this->lazyDouble = $lazyDouble; + $this->callCenter = $callCenter ?: new CallCenter; + $this->revealer = $revealer ?: new Revealer; + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Forces double to extend specific class. + * + * @param string $class + * + * @return $this + */ + public function willExtend($class) + { + $this->lazyDouble->setParentClass($class); + + return $this; + } + + /** + * Forces double to implement specific interface. + * + * @param string $interface + * + * @return $this + */ + public function willImplement($interface) + { + $this->lazyDouble->addInterface($interface); + + return $this; + } + + /** + * Sets constructor arguments. + * + * @param array $arguments + * + * @return $this + */ + public function willBeConstructedWith(array $arguments = null) + { + $this->lazyDouble->setArguments($arguments); + + return $this; + } + + /** + * Reveals double. + * + * @return object + * + * @throws \Prophecy\Exception\Prophecy\ObjectProphecyException If double doesn't implement needed interface + */ + public function reveal() + { + $double = $this->lazyDouble->getInstance(); + + if (null === $double || !$double instanceof ProphecySubjectInterface) { + throw new ObjectProphecyException( + "Generated double must implement ProphecySubjectInterface, but it does not.\n". + 'It seems you have wrongly configured doubler without required ClassPatch.', + $this + ); + } + + $double->setProphecy($this); + + return $double; + } + + /** + * Adds method prophecy to object prophecy. + * + * @param MethodProphecy $methodProphecy + * + * @throws \Prophecy\Exception\Prophecy\MethodProphecyException If method prophecy doesn't + * have arguments wildcard + */ + public function addMethodProphecy(MethodProphecy $methodProphecy) + { + $argumentsWildcard = $methodProphecy->getArgumentsWildcard(); + if (null === $argumentsWildcard) { + throw new MethodProphecyException(sprintf( + "Can not add prophecy for a method `%s::%s()`\n". + "as you did not specify arguments wildcard for it.", + get_class($this->reveal()), + $methodProphecy->getMethodName() + ), $methodProphecy); + } + + $methodName = $methodProphecy->getMethodName(); + + if (!isset($this->methodProphecies[$methodName])) { + $this->methodProphecies[$methodName] = array(); + } + + $this->methodProphecies[$methodName][] = $methodProphecy; + } + + /** + * Returns either all or related to single method prophecies. + * + * @param null|string $methodName + * + * @return MethodProphecy[] + */ + public function getMethodProphecies($methodName = null) + { + if (null === $methodName) { + return $this->methodProphecies; + } + + if (!isset($this->methodProphecies[$methodName])) { + return array(); + } + + return $this->methodProphecies[$methodName]; + } + + /** + * Makes specific method call. + * + * @param string $methodName + * @param array $arguments + * + * @return mixed + */ + public function makeProphecyMethodCall($methodName, array $arguments) + { + $arguments = $this->revealer->reveal($arguments); + $return = $this->callCenter->makeCall($this, $methodName, $arguments); + + return $this->revealer->reveal($return); + } + + /** + * Finds calls by method name & arguments wildcard. + * + * @param string $methodName + * @param ArgumentsWildcard $wildcard + * + * @return Call[] + */ + public function findProphecyMethodCalls($methodName, ArgumentsWildcard $wildcard) + { + return $this->callCenter->findCalls($methodName, $wildcard); + } + + /** + * Checks that registered method predictions do not fail. + * + * @throws \Prophecy\Exception\Prediction\AggregateException If any of registered predictions fail + */ + public function checkProphecyMethodsPredictions() + { + $exception = new AggregateException(sprintf("%s:\n", get_class($this->reveal()))); + $exception->setObjectProphecy($this); + + foreach ($this->methodProphecies as $prophecies) { + foreach ($prophecies as $prophecy) { + try { + $prophecy->checkPrediction(); + } catch (PredictionException $e) { + $exception->append($e); + } + } + } + + if (count($exception->getExceptions())) { + throw $exception; + } + } + + /** + * Creates new method prophecy using specified method name and arguments. + * + * @param string $methodName + * @param array $arguments + * + * @return MethodProphecy + */ + public function __call($methodName, array $arguments) + { + $arguments = new ArgumentsWildcard($this->revealer->reveal($arguments)); + + foreach ($this->getMethodProphecies($methodName) as $prophecy) { + $argumentsWildcard = $prophecy->getArgumentsWildcard(); + $comparator = $this->comparatorFactory->getComparatorFor( + $argumentsWildcard, $arguments + ); + + try { + $comparator->assertEquals($argumentsWildcard, $arguments); + return $prophecy; + } catch (ComparisonFailure $failure) {} + } + + return new MethodProphecy($this, $methodName, $arguments); + } + + /** + * Tries to get property value from double. + * + * @param string $name + */ + public function __get($name) + { + return $this->reveal()->$name; + } + + /** + * Tries to set property value to double. + * + * @param string $name + * @param string $value + */ + public function __set($name, $value) + { + $this->reveal()->$name = $this->revealer->reveal($value); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php new file mode 100644 index 0000000..462f15a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php @@ -0,0 +1,27 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Core Prophecy interface. + * + * @author Konstantin Kudryashov + */ +interface ProphecyInterface +{ + /** + * Reveals prophecy object (double) . + * + * @return object + */ + public function reveal(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php new file mode 100644 index 0000000..2d83958 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Controllable doubles interface. + * + * @author Konstantin Kudryashov + */ +interface ProphecySubjectInterface +{ + /** + * Sets subject prophecy. + * + * @param ProphecyInterface $prophecy + */ + public function setProphecy(ProphecyInterface $prophecy); + + /** + * Returns subject prophecy. + * + * @return ProphecyInterface + */ + public function getProphecy(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php new file mode 100644 index 0000000..60ecdac --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php @@ -0,0 +1,44 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Basic prophecies revealer. + * + * @author Konstantin Kudryashov + */ +class Revealer implements RevealerInterface +{ + /** + * Unwraps value(s). + * + * @param mixed $value + * + * @return mixed + */ + public function reveal($value) + { + if (is_array($value)) { + return array_map(array($this, __FUNCTION__), $value); + } + + if (!is_object($value)) { + return $value; + } + + if ($value instanceof ProphecyInterface) { + $value = $value->reveal(); + } + + return $value; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php new file mode 100644 index 0000000..ffc82bb --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php @@ -0,0 +1,29 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Prophecies revealer interface. + * + * @author Konstantin Kudryashov + */ +interface RevealerInterface +{ + /** + * Unwraps value(s). + * + * @param mixed $value + * + * @return mixed + */ + public function reveal($value); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophet.php b/vendor/phpspec/prophecy/src/Prophecy/Prophet.php new file mode 100644 index 0000000..ac64923 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophet.php @@ -0,0 +1,134 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy; + +use Prophecy\Doubler\Doubler; +use Prophecy\Doubler\LazyDouble; +use Prophecy\Doubler\ClassPatch; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\RevealerInterface; +use Prophecy\Prophecy\Revealer; +use Prophecy\Call\CallCenter; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\PredictionException; +use Prophecy\Exception\Prediction\AggregateException; + +/** + * Prophet creates prophecies. + * + * @author Konstantin Kudryashov + */ +class Prophet +{ + private $doubler; + private $revealer; + private $util; + + /** + * @var ObjectProphecy[] + */ + private $prophecies = array(); + + /** + * Initializes Prophet. + * + * @param null|Doubler $doubler + * @param null|RevealerInterface $revealer + * @param null|StringUtil $util + */ + public function __construct(Doubler $doubler = null, RevealerInterface $revealer = null, + StringUtil $util = null) + { + if (null === $doubler) { + $doubler = new Doubler; + $doubler->registerClassPatch(new ClassPatch\SplFileInfoPatch); + $doubler->registerClassPatch(new ClassPatch\TraversablePatch); + $doubler->registerClassPatch(new ClassPatch\DisableConstructorPatch); + $doubler->registerClassPatch(new ClassPatch\ProphecySubjectPatch); + $doubler->registerClassPatch(new ClassPatch\ReflectionClassNewInstancePatch); + $doubler->registerClassPatch(new ClassPatch\HhvmExceptionPatch()); + $doubler->registerClassPatch(new ClassPatch\MagicCallPatch); + $doubler->registerClassPatch(new ClassPatch\KeywordPatch); + } + + $this->doubler = $doubler; + $this->revealer = $revealer ?: new Revealer; + $this->util = $util ?: new StringUtil; + } + + /** + * Creates new object prophecy. + * + * @param null|string $classOrInterface Class or interface name + * + * @return ObjectProphecy + */ + public function prophesize($classOrInterface = null) + { + $this->prophecies[] = $prophecy = new ObjectProphecy( + new LazyDouble($this->doubler), + new CallCenter($this->util), + $this->revealer + ); + + if ($classOrInterface && class_exists($classOrInterface)) { + return $prophecy->willExtend($classOrInterface); + } + + if ($classOrInterface && interface_exists($classOrInterface)) { + return $prophecy->willImplement($classOrInterface); + } + + return $prophecy; + } + + /** + * Returns all created object prophecies. + * + * @return ObjectProphecy[] + */ + public function getProphecies() + { + return $this->prophecies; + } + + /** + * Returns Doubler instance assigned to this Prophet. + * + * @return Doubler + */ + public function getDoubler() + { + return $this->doubler; + } + + /** + * Checks all predictions defined by prophecies of this Prophet. + * + * @throws Exception\Prediction\AggregateException If any prediction fails + */ + public function checkPredictions() + { + $exception = new AggregateException("Some predictions failed:\n"); + foreach ($this->prophecies as $prophecy) { + try { + $prophecy->checkProphecyMethodsPredictions(); + } catch (PredictionException $e) { + $exception->append($e); + } + } + + if (count($exception->getExceptions())) { + throw $exception; + } + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php b/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php new file mode 100644 index 0000000..54d3832 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php @@ -0,0 +1,185 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Exporting utility. + * + * This class is derived from the PHPUnit testing framework. + * + * @author Sebastiaan Stok + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License> + */ +class ExportUtil +{ + /** + * Exports a value into a string. + * + * The output of this method is similar to the output of print_r(), but + * improved in various aspects: + * + * - NULL is rendered as "null" (instead of "") + * - true is rendered as "true" (instead of "1") + * - FALSE is rendered as "false" (instead of "") + * - Strings are always quoted with single quotes + * - Carriage returns and newlines are normalized to \n + * - Recursion and repeated rendering is treated properly + * + * @param mixed $value The value to export + * @param integer $indentation The indentation level of the 2nd+ line + * + * @return string + */ + public static function export($value, $indentation = 0) + { + return static::recursiveExport($value, $indentation); + } + + /** + * Converts an object to an array containing all of its private, protected + * and public properties. + * + * @param object $object + * + * @return array + */ + public static function toArray($object) + { + $array = array(); + + foreach ((array) $object as $key => $value) { + // properties are transformed to keys in the following way: + + // private $property => "\0Classname\0property" + // protected $property => "\0*\0property" + // public $property => "property" + + if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) { + $key = $matches[1]; + } + + $array[$key] = $value; + } + + // Some internal classes like SplObjectStorage don't work with the + // above (fast) mechanism nor with reflection + // Format the output similarly to print_r() in this case + if ($object instanceof SplObjectStorage) { + foreach ($object as $key => $value) { + $array[spl_object_hash($value)] = array( + 'obj' => $value, + 'inf' => $object->getInfo(), + ); + } + } + + return $array; + } + + /** + * Recursive implementation of export. + * + * @param mixed $value The value to export + * @param integer $indentation The indentation level of the 2nd+ line + * @param array $processedObjects Contains all objects that were already + * rendered + * + * @return string + */ + protected static function recursiveExport($value, $indentation, &$processedObjects = array()) + { + if ($value === null) { + return 'null'; + } + + if ($value === true) { + return 'true'; + } + + if ($value === false) { + return 'false'; + } + + if (is_string($value)) { + // Match for most non printable chars somewhat taking multibyte chars into account + if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) { + return 'Binary String: 0x' . bin2hex($value); + } + + return "'" . str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) . "'"; + } + + $origValue = $value; + + if (is_object($value)) { + if ($value instanceof ProphecyInterface) { + return sprintf('%s Object (*Prophecy*)', get_class($value)); + } elseif (in_array($value, $processedObjects, true)) { + return sprintf('%s Object (*RECURSION*)', get_class($value)); + } + + $processedObjects[] = $value; + + // Convert object to array + $value = self::toArray($value); + } + + if (is_array($value)) { + $whitespace = str_repeat(' ', $indentation); + + // There seems to be no other way to check arrays for recursion + // http://www.php.net/manual/en/language.types.array.php#73936 + preg_match_all('/\n \[(\w+)\] => Array\s+\*RECURSION\*/', print_r($value, true), $matches); + $recursiveKeys = array_unique($matches[1]); + + // Convert to valid array keys + // Numeric integer strings are automatically converted to integers + // by PHP + foreach ($recursiveKeys as $key => $recursiveKey) { + if ((string) (integer) $recursiveKey === $recursiveKey) { + $recursiveKeys[$key] = (integer) $recursiveKey; + } + } + + $content = ''; + + foreach ($value as $key => $val) { + if (in_array($key, $recursiveKeys, true)) { + $val = 'Array (*RECURSION*)'; + } else { + $val = self::recursiveExport($val, $indentation + 1, $processedObjects); + } + + $content .= $whitespace . ' ' . self::export($key) . ' => ' . $val . "\n"; + } + + if (strlen($content) > 0) { + $content = "\n" . $content . $whitespace; + } + + return sprintf( + "%s (%s)", + is_object($origValue) ? sprintf('%s:%s', get_class($origValue), spl_object_hash($origValue)) . ' Object' : 'Array', $content + ); + } + + if (is_double($value) && (double)(integer) $value === $value) { + return $value . '.0'; + } + + return (string) $value; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php b/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php new file mode 100644 index 0000000..bb90156 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php @@ -0,0 +1,89 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Util; + +use Prophecy\Call\Call; + +/** + * String utility. + * + * @author Konstantin Kudryashov + */ +class StringUtil +{ + /** + * Stringifies any provided value. + * + * @param mixed $value + * @param boolean $exportObject + * + * @return string + */ + public function stringify($value, $exportObject = true) + { + if (is_array($value)) { + if (range(0, count($value) - 1) === array_keys($value)) { + return '['.implode(', ', array_map(array($this, __FUNCTION__), $value)).']'; + } + + $stringify = array($this, __FUNCTION__); + + return '['.implode(', ', array_map(function ($item, $key) use ($stringify) { + return (is_integer($key) ? $key : '"'.$key.'"'). + ' => '.call_user_func($stringify, $item); + }, $value, array_keys($value))).']'; + } + if (is_resource($value)) { + return get_resource_type($value).':'.$value; + } + if (is_object($value)) { + return $exportObject ? ExportUtil::export($value) : sprintf('%s:%s', get_class($value), spl_object_hash($value)); + } + if (true === $value || false === $value) { + return $value ? 'true' : 'false'; + } + if (is_string($value)) { + $str = sprintf('"%s"', str_replace("\n", '\\n', $value)); + + if (50 <= strlen($str)) { + return substr($str, 0, 50).'"...'; + } + + return $str; + } + if (null === $value) { + return 'null'; + } + + return (string) $value; + } + + /** + * Stringifies provided array of calls. + * + * @param Call[] $calls Array of Call instances + * + * @return string + */ + public function stringifyCalls(array $calls) + { + $self = $this; + + return implode(PHP_EOL, array_map(function (Call $call) use ($self) { + return sprintf(' - %s(%s) @ %s', + $call->getMethodName(), + implode(', ', array_map(array($self, 'stringify'), $call->getArguments())), + str_replace(GETCWD().DIRECTORY_SEPARATOR, '', $call->getCallPlace()) + ); + }, $calls)); + } +} diff --git a/vendor/phpunit/php-code-coverage/.gitattributes b/vendor/phpunit/php-code-coverage/.gitattributes new file mode 100644 index 0000000..461090b --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.gitattributes @@ -0,0 +1 @@ +*.php diff=php diff --git a/vendor/phpunit/php-code-coverage/.gitignore b/vendor/phpunit/php-code-coverage/.gitignore new file mode 100644 index 0000000..b386531 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.gitignore @@ -0,0 +1,11 @@ +build/api +build/code-browser +build/coverage +build/logs +build/pdepend +cache.properties +phpunit.xml +/vendor +/composer.lock +/composer.phar +/.idea diff --git a/vendor/phpunit/php-code-coverage/.travis.yml b/vendor/phpunit/php-code-coverage/.travis.yml new file mode 100644 index 0000000..ad88a08 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.travis.yml @@ -0,0 +1,20 @@ +language: php + +php: + - 5.3.3 + - 5.3 + - 5.4 + - 5.5 + - 5.6 + +before_script: + - COMPOSER_ROOT_VERSION=dev-master composer install --prefer-source + +script: vendor/bin/phpunit --configuration ./build/travis-ci.xml + +notifications: + email: false + irc: + channels: + - "irc.freenode.org#phpunit" + use_notice: true diff --git a/vendor/phpunit/php-code-coverage/CONTRIBUTING.md b/vendor/phpunit/php-code-coverage/CONTRIBUTING.md new file mode 100644 index 0000000..40dbc25 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/CONTRIBUTING.md @@ -0,0 +1,5 @@ +Pull Requests for bug fixes should be made against the current release branch (2.0). + +Pull Requests for new features should be made against master. + +For further notes please refer to [https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md](https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md) diff --git a/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md b/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md new file mode 100644 index 0000000..353b6f6 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md @@ -0,0 +1,56 @@ +# Changes in PHP_CodeCoverage 2.2 + +All notable changes of the PHP_CodeCoverage 2.2 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [2.2.4] - 2015-10-06 + +### Fixed + +* Fixed [#391](https://github.com/sebastianbergmann/php-code-coverage/pull/391): Missing `` tag + +## [2.2.3] - 2015-09-14 + +### Fixed + +* Fixed [#368](https://github.com/sebastianbergmann/php-code-coverage/pull/368): Blacklists and whitelists are not merged when merging data sets +* Fixed [#370](https://github.com/sebastianbergmann/php-code-coverage/issues/370): Confusing statistics for source file that declares a class without methods +* Fixed [#372](https://github.com/sebastianbergmann/php-code-coverage/pull/372): Nested classes and functions are not handled correctly +* Fixed [#382](https://github.com/sebastianbergmann/php-code-coverage/issues/382): Crap4J report generates incorrect XML logfile + +## [2.2.2] - 2015-08-04 + +### Added + +* Reintroduced the `PHP_CodeCoverage_Driver_HHVM` driver as an extension of `PHP_CodeCoverage_Driver_Xdebug` that does not use `xdebug_start_code_coverage()` with options not supported by HHVM + +### Changed + +* Bumped required version of `sebastian/environment` to 1.3.2 for [#365](https://github.com/sebastianbergmann/php-code-coverage/issues/365) + +## [2.2.1] - 2015-08-02 + +### Changed + +* Bumped required version of `sebastian/environment` to 1.3.1 for [#365](https://github.com/sebastianbergmann/php-code-coverage/issues/365) + +## [2.2.0] - 2015-08-01 + +### Added + +* Added a driver for PHPDBG (requires PHP 7) +* Added `PHP_CodeCoverage::setDisableIgnoredLines()` to disable the ignoring of lines using annotations such as `@codeCoverageIgnore` + +### Changed + +* Annotating a method with `@deprecated` now has the same effect as annotating it with `@codeCoverageIgnore` + +### Removed + +* The dedicated driver for HHVM, `PHP_CodeCoverage_Driver_HHVM` has been removed + +[2.2.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.3...2.2.4 +[2.2.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.2...2.2.3 +[2.2.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.1...2.2.2 +[2.2.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.0...2.2.1 +[2.2.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.1...2.2.0 + diff --git a/vendor/phpunit/php-code-coverage/LICENSE b/vendor/phpunit/php-code-coverage/LICENSE new file mode 100644 index 0000000..fcfa37e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/LICENSE @@ -0,0 +1,33 @@ +PHP_CodeCoverage + +Copyright (c) 2009-2015, Sebastian Bergmann . +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/phpunit/php-code-coverage/README.md b/vendor/phpunit/php-code-coverage/README.md new file mode 100644 index 0000000..4411d7f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/README.md @@ -0,0 +1,50 @@ +[![Latest Stable Version](https://poser.pugx.org/phpunit/php-code-coverage/v/stable.png)](https://packagist.org/packages/phpunit/php-code-coverage) +[![Build Status](https://travis-ci.org/sebastianbergmann/php-code-coverage.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-code-coverage) + +# PHP_CodeCoverage + +**PHP_CodeCoverage** is a library that provides collection, processing, and rendering functionality for PHP code coverage information. + +## Requirements + +PHP 5.3.3 is required but using the latest version of PHP is highly recommended + +### PHP 5 + +[Xdebug](http://xdebug.org/) is the only source of raw code coverage data supported for PHP 5. Version 2.1.3 of Xdebug is required but using the latest version is highly recommended. + +### PHP 7 + +[phpdbg](http://phpdbg.com/docs) is currently the only source of raw code coverage data supported for PHP 7. Once Xdebug has been updated for PHP 7 it, too, will be supported. + +### HHVM + +A version of HHVM that implements the Xdebug API for code coverage (`xdebug_*_code_coverage()`) is required. + +## Installation + +To add PHP_CodeCoverage as a local, per-project dependency to your project, simply add a dependency on `phpunit/php-code-coverage` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on PHP_CodeCoverage 2.0: + + { + "require": { + "phpunit/php-code-coverage": "^2" + } + } + +## Using the PHP_CodeCoverage API + +```php +start(''); + +// ... + +$coverage->stop(); + +$writer = new PHP_CodeCoverage_Report_Clover; +$writer->process($coverage, '/tmp/clover.xml'); + +$writer = new PHP_CodeCoverage_Report_HTML; +$writer->process($coverage, '/tmp/code-coverage-report'); +``` diff --git a/vendor/phpunit/php-code-coverage/build.xml b/vendor/phpunit/php-code-coverage/build.xml new file mode 100644 index 0000000..c335d15 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/build.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/build/travis-ci.xml b/vendor/phpunit/php-code-coverage/build/travis-ci.xml new file mode 100644 index 0000000..15e879f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/build/travis-ci.xml @@ -0,0 +1,21 @@ + + + + + + ../tests/PHP + + + + + + + + + + ../src + + + diff --git a/vendor/phpunit/php-code-coverage/composer.json b/vendor/phpunit/php-code-coverage/composer.json new file mode 100644 index 0000000..55f9fd0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/composer.json @@ -0,0 +1,50 @@ +{ + "name": "phpunit/php-code-coverage", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "type": "library", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "irc": "irc://irc.freenode.net/phpunit" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-token-stream": "~1.3", + "phpunit/php-text-template": "~1.2", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4", + "ext-xdebug": ">=2.1.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + } +} diff --git a/vendor/phpunit/php-code-coverage/phpunit.xml.dist b/vendor/phpunit/php-code-coverage/phpunit.xml.dist new file mode 100644 index 0000000..f5fa606 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/phpunit.xml.dist @@ -0,0 +1,23 @@ + + + + + tests/PHP + + + + + + + + + + + + src + + + + diff --git a/vendor/phpunit/php-code-coverage/scripts/auto_append.php b/vendor/phpunit/php-code-coverage/scripts/auto_append.php new file mode 100644 index 0000000..6cd768d --- /dev/null +++ b/vendor/phpunit/php-code-coverage/scripts/auto_append.php @@ -0,0 +1,5 @@ +stop(); + +$writer = new PHP_CodeCoverage_Report_HTML; +$writer->process($coverage, '/tmp/coverage'); diff --git a/vendor/phpunit/php-code-coverage/scripts/auto_prepend.php b/vendor/phpunit/php-code-coverage/scripts/auto_prepend.php new file mode 100644 index 0000000..7a8887a --- /dev/null +++ b/vendor/phpunit/php-code-coverage/scripts/auto_prepend.php @@ -0,0 +1,10 @@ +filter(); + +$filter->addFileToBlacklist(__FILE__); +$filter->addFileToBlacklist(dirname(__FILE__) . '/auto_append.php'); + +$coverage->start($_SERVER['SCRIPT_FILENAME']); diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage.php new file mode 100644 index 0000000..88326f0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage.php @@ -0,0 +1,920 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\Environment\Runtime; + +/** + * Provides collection functionality for PHP code coverage information. + * + * @since Class available since Release 1.0.0 + */ +class PHP_CodeCoverage +{ + /** + * @var PHP_CodeCoverage_Driver + */ + private $driver; + + /** + * @var PHP_CodeCoverage_Filter + */ + private $filter; + + /** + * @var bool + */ + private $cacheTokens = false; + + /** + * @var bool + */ + private $checkForUnintentionallyCoveredCode = false; + + /** + * @var bool + */ + private $forceCoversAnnotation = false; + + /** + * @var bool + */ + private $mapTestClassNameToCoveredClassName = false; + + /** + * @var bool + */ + private $addUncoveredFilesFromWhitelist = true; + + /** + * @var bool + */ + private $processUncoveredFilesFromWhitelist = false; + + /** + * @var mixed + */ + private $currentId; + + /** + * Code coverage data. + * + * @var array + */ + private $data = array(); + + /** + * @var array + */ + private $ignoredLines = array(); + + /** + * @var bool + */ + private $disableIgnoredLines = false; + + /** + * Test data. + * + * @var array + */ + private $tests = array(); + + /** + * Constructor. + * + * @param PHP_CodeCoverage_Driver $driver + * @param PHP_CodeCoverage_Filter $filter + * @throws PHP_CodeCoverage_Exception + */ + public function __construct(PHP_CodeCoverage_Driver $driver = null, PHP_CodeCoverage_Filter $filter = null) + { + if ($driver === null) { + $driver = $this->selectDriver(); + } + + if ($filter === null) { + $filter = new PHP_CodeCoverage_Filter; + } + + $this->driver = $driver; + $this->filter = $filter; + } + + /** + * Returns the PHP_CodeCoverage_Report_Node_* object graph + * for this PHP_CodeCoverage object. + * + * @return PHP_CodeCoverage_Report_Node_Directory + * @since Method available since Release 1.1.0 + */ + public function getReport() + { + $factory = new PHP_CodeCoverage_Report_Factory; + + return $factory->create($this); + } + + /** + * Clears collected code coverage data. + */ + public function clear() + { + $this->currentId = null; + $this->data = array(); + $this->tests = array(); + } + + /** + * Returns the PHP_CodeCoverage_Filter used. + * + * @return PHP_CodeCoverage_Filter + */ + public function filter() + { + return $this->filter; + } + + /** + * Returns the collected code coverage data. + * Set $raw = true to bypass all filters. + * + * @param bool $raw + * @return array + * @since Method available since Release 1.1.0 + */ + public function getData($raw = false) + { + if (!$raw && $this->addUncoveredFilesFromWhitelist) { + $this->addUncoveredFilesFromWhitelist(); + } + + // We need to apply the blacklist filter a second time + // when no whitelist is used. + if (!$raw && !$this->filter->hasWhitelist()) { + $this->applyListsFilter($this->data); + } + + return $this->data; + } + + /** + * Sets the coverage data. + * + * @param array $data + * @since Method available since Release 2.0.0 + */ + public function setData(array $data) + { + $this->data = $data; + } + + /** + * Returns the test data. + * + * @return array + * @since Method available since Release 1.1.0 + */ + public function getTests() + { + return $this->tests; + } + + /** + * Sets the test data. + * + * @param array $tests + * @since Method available since Release 2.0.0 + */ + public function setTests(array $tests) + { + $this->tests = $tests; + } + + /** + * Start collection of code coverage information. + * + * @param mixed $id + * @param bool $clear + * @throws PHP_CodeCoverage_Exception + */ + public function start($id, $clear = false) + { + if (!is_bool($clear)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + if ($clear) { + $this->clear(); + } + + $this->currentId = $id; + + $this->driver->start(); + } + + /** + * Stop collection of code coverage information. + * + * @param bool $append + * @param mixed $linesToBeCovered + * @param array $linesToBeUsed + * @return array + * @throws PHP_CodeCoverage_Exception + */ + public function stop($append = true, $linesToBeCovered = array(), array $linesToBeUsed = array()) + { + if (!is_bool($append)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 2, + 'array or false' + ); + } + + $data = $this->driver->stop(); + $this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed); + + $this->currentId = null; + + return $data; + } + + /** + * Appends code coverage data. + * + * @param array $data + * @param mixed $id + * @param bool $append + * @param mixed $linesToBeCovered + * @param array $linesToBeUsed + * @throws PHP_CodeCoverage_Exception + */ + public function append(array $data, $id = null, $append = true, $linesToBeCovered = array(), array $linesToBeUsed = array()) + { + if ($id === null) { + $id = $this->currentId; + } + + if ($id === null) { + throw new PHP_CodeCoverage_Exception; + } + + $this->applyListsFilter($data); + $this->applyIgnoredLinesFilter($data); + $this->initializeFilesThatAreSeenTheFirstTime($data); + + if (!$append) { + return; + } + + if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') { + $this->applyCoversAnnotationFilter( + $data, + $linesToBeCovered, + $linesToBeUsed + ); + } + + if (empty($data)) { + return; + } + + $size = 'unknown'; + $status = null; + + if ($id instanceof PHPUnit_Framework_TestCase) { + $_size = $id->getSize(); + + if ($_size == PHPUnit_Util_Test::SMALL) { + $size = 'small'; + } elseif ($_size == PHPUnit_Util_Test::MEDIUM) { + $size = 'medium'; + } elseif ($_size == PHPUnit_Util_Test::LARGE) { + $size = 'large'; + } + + $status = $id->getStatus(); + $id = get_class($id) . '::' . $id->getName(); + } elseif ($id instanceof PHPUnit_Extensions_PhptTestCase) { + $size = 'large'; + $id = $id->getName(); + } + + $this->tests[$id] = array('size' => $size, 'status' => $status); + + foreach ($data as $file => $lines) { + if (!$this->filter->isFile($file)) { + continue; + } + + foreach ($lines as $k => $v) { + if ($v == PHP_CodeCoverage_Driver::LINE_EXECUTED) { + if (empty($this->data[$file][$k]) || !in_array($id, $this->data[$file][$k])) { + $this->data[$file][$k][] = $id; + } + } + } + } + } + + /** + * Merges the data from another instance of PHP_CodeCoverage. + * + * @param PHP_CodeCoverage $that + */ + public function merge(PHP_CodeCoverage $that) + { + $this->filter->setBlacklistedFiles( + array_merge($this->filter->getBlacklistedFiles(), $that->filter()->getBlacklistedFiles()) + ); + + $this->filter->setWhitelistedFiles( + array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles()) + ); + + foreach ($that->data as $file => $lines) { + if (!isset($this->data[$file])) { + if (!$this->filter->isFiltered($file)) { + $this->data[$file] = $lines; + } + + continue; + } + + foreach ($lines as $line => $data) { + if ($data !== null) { + if (!isset($this->data[$file][$line])) { + $this->data[$file][$line] = $data; + } else { + $this->data[$file][$line] = array_unique( + array_merge($this->data[$file][$line], $data) + ); + } + } + } + } + + $this->tests = array_merge($this->tests, $that->getTests()); + + } + + /** + * @param bool $flag + * @throws PHP_CodeCoverage_Exception + * @since Method available since Release 1.1.0 + */ + public function setCacheTokens($flag) + { + if (!is_bool($flag)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + $this->cacheTokens = $flag; + } + + /** + * @since Method available since Release 1.1.0 + */ + public function getCacheTokens() + { + return $this->cacheTokens; + } + + /** + * @param bool $flag + * @throws PHP_CodeCoverage_Exception + * @since Method available since Release 2.0.0 + */ + public function setCheckForUnintentionallyCoveredCode($flag) + { + if (!is_bool($flag)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + $this->checkForUnintentionallyCoveredCode = $flag; + } + + /** + * @param bool $flag + * @throws PHP_CodeCoverage_Exception + */ + public function setForceCoversAnnotation($flag) + { + if (!is_bool($flag)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + $this->forceCoversAnnotation = $flag; + } + + /** + * @param bool $flag + * @throws PHP_CodeCoverage_Exception + */ + public function setMapTestClassNameToCoveredClassName($flag) + { + if (!is_bool($flag)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + $this->mapTestClassNameToCoveredClassName = $flag; + } + + /** + * @param bool $flag + * @throws PHP_CodeCoverage_Exception + */ + public function setAddUncoveredFilesFromWhitelist($flag) + { + if (!is_bool($flag)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + $this->addUncoveredFilesFromWhitelist = $flag; + } + + /** + * @param bool $flag + * @throws PHP_CodeCoverage_Exception + */ + public function setProcessUncoveredFilesFromWhitelist($flag) + { + if (!is_bool($flag)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + $this->processUncoveredFilesFromWhitelist = $flag; + } + + /** + * @param bool $flag + * @throws PHP_CodeCoverage_Exception + */ + public function setDisableIgnoredLines($flag) + { + if (!is_bool($flag)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'boolean' + ); + } + + $this->disableIgnoredLines = $flag; + } + + /** + * Applies the @covers annotation filtering. + * + * @param array $data + * @param mixed $linesToBeCovered + * @param array $linesToBeUsed + * @throws PHP_CodeCoverage_Exception_UnintentionallyCoveredCode + */ + private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed) + { + if ($linesToBeCovered === false || + ($this->forceCoversAnnotation && empty($linesToBeCovered))) { + $data = array(); + + return; + } + + if (empty($linesToBeCovered)) { + return; + } + + if ($this->checkForUnintentionallyCoveredCode) { + $this->performUnintentionallyCoveredCodeCheck( + $data, + $linesToBeCovered, + $linesToBeUsed + ); + } + + $data = array_intersect_key($data, $linesToBeCovered); + + foreach (array_keys($data) as $filename) { + $_linesToBeCovered = array_flip($linesToBeCovered[$filename]); + + $data[$filename] = array_intersect_key( + $data[$filename], + $_linesToBeCovered + ); + } + } + + /** + * Applies the blacklist/whitelist filtering. + * + * @param array $data + */ + private function applyListsFilter(array &$data) + { + foreach (array_keys($data) as $filename) { + if ($this->filter->isFiltered($filename)) { + unset($data[$filename]); + } + } + } + + /** + * Applies the "ignored lines" filtering. + * + * @param array $data + */ + private function applyIgnoredLinesFilter(array &$data) + { + foreach (array_keys($data) as $filename) { + if (!$this->filter->isFile($filename)) { + continue; + } + + foreach ($this->getLinesToBeIgnored($filename) as $line) { + unset($data[$filename][$line]); + } + } + } + + /** + * @param array $data + * @since Method available since Release 1.1.0 + */ + private function initializeFilesThatAreSeenTheFirstTime(array $data) + { + foreach ($data as $file => $lines) { + if ($this->filter->isFile($file) && !isset($this->data[$file])) { + $this->data[$file] = array(); + + foreach ($lines as $k => $v) { + $this->data[$file][$k] = $v == -2 ? null : array(); + } + } + } + } + + /** + * Processes whitelisted files that are not covered. + */ + private function addUncoveredFilesFromWhitelist() + { + $data = array(); + $uncoveredFiles = array_diff( + $this->filter->getWhitelist(), + array_keys($this->data) + ); + + foreach ($uncoveredFiles as $uncoveredFile) { + if (!file_exists($uncoveredFile)) { + continue; + } + + if ($this->processUncoveredFilesFromWhitelist) { + $this->processUncoveredFileFromWhitelist( + $uncoveredFile, + $data, + $uncoveredFiles + ); + } else { + $data[$uncoveredFile] = array(); + + $lines = count(file($uncoveredFile)); + + for ($i = 1; $i <= $lines; $i++) { + $data[$uncoveredFile][$i] = PHP_CodeCoverage_Driver::LINE_NOT_EXECUTED; + } + } + } + + $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST'); + } + + /** + * @param string $uncoveredFile + * @param array $data + * @param array $uncoveredFiles + */ + private function processUncoveredFileFromWhitelist($uncoveredFile, array &$data, array $uncoveredFiles) + { + $this->driver->start(); + include_once $uncoveredFile; + $coverage = $this->driver->stop(); + + foreach ($coverage as $file => $fileCoverage) { + if (!isset($data[$file]) && + in_array($file, $uncoveredFiles)) { + foreach (array_keys($fileCoverage) as $key) { + if ($fileCoverage[$key] == PHP_CodeCoverage_Driver::LINE_EXECUTED) { + $fileCoverage[$key] = PHP_CodeCoverage_Driver::LINE_NOT_EXECUTED; + } + } + + $data[$file] = $fileCoverage; + } + } + } + + /** + * Returns the lines of a source file that should be ignored. + * + * @param string $filename + * @return array + * @throws PHP_CodeCoverage_Exception + * @since Method available since Release 2.0.0 + */ + private function getLinesToBeIgnored($filename) + { + if (!is_string($filename)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'string' + ); + } + + if (!isset($this->ignoredLines[$filename])) { + $this->ignoredLines[$filename] = array(); + + if ($this->disableIgnoredLines) { + return $this->ignoredLines[$filename]; + } + + $ignore = false; + $stop = false; + $lines = file($filename); + $numLines = count($lines); + + foreach ($lines as $index => $line) { + if (!trim($line)) { + $this->ignoredLines[$filename][] = $index + 1; + } + } + + if ($this->cacheTokens) { + $tokens = PHP_Token_Stream_CachingFactory::get($filename); + } else { + $tokens = new PHP_Token_Stream($filename); + } + + $classes = array_merge($tokens->getClasses(), $tokens->getTraits()); + $tokens = $tokens->tokens(); + + foreach ($tokens as $token) { + switch (get_class($token)) { + case 'PHP_Token_COMMENT': + case 'PHP_Token_DOC_COMMENT': + $_token = trim($token); + $_line = trim($lines[$token->getLine() - 1]); + + if ($_token == '// @codeCoverageIgnore' || + $_token == '//@codeCoverageIgnore') { + $ignore = true; + $stop = true; + } elseif ($_token == '// @codeCoverageIgnoreStart' || + $_token == '//@codeCoverageIgnoreStart') { + $ignore = true; + } elseif ($_token == '// @codeCoverageIgnoreEnd' || + $_token == '//@codeCoverageIgnoreEnd') { + $stop = true; + } + + if (!$ignore) { + $start = $token->getLine(); + $end = $start + substr_count($token, "\n"); + + // Do not ignore the first line when there is a token + // before the comment + if (0 !== strpos($_token, $_line)) { + $start++; + } + + for ($i = $start; $i < $end; $i++) { + $this->ignoredLines[$filename][] = $i; + } + + // A DOC_COMMENT token or a COMMENT token starting with "/*" + // does not contain the final \n character in its text + if (isset($lines[$i-1]) && 0 === strpos($_token, '/*') && '*/' === substr(trim($lines[$i-1]), -2)) { + $this->ignoredLines[$filename][] = $i; + } + } + break; + + case 'PHP_Token_INTERFACE': + case 'PHP_Token_TRAIT': + case 'PHP_Token_CLASS': + case 'PHP_Token_FUNCTION': + $docblock = $token->getDocblock(); + + $this->ignoredLines[$filename][] = $token->getLine(); + + if (strpos($docblock, '@codeCoverageIgnore') || strpos($docblock, '@deprecated')) { + $endLine = $token->getEndLine(); + + for ($i = $token->getLine(); $i <= $endLine; $i++) { + $this->ignoredLines[$filename][] = $i; + } + } elseif ($token instanceof PHP_Token_INTERFACE || + $token instanceof PHP_Token_TRAIT || + $token instanceof PHP_Token_CLASS) { + if (empty($classes[$token->getName()]['methods'])) { + for ($i = $token->getLine(); + $i <= $token->getEndLine(); + $i++) { + $this->ignoredLines[$filename][] = $i; + } + } else { + $firstMethod = array_shift( + $classes[$token->getName()]['methods'] + ); + + do { + $lastMethod = array_pop( + $classes[$token->getName()]['methods'] + ); + } while ($lastMethod !== null && + substr($lastMethod['signature'], 0, 18) == 'anonymous function'); + + if ($lastMethod === null) { + $lastMethod = $firstMethod; + } + + for ($i = $token->getLine(); + $i < $firstMethod['startLine']; + $i++) { + $this->ignoredLines[$filename][] = $i; + } + + for ($i = $token->getEndLine(); + $i > $lastMethod['endLine']; + $i--) { + $this->ignoredLines[$filename][] = $i; + } + } + } + break; + + case 'PHP_Token_NAMESPACE': + $this->ignoredLines[$filename][] = $token->getEndLine(); + + // Intentional fallthrough + case 'PHP_Token_OPEN_TAG': + case 'PHP_Token_CLOSE_TAG': + case 'PHP_Token_USE': + $this->ignoredLines[$filename][] = $token->getLine(); + break; + } + + if ($ignore) { + $this->ignoredLines[$filename][] = $token->getLine(); + + if ($stop) { + $ignore = false; + $stop = false; + } + } + } + + $this->ignoredLines[$filename][] = $numLines + 1; + + $this->ignoredLines[$filename] = array_unique( + $this->ignoredLines[$filename] + ); + + sort($this->ignoredLines[$filename]); + } + + return $this->ignoredLines[$filename]; + } + + /** + * @param array $data + * @param array $linesToBeCovered + * @param array $linesToBeUsed + * @throws PHP_CodeCoverage_Exception_UnintentionallyCoveredCode + * @since Method available since Release 2.0.0 + */ + private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed) + { + $allowedLines = $this->getAllowedLines( + $linesToBeCovered, + $linesToBeUsed + ); + + $message = ''; + + foreach ($data as $file => $_data) { + foreach ($_data as $line => $flag) { + if ($flag == 1 && + (!isset($allowedLines[$file]) || + !isset($allowedLines[$file][$line]))) { + $message .= sprintf( + '- %s:%d' . PHP_EOL, + $file, + $line + ); + } + } + } + + if (!empty($message)) { + throw new PHP_CodeCoverage_Exception_UnintentionallyCoveredCode( + $message + ); + } + } + + /** + * @param array $linesToBeCovered + * @param array $linesToBeUsed + * @return array + * @since Method available since Release 2.0.0 + */ + private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed) + { + $allowedLines = array(); + + foreach (array_keys($linesToBeCovered) as $file) { + if (!isset($allowedLines[$file])) { + $allowedLines[$file] = array(); + } + + $allowedLines[$file] = array_merge( + $allowedLines[$file], + $linesToBeCovered[$file] + ); + } + + foreach (array_keys($linesToBeUsed) as $file) { + if (!isset($allowedLines[$file])) { + $allowedLines[$file] = array(); + } + + $allowedLines[$file] = array_merge( + $allowedLines[$file], + $linesToBeUsed[$file] + ); + } + + foreach (array_keys($allowedLines) as $file) { + $allowedLines[$file] = array_flip( + array_unique($allowedLines[$file]) + ); + } + + return $allowedLines; + } + + /** + * @return PHP_CodeCoverage_Driver + * @throws PHP_CodeCoverage_Exception + */ + private function selectDriver() + { + $runtime = new Runtime; + + if (!$runtime->canCollectCodeCoverage()) { + throw new PHP_CodeCoverage_Exception('No code coverage driver available'); + } + + if ($runtime->isHHVM()) { + return new PHP_CodeCoverage_Driver_HHVM; + } elseif ($runtime->isPHPDBG()) { + return new PHP_CodeCoverage_Driver_PHPDBG; + } else { + return new PHP_CodeCoverage_Driver_Xdebug; + } + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver.php new file mode 100644 index 0000000..8635ace --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Interface for code coverage drivers. + * + * @since Class available since Release 1.0.0 + */ +interface PHP_CodeCoverage_Driver +{ + /** + * @var int + * @see http://xdebug.org/docs/code_coverage + */ + const LINE_EXECUTED = 1; + + /** + * @var int + * @see http://xdebug.org/docs/code_coverage + */ + const LINE_NOT_EXECUTED = -1; + + /** + * @var int + * @see http://xdebug.org/docs/code_coverage + */ + const LINE_NOT_EXECUTABLE = -2; + + /** + * Start collection of code coverage information. + */ + public function start(); + + /** + * Stop collection of code coverage information. + * + * @return array + */ + public function stop(); +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php new file mode 100644 index 0000000..a9d8f0c --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Driver for HHVM's code coverage functionality. + * + * @since Class available since Release 2.2.2 + * @codeCoverageIgnore + */ +class PHP_CodeCoverage_Driver_HHVM extends PHP_CodeCoverage_Driver_Xdebug +{ + /** + * Start collection of code coverage information. + */ + public function start() + { + xdebug_start_code_coverage(); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/PHPDBG.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/PHPDBG.php new file mode 100644 index 0000000..f3eb621 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/PHPDBG.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Driver for PHPDBG's code coverage functionality. + * + * @since Class available since Release 2.2.0 + * @codeCoverageIgnore + */ +class PHP_CodeCoverage_Driver_PHPDBG implements PHP_CodeCoverage_Driver +{ + /** + * Constructor. + */ + public function __construct() + { + if (PHP_SAPI !== 'phpdbg') { + throw new PHP_CodeCoverage_Exception( + 'This driver requires the PHPDBG SAPI' + ); + } + + if (!function_exists('phpdbg_start_oplog')) { + throw new PHP_CodeCoverage_Exception( + 'This build of PHPDBG does not support code coverage' + ); + } + } + + /** + * Start collection of code coverage information. + */ + public function start() + { + phpdbg_start_oplog(); + } + + /** + * Stop collection of code coverage information. + * + * @return array + */ + public function stop() + { + static $fetchedLines = array(); + + $dbgData = phpdbg_end_oplog(); + + if ($fetchedLines == array()) { + $sourceLines = phpdbg_get_executable(); + } else { + $newFiles = array_diff( + get_included_files(), + array_keys($fetchedLines) + ); + + if ($newFiles) { + $sourceLines = phpdbg_get_executable( + array('files' => $newFiles) + ); + } else { + $sourceLines = array(); + } + } + + foreach ($sourceLines as $file => $lines) { + foreach ($lines as $lineNo => $numExecuted) { + $sourceLines[$file][$lineNo] = self::LINE_NOT_EXECUTED; + } + } + + $fetchedLines = array_merge($fetchedLines, $sourceLines); + + return $this->detectExecutedLines($fetchedLines, $dbgData); + } + + /** + * Convert phpdbg based data into the format CodeCoverage expects + * + * @param array $sourceLines + * @param array $dbgData + * @return array + */ + private function detectExecutedLines(array $sourceLines, array $dbgData) + { + foreach ($dbgData as $file => $coveredLines) { + foreach ($coveredLines as $lineNo => $numExecuted) { + // phpdbg also reports $lineNo=0 when e.g. exceptions get thrown. + // make sure we only mark lines executed which are actually executable. + if (isset($sourceLines[$file][$lineNo])) { + $sourceLines[$file][$lineNo] = self::LINE_EXECUTED; + } + } + } + + return $sourceLines; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php new file mode 100644 index 0000000..0cd7b9a --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Driver for Xdebug's code coverage functionality. + * + * @since Class available since Release 1.0.0 + * @codeCoverageIgnore + */ +class PHP_CodeCoverage_Driver_Xdebug implements PHP_CodeCoverage_Driver +{ + /** + * Constructor. + */ + public function __construct() + { + if (!extension_loaded('xdebug')) { + throw new PHP_CodeCoverage_Exception('This driver requires Xdebug'); + } + + if (version_compare(phpversion('xdebug'), '2.2.0-dev', '>=') && + !ini_get('xdebug.coverage_enable')) { + throw new PHP_CodeCoverage_Exception( + 'xdebug.coverage_enable=On has to be set in php.ini' + ); + } + } + + /** + * Start collection of code coverage information. + */ + public function start() + { + xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); + } + + /** + * Stop collection of code coverage information. + * + * @return array + */ + public function stop() + { + $data = xdebug_get_code_coverage(); + xdebug_stop_code_coverage(); + + return $this->cleanup($data); + } + + /** + * @param array $data + * @return array + * @since Method available since Release 2.0.0 + */ + private function cleanup(array $data) + { + foreach (array_keys($data) as $file) { + unset($data[$file][0]); + + if ($file != 'xdebug://debug-eval' && file_exists($file)) { + $numLines = $this->getNumberOfLinesInFile($file); + + foreach (array_keys($data[$file]) as $line) { + if (isset($data[$file][$line]) && $line > $numLines) { + unset($data[$file][$line]); + } + } + } + } + + return $data; + } + + /** + * @param string $file + * @return int + * @since Method available since Release 2.0.0 + */ + private function getNumberOfLinesInFile($file) + { + $buffer = file_get_contents($file); + $lines = substr_count($buffer, "\n"); + + if (substr($buffer, -1) !== "\n") { + $lines++; + } + + return $lines; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Exception.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Exception.php new file mode 100644 index 0000000..bded3c0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Exception.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Exception class for PHP_CodeCoverage component. + * + * @since Class available since Release 1.1.0 + */ +class PHP_CodeCoverage_Exception extends RuntimeException +{ +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCode.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCode.php new file mode 100644 index 0000000..463785e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCode.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Exception that is raised when code is unintentionally covered. + * + * @since Class available since Release 2.0.0 + */ +class PHP_CodeCoverage_Exception_UnintentionallyCoveredCode extends PHP_CodeCoverage_Exception +{ +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Filter.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Filter.php new file mode 100644 index 0000000..bb4a251 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Filter.php @@ -0,0 +1,293 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Filter for blacklisting and whitelisting of code coverage information. + * + * @since Class available since Release 1.0.0 + */ +class PHP_CodeCoverage_Filter +{ + /** + * Source files that are blacklisted. + * + * @var array + */ + private $blacklistedFiles = array(); + + /** + * Source files that are whitelisted. + * + * @var array + */ + private $whitelistedFiles = array(); + + /** + * Adds a directory to the blacklist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $prefix + */ + public function addDirectoryToBlacklist($directory, $suffix = '.php', $prefix = '') + { + $facade = new File_Iterator_Facade; + $files = $facade->getFilesAsArray($directory, $suffix, $prefix); + + foreach ($files as $file) { + $this->addFileToBlacklist($file); + } + } + + /** + * Adds a file to the blacklist. + * + * @param string $filename + */ + public function addFileToBlacklist($filename) + { + $this->blacklistedFiles[realpath($filename)] = true; + } + + /** + * Adds files to the blacklist. + * + * @param array $files + */ + public function addFilesToBlacklist(array $files) + { + foreach ($files as $file) { + $this->addFileToBlacklist($file); + } + } + + /** + * Removes a directory from the blacklist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $prefix + */ + public function removeDirectoryFromBlacklist($directory, $suffix = '.php', $prefix = '') + { + $facade = new File_Iterator_Facade; + $files = $facade->getFilesAsArray($directory, $suffix, $prefix); + + foreach ($files as $file) { + $this->removeFileFromBlacklist($file); + } + } + + /** + * Removes a file from the blacklist. + * + * @param string $filename + */ + public function removeFileFromBlacklist($filename) + { + $filename = realpath($filename); + + if (isset($this->blacklistedFiles[$filename])) { + unset($this->blacklistedFiles[$filename]); + } + } + + /** + * Adds a directory to the whitelist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $prefix + */ + public function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '') + { + $facade = new File_Iterator_Facade; + $files = $facade->getFilesAsArray($directory, $suffix, $prefix); + + foreach ($files as $file) { + $this->addFileToWhitelist($file); + } + } + + /** + * Adds a file to the whitelist. + * + * @param string $filename + */ + public function addFileToWhitelist($filename) + { + $this->whitelistedFiles[realpath($filename)] = true; + } + + /** + * Adds files to the whitelist. + * + * @param array $files + */ + public function addFilesToWhitelist(array $files) + { + foreach ($files as $file) { + $this->addFileToWhitelist($file); + } + } + + /** + * Removes a directory from the whitelist (recursively). + * + * @param string $directory + * @param string $suffix + * @param string $prefix + */ + public function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '') + { + $facade = new File_Iterator_Facade; + $files = $facade->getFilesAsArray($directory, $suffix, $prefix); + + foreach ($files as $file) { + $this->removeFileFromWhitelist($file); + } + } + + /** + * Removes a file from the whitelist. + * + * @param string $filename + */ + public function removeFileFromWhitelist($filename) + { + $filename = realpath($filename); + + if (isset($this->whitelistedFiles[$filename])) { + unset($this->whitelistedFiles[$filename]); + } + } + + /** + * Checks whether a filename is a real filename. + * + * @param string $filename + * @return bool + */ + public function isFile($filename) + { + if ($filename == '-' || + strpos($filename, 'vfs://') === 0 || + strpos($filename, 'xdebug://debug-eval') !== false || + strpos($filename, 'eval()\'d code') !== false || + strpos($filename, 'runtime-created function') !== false || + strpos($filename, 'runkit created function') !== false || + strpos($filename, 'assert code') !== false || + strpos($filename, 'regexp code') !== false) { + return false; + } + + return file_exists($filename); + } + + /** + * Checks whether or not a file is filtered. + * + * When the whitelist is empty (default), blacklisting is used. + * When the whitelist is not empty, whitelisting is used. + * + * @param string $filename + * @return bool + * @throws PHP_CodeCoverage_Exception + */ + public function isFiltered($filename) + { + if (!$this->isFile($filename)) { + return true; + } + + $filename = realpath($filename); + + if (!empty($this->whitelistedFiles)) { + return !isset($this->whitelistedFiles[$filename]); + } + + return isset($this->blacklistedFiles[$filename]); + } + + /** + * Returns the list of blacklisted files. + * + * @return array + */ + public function getBlacklist() + { + return array_keys($this->blacklistedFiles); + } + + /** + * Returns the list of whitelisted files. + * + * @return array + */ + public function getWhitelist() + { + return array_keys($this->whitelistedFiles); + } + + /** + * Returns whether this filter has a whitelist. + * + * @return bool + * @since Method available since Release 1.1.0 + */ + public function hasWhitelist() + { + return !empty($this->whitelistedFiles); + } + + /** + * Returns the blacklisted files. + * + * @return array + * @since Method available since Release 2.0.0 + */ + public function getBlacklistedFiles() + { + return $this->blacklistedFiles; + } + + /** + * Sets the blacklisted files. + * + * @param array $blacklistedFiles + * @since Method available since Release 2.0.0 + */ + public function setBlacklistedFiles($blacklistedFiles) + { + $this->blacklistedFiles = $blacklistedFiles; + } + + /** + * Returns the whitelisted files. + * + * @return array + * @since Method available since Release 2.0.0 + */ + public function getWhitelistedFiles() + { + return $this->whitelistedFiles; + } + + /** + * Sets the whitelisted files. + * + * @param array $whitelistedFiles + * @since Method available since Release 2.0.0 + */ + public function setWhitelistedFiles($whitelistedFiles) + { + $this->whitelistedFiles = $whitelistedFiles; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php new file mode 100644 index 0000000..c0ea8d8 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php @@ -0,0 +1,284 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Generates a Clover XML logfile from an PHP_CodeCoverage object. + * + * @since Class available since Release 1.0.0 + */ +class PHP_CodeCoverage_Report_Clover +{ + /** + * @param PHP_CodeCoverage $coverage + * @param string $target + * @param string $name + * @return string + */ + public function process(PHP_CodeCoverage $coverage, $target = null, $name = null) + { + $xmlDocument = new DOMDocument('1.0', 'UTF-8'); + $xmlDocument->formatOutput = true; + + $xmlCoverage = $xmlDocument->createElement('coverage'); + $xmlCoverage->setAttribute('generated', (int) $_SERVER['REQUEST_TIME']); + $xmlDocument->appendChild($xmlCoverage); + + $xmlProject = $xmlDocument->createElement('project'); + $xmlProject->setAttribute('timestamp', (int) $_SERVER['REQUEST_TIME']); + + if (is_string($name)) { + $xmlProject->setAttribute('name', $name); + } + + $xmlCoverage->appendChild($xmlProject); + + $packages = array(); + $report = $coverage->getReport(); + unset($coverage); + + foreach ($report as $item) { + $namespace = 'global'; + + if (!$item instanceof PHP_CodeCoverage_Report_Node_File) { + continue; + } + + $xmlFile = $xmlDocument->createElement('file'); + $xmlFile->setAttribute('name', $item->getPath()); + + $classes = $item->getClassesAndTraits(); + $coverage = $item->getCoverageData(); + $lines = array(); + + foreach ($classes as $className => $class) { + $classStatements = 0; + $coveredClassStatements = 0; + $coveredMethods = 0; + $classMethods = 0; + + foreach ($class['methods'] as $methodName => $method) { + if ($method['executableLines'] == 0) { + continue; + } + + $classMethods++; + $classStatements += $method['executableLines']; + $coveredClassStatements += $method['executedLines']; + if ($method['coverage'] == 100) { + $coveredMethods++; + } + + $methodCount = 0; + for ($i = $method['startLine']; + $i <= $method['endLine']; + $i++) { + if (isset($coverage[$i]) && ($coverage[$i] !== null)) { + $methodCount = max($methodCount, count($coverage[$i])); + } + } + + $lines[$method['startLine']] = array( + 'count' => $methodCount, + 'crap' => $method['crap'], + 'type' => 'method', + 'name' => $methodName + ); + } + + if (!empty($class['package']['namespace'])) { + $namespace = $class['package']['namespace']; + } + + $xmlClass = $xmlDocument->createElement('class'); + $xmlClass->setAttribute('name', $className); + $xmlClass->setAttribute('namespace', $namespace); + + if (!empty($class['package']['fullPackage'])) { + $xmlClass->setAttribute( + 'fullPackage', + $class['package']['fullPackage'] + ); + } + + if (!empty($class['package']['category'])) { + $xmlClass->setAttribute( + 'category', + $class['package']['category'] + ); + } + + if (!empty($class['package']['package'])) { + $xmlClass->setAttribute( + 'package', + $class['package']['package'] + ); + } + + if (!empty($class['package']['subpackage'])) { + $xmlClass->setAttribute( + 'subpackage', + $class['package']['subpackage'] + ); + } + + $xmlFile->appendChild($xmlClass); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('methods', $classMethods); + $xmlMetrics->setAttribute('coveredmethods', $coveredMethods); + $xmlMetrics->setAttribute('conditionals', 0); + $xmlMetrics->setAttribute('coveredconditionals', 0); + $xmlMetrics->setAttribute('statements', $classStatements); + $xmlMetrics->setAttribute( + 'coveredstatements', + $coveredClassStatements + ); + $xmlMetrics->setAttribute( + 'elements', + $classMethods + + $classStatements + /* + conditionals */ + ); + $xmlMetrics->setAttribute( + 'coveredelements', + $coveredMethods + + $coveredClassStatements + /* + coveredconditionals */ + ); + $xmlClass->appendChild($xmlMetrics); + } + + foreach ($coverage as $line => $data) { + if ($data === null || isset($lines[$line])) { + continue; + } + + $lines[$line] = array( + 'count' => count($data), 'type' => 'stmt' + ); + } + + ksort($lines); + + foreach ($lines as $line => $data) { + $xmlLine = $xmlDocument->createElement('line'); + $xmlLine->setAttribute('num', $line); + $xmlLine->setAttribute('type', $data['type']); + + if (isset($data['name'])) { + $xmlLine->setAttribute('name', $data['name']); + } + + if (isset($data['crap'])) { + $xmlLine->setAttribute('crap', $data['crap']); + } + + $xmlLine->setAttribute('count', $data['count']); + $xmlFile->appendChild($xmlLine); + } + + $linesOfCode = $item->getLinesOfCode(); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('loc', $linesOfCode['loc']); + $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']); + $xmlMetrics->setAttribute('classes', $item->getNumClassesAndTraits()); + $xmlMetrics->setAttribute('methods', $item->getNumMethods()); + $xmlMetrics->setAttribute( + 'coveredmethods', + $item->getNumTestedMethods() + ); + $xmlMetrics->setAttribute('conditionals', 0); + $xmlMetrics->setAttribute('coveredconditionals', 0); + $xmlMetrics->setAttribute( + 'statements', + $item->getNumExecutableLines() + ); + $xmlMetrics->setAttribute( + 'coveredstatements', + $item->getNumExecutedLines() + ); + $xmlMetrics->setAttribute( + 'elements', + $item->getNumMethods() + $item->getNumExecutableLines() + /* + conditionals */ + ); + $xmlMetrics->setAttribute( + 'coveredelements', + $item->getNumTestedMethods() + $item->getNumExecutedLines() + /* + coveredconditionals */ + ); + $xmlFile->appendChild($xmlMetrics); + + if ($namespace == 'global') { + $xmlProject->appendChild($xmlFile); + } else { + if (!isset($packages[$namespace])) { + $packages[$namespace] = $xmlDocument->createElement( + 'package' + ); + + $packages[$namespace]->setAttribute('name', $namespace); + $xmlProject->appendChild($packages[$namespace]); + } + + $packages[$namespace]->appendChild($xmlFile); + } + } + + $linesOfCode = $report->getLinesOfCode(); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('files', count($report)); + $xmlMetrics->setAttribute('loc', $linesOfCode['loc']); + $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']); + $xmlMetrics->setAttribute( + 'classes', + $report->getNumClassesAndTraits() + ); + $xmlMetrics->setAttribute('methods', $report->getNumMethods()); + $xmlMetrics->setAttribute( + 'coveredmethods', + $report->getNumTestedMethods() + ); + $xmlMetrics->setAttribute('conditionals', 0); + $xmlMetrics->setAttribute('coveredconditionals', 0); + $xmlMetrics->setAttribute( + 'statements', + $report->getNumExecutableLines() + ); + $xmlMetrics->setAttribute( + 'coveredstatements', + $report->getNumExecutedLines() + ); + $xmlMetrics->setAttribute( + 'elements', + $report->getNumMethods() + $report->getNumExecutableLines() + /* + conditionals */ + ); + $xmlMetrics->setAttribute( + 'coveredelements', + $report->getNumTestedMethods() + $report->getNumExecutedLines() + /* + coveredconditionals */ + ); + + $xmlProject->appendChild($xmlMetrics); + + if ($target !== null) { + if (!is_dir(dirname($target))) { + mkdir(dirname($target), 0777, true); + } + + return $xmlDocument->save($target); + } else { + return $xmlDocument->saveXML(); + } + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php new file mode 100644 index 0000000..c006ea6 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php @@ -0,0 +1,164 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 2.0.0 + */ +class PHP_CodeCoverage_Report_Crap4j +{ + /** + * @var int + */ + private $threshold; + + /** + * @param int $threshold + */ + public function __construct($threshold = 30) + { + if (!is_int($threshold)) { + throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory( + 1, + 'integer' + ); + } + + $this->threshold = $threshold; + } + + /** + * @param PHP_CodeCoverage $coverage + * @param string $target + * @param string $name + * @return string + */ + public function process(PHP_CodeCoverage $coverage, $target = null, $name = null) + { + $document = new DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = true; + + $root = $document->createElement('crap_result'); + $document->appendChild($root); + + $project = $document->createElement('project', is_string($name) ? $name : ''); + $root->appendChild($project); + $root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME']))); + + $stats = $document->createElement('stats'); + $methodsNode = $document->createElement('methods'); + + $report = $coverage->getReport(); + unset($coverage); + + $fullMethodCount = 0; + $fullCrapMethodCount = 0; + $fullCrapLoad = 0; + $fullCrap = 0; + + foreach ($report as $item) { + $namespace = 'global'; + + if (!$item instanceof PHP_CodeCoverage_Report_Node_File) { + continue; + } + + $file = $document->createElement('file'); + $file->setAttribute('name', $item->getPath()); + + $classes = $item->getClassesAndTraits(); + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + $crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']); + + $fullCrap += $method['crap']; + $fullCrapLoad += $crapLoad; + $fullMethodCount++; + + if ($method['crap'] >= $this->threshold) { + $fullCrapMethodCount++; + } + + $methodNode = $document->createElement('method'); + + if (!empty($class['package']['namespace'])) { + $namespace = $class['package']['namespace']; + } + + $methodNode->appendChild($document->createElement('package', $namespace)); + $methodNode->appendChild($document->createElement('className', $className)); + $methodNode->appendChild($document->createElement('methodName', $methodName)); + $methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature']))); + $methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature']))); + $methodNode->appendChild($document->createElement('crap', $this->roundValue($method['crap']))); + $methodNode->appendChild($document->createElement('complexity', $method['ccn'])); + $methodNode->appendChild($document->createElement('coverage', $this->roundValue($method['coverage']))); + $methodNode->appendChild($document->createElement('crapLoad', round($crapLoad))); + + $methodsNode->appendChild($methodNode); + } + } + } + + $stats->appendChild($document->createElement('name', 'Method Crap Stats')); + $stats->appendChild($document->createElement('methodCount', $fullMethodCount)); + $stats->appendChild($document->createElement('crapMethodCount', $fullCrapMethodCount)); + $stats->appendChild($document->createElement('crapLoad', round($fullCrapLoad))); + $stats->appendChild($document->createElement('totalCrap', $fullCrap)); + + if ($fullMethodCount > 0) { + $crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount); + } else { + $crapMethodPercent = 0; + } + + $stats->appendChild($document->createElement('crapMethodPercent', $crapMethodPercent)); + + $root->appendChild($stats); + $root->appendChild($methodsNode); + + if ($target !== null) { + if (!is_dir(dirname($target))) { + mkdir(dirname($target), 0777, true); + } + + return $document->save($target); + } else { + return $document->saveXML(); + } + } + + /** + * @param float $crapValue + * @param int $cyclomaticComplexity + * @param float $coveragePercent + * @return float + */ + private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent) + { + $crapLoad = 0; + + if ($crapValue >= $this->threshold) { + $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100); + $crapLoad += $cyclomaticComplexity / $this->threshold; + } + + return $crapLoad; + } + + /** + * @param float $value + * @return float + */ + private function roundValue($value) + { + return round($value, 2); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php new file mode 100644 index 0000000..b28964e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php @@ -0,0 +1,242 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Factory for PHP_CodeCoverage_Report_Node_* object graphs. + * + * @since Class available since Release 1.1.0 + */ +class PHP_CodeCoverage_Report_Factory +{ + /** + * @param PHP_CodeCoverage $coverage + * @return PHP_CodeCoverage_Report_Node_Directory + */ + public function create(PHP_CodeCoverage $coverage) + { + $files = $coverage->getData(); + $commonPath = $this->reducePaths($files); + $root = new PHP_CodeCoverage_Report_Node_Directory( + $commonPath, + null + ); + + $this->addItems( + $root, + $this->buildDirectoryStructure($files), + $coverage->getTests(), + $coverage->getCacheTokens() + ); + + return $root; + } + + /** + * @param PHP_CodeCoverage_Report_Node_Directory $root + * @param array $items + * @param array $tests + * @param bool $cacheTokens + */ + private function addItems(PHP_CodeCoverage_Report_Node_Directory $root, array $items, array $tests, $cacheTokens) + { + foreach ($items as $key => $value) { + if (substr($key, -2) == '/f') { + $key = substr($key, 0, -2); + + if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) { + $root->addFile($key, $value, $tests, $cacheTokens); + } + } else { + $child = $root->addDirectory($key); + $this->addItems($child, $value, $tests, $cacheTokens); + } + } + } + + /** + * Builds an array representation of the directory structure. + * + * For instance, + * + * + * Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * is transformed into + * + * + * Array + * ( + * [.] => Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * ) + * + * + * @param array $files + * @return array + */ + private function buildDirectoryStructure($files) + { + $result = array(); + + foreach ($files as $path => $file) { + $path = explode('/', $path); + $pointer = &$result; + $max = count($path); + + for ($i = 0; $i < $max; $i++) { + if ($i == ($max - 1)) { + $type = '/f'; + } else { + $type = ''; + } + + $pointer = &$pointer[$path[$i] . $type]; + } + + $pointer = $file; + } + + return $result; + } + + /** + * Reduces the paths by cutting the longest common start path. + * + * For instance, + * + * + * Array + * ( + * [/home/sb/Money/Money.php] => Array + * ( + * ... + * ) + * + * [/home/sb/Money/MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * is reduced to + * + * + * Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * @param array $files + * @return string + */ + private function reducePaths(&$files) + { + if (empty($files)) { + return '.'; + } + + $commonPath = ''; + $paths = array_keys($files); + + if (count($files) == 1) { + $commonPath = dirname($paths[0]) . '/'; + $files[basename($paths[0])] = $files[$paths[0]]; + + unset($files[$paths[0]]); + + return $commonPath; + } + + $max = count($paths); + + for ($i = 0; $i < $max; $i++) { + // strip phar:// prefixes + if (strpos($paths[$i], 'phar://') === 0) { + $paths[$i] = substr($paths[$i], 7); + $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR); + } + $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]); + + if (empty($paths[$i][0])) { + $paths[$i][0] = DIRECTORY_SEPARATOR; + } + } + + $done = false; + $max = count($paths); + + while (!$done) { + for ($i = 0; $i < $max - 1; $i++) { + if (!isset($paths[$i][0]) || + !isset($paths[$i+1][0]) || + $paths[$i][0] != $paths[$i+1][0]) { + $done = true; + break; + } + } + + if (!$done) { + $commonPath .= $paths[0][0]; + + if ($paths[0][0] != DIRECTORY_SEPARATOR) { + $commonPath .= DIRECTORY_SEPARATOR; + } + + for ($i = 0; $i < $max; $i++) { + array_shift($paths[$i]); + } + } + } + + $original = array_keys($files); + $max = count($original); + + for ($i = 0; $i < $max; $i++) { + $files[implode('/', $paths[$i])] = $files[$original[$i]]; + unset($files[$original[$i]]); + } + + ksort($files); + + return substr($commonPath, 0, -1); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php new file mode 100644 index 0000000..80916ef --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php @@ -0,0 +1,182 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Generates an HTML report from an PHP_CodeCoverage object. + * + * @since Class available since Release 1.0.0 + */ +class PHP_CodeCoverage_Report_HTML +{ + /** + * @var string + */ + private $templatePath; + + /** + * @var string + */ + private $generator; + + /** + * @var int + */ + private $lowUpperBound; + + /** + * @var int + */ + private $highLowerBound; + + /** + * Constructor. + * + * @param int $lowUpperBound + * @param int $highLowerBound + * @param string $generator + */ + public function __construct($lowUpperBound = 50, $highLowerBound = 90, $generator = '') + { + $this->generator = $generator; + $this->highLowerBound = $highLowerBound; + $this->lowUpperBound = $lowUpperBound; + + $this->templatePath = sprintf( + '%s%sHTML%sRenderer%sTemplate%s', + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ); + } + + /** + * @param PHP_CodeCoverage $coverage + * @param string $target + */ + public function process(PHP_CodeCoverage $coverage, $target) + { + $target = $this->getDirectory($target); + $report = $coverage->getReport(); + unset($coverage); + + if (!isset($_SERVER['REQUEST_TIME'])) { + $_SERVER['REQUEST_TIME'] = time(); + } + + $date = date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']); + + $dashboard = new PHP_CodeCoverage_Report_HTML_Renderer_Dashboard( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $directory = new PHP_CodeCoverage_Report_HTML_Renderer_Directory( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $file = new PHP_CodeCoverage_Report_HTML_Renderer_File( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $directory->render($report, $target . 'index.html'); + $dashboard->render($report, $target . 'dashboard.html'); + + foreach ($report as $node) { + $id = $node->getId(); + + if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) { + if (!file_exists($target . $id)) { + mkdir($target . $id, 0777, true); + } + + $directory->render($node, $target . $id . '/index.html'); + $dashboard->render($node, $target . $id . '/dashboard.html'); + } else { + $dir = dirname($target . $id); + + if (!file_exists($dir)) { + mkdir($dir, 0777, true); + } + + $file->render($node, $target . $id . '.html'); + } + } + + $this->copyFiles($target); + } + + /** + * @param string $target + */ + private function copyFiles($target) + { + $dir = $this->getDirectory($target . 'css'); + copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css'); + copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css'); + copy($this->templatePath . 'css/style.css', $dir . 'style.css'); + + $dir = $this->getDirectory($target . 'fonts'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.svg', $dir . 'glyphicons-halflings-regular.svg'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.ttf', $dir . 'glyphicons-halflings-regular.ttf'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff', $dir . 'glyphicons-halflings-regular.woff'); + copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff2', $dir . 'glyphicons-halflings-regular.woff2'); + + $dir = $this->getDirectory($target . 'js'); + copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js'); + copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js'); + copy($this->templatePath . 'js/holder.min.js', $dir . 'holder.min.js'); + copy($this->templatePath . 'js/html5shiv.min.js', $dir . 'html5shiv.min.js'); + copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js'); + copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js'); + copy($this->templatePath . 'js/respond.min.js', $dir . 'respond.min.js'); + } + + /** + * @param string $directory + * @return string + * @throws PHP_CodeCoverage_Exception + * @since Method available since Release 1.2.0 + */ + private function getDirectory($directory) + { + if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) { + $directory .= DIRECTORY_SEPARATOR; + } + + if (is_dir($directory)) { + return $directory; + } + + if (@mkdir($directory, 0777, true)) { + return $directory; + } + + throw new PHP_CodeCoverage_Exception( + sprintf( + 'Directory "%s" does not exist.', + $directory + ) + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php new file mode 100644 index 0000000..51aa15e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php @@ -0,0 +1,271 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\Environment\Runtime; + +/** + * Base class for PHP_CodeCoverage_Report_Node renderers. + * + * @since Class available since Release 1.1.0 + */ +abstract class PHP_CodeCoverage_Report_HTML_Renderer +{ + /** + * @var string + */ + protected $templatePath; + + /** + * @var string + */ + protected $generator; + + /** + * @var string + */ + protected $date; + + /** + * @var int + */ + protected $lowUpperBound; + + /** + * @var int + */ + protected $highLowerBound; + + /** + * @var string + */ + protected $version; + + /** + * Constructor. + * + * @param string $templatePath + * @param string $generator + * @param string $date + * @param int $lowUpperBound + * @param int $highLowerBound + */ + public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound) + { + $version = new SebastianBergmann\Version('2.2.4', dirname(dirname(dirname(dirname(__DIR__))))); + + $this->templatePath = $templatePath; + $this->generator = $generator; + $this->date = $date; + $this->lowUpperBound = $lowUpperBound; + $this->highLowerBound = $highLowerBound; + $this->version = $version->getVersion(); + } + + /** + * @param Text_Template $template + * @param array $data + * @return string + */ + protected function renderItemTemplate(Text_Template $template, array $data) + { + $numSeparator = ' / '; + + if (isset($data['numClasses']) && $data['numClasses'] > 0) { + $classesLevel = $this->getColorLevel($data['testedClassesPercent']); + + $classesNumber = $data['numTestedClasses'] . $numSeparator . + $data['numClasses']; + + $classesBar = $this->getCoverageBar( + $data['testedClassesPercent'] + ); + } else { + $classesLevel = 'success'; + $classesNumber = '0' . $numSeparator . '0'; + $classesBar = $this->getCoverageBar(100); + } + + if ($data['numMethods'] > 0) { + $methodsLevel = $this->getColorLevel($data['testedMethodsPercent']); + + $methodsNumber = $data['numTestedMethods'] . $numSeparator . + $data['numMethods']; + + $methodsBar = $this->getCoverageBar( + $data['testedMethodsPercent'] + ); + } else { + $methodsLevel = 'success'; + $methodsNumber = '0' . $numSeparator . '0'; + $methodsBar = $this->getCoverageBar(100); + $data['testedMethodsPercentAsString'] = '100.00%'; + } + + if ($data['numExecutableLines'] > 0) { + $linesLevel = $this->getColorLevel($data['linesExecutedPercent']); + + $linesNumber = $data['numExecutedLines'] . $numSeparator . + $data['numExecutableLines']; + + $linesBar = $this->getCoverageBar( + $data['linesExecutedPercent'] + ); + } else { + $linesLevel = 'success'; + $linesNumber = '0' . $numSeparator . '0'; + $linesBar = $this->getCoverageBar(100); + $data['linesExecutedPercentAsString'] = '100.00%'; + } + + $template->setVar( + array( + 'icon' => isset($data['icon']) ? $data['icon'] : '', + 'crap' => isset($data['crap']) ? $data['crap'] : '', + 'name' => $data['name'], + 'lines_bar' => $linesBar, + 'lines_executed_percent' => $data['linesExecutedPercentAsString'], + 'lines_level' => $linesLevel, + 'lines_number' => $linesNumber, + 'methods_bar' => $methodsBar, + 'methods_tested_percent' => $data['testedMethodsPercentAsString'], + 'methods_level' => $methodsLevel, + 'methods_number' => $methodsNumber, + 'classes_bar' => $classesBar, + 'classes_tested_percent' => isset($data['testedClassesPercentAsString']) ? $data['testedClassesPercentAsString'] : '', + 'classes_level' => $classesLevel, + 'classes_number' => $classesNumber + ) + ); + + return $template->render(); + } + + /** + * @param Text_Template $template + * @param PHP_CodeCoverage_Report_Node $node + */ + protected function setCommonTemplateVariables(Text_Template $template, PHP_CodeCoverage_Report_Node $node) + { + $runtime = new Runtime; + + $template->setVar( + array( + 'id' => $node->getId(), + 'full_path' => $node->getPath(), + 'path_to_root' => $this->getPathToRoot($node), + 'breadcrumbs' => $this->getBreadcrumbs($node), + 'date' => $this->date, + 'version' => $this->version, + 'runtime_name' => $runtime->getName(), + 'runtime_version' => $runtime->getVersion(), + 'runtime_link' => $runtime->getVendorUrl(), + 'generator' => $this->generator, + 'low_upper_bound' => $this->lowUpperBound, + 'high_lower_bound' => $this->highLowerBound + ) + ); + } + + protected function getBreadcrumbs(PHP_CodeCoverage_Report_Node $node) + { + $breadcrumbs = ''; + $path = $node->getPathAsArray(); + $pathToRoot = array(); + $max = count($path); + + if ($node instanceof PHP_CodeCoverage_Report_Node_File) { + $max--; + } + + for ($i = 0; $i < $max; $i++) { + $pathToRoot[] = str_repeat('../', $i); + } + + foreach ($path as $step) { + if ($step !== $node) { + $breadcrumbs .= $this->getInactiveBreadcrumb( + $step, + array_pop($pathToRoot) + ); + } else { + $breadcrumbs .= $this->getActiveBreadcrumb($step); + } + } + + return $breadcrumbs; + } + + protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node) + { + $buffer = sprintf( + '
  • %s
  • ' . "\n", + $node->getName() + ); + + if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) { + $buffer .= '
  • (Dashboard)
  • ' . "\n"; + } + + return $buffer; + } + + protected function getInactiveBreadcrumb(PHP_CodeCoverage_Report_Node $node, $pathToRoot) + { + return sprintf( + '
  • %s
  • ' . "\n", + $pathToRoot, + $node->getName() + ); + } + + protected function getPathToRoot(PHP_CodeCoverage_Report_Node $node) + { + $id = $node->getId(); + $depth = substr_count($id, '/'); + + if ($id != 'index' && + $node instanceof PHP_CodeCoverage_Report_Node_Directory) { + $depth++; + } + + return str_repeat('../', $depth); + } + + protected function getCoverageBar($percent) + { + $level = $this->getColorLevel($percent); + + $template = new Text_Template( + $this->templatePath . 'coverage_bar.html', + '{{', + '}}' + ); + + $template->setVar(array('level' => $level, 'percent' => sprintf('%.2F', $percent))); + + return $template->render(); + } + + /** + * @param int $percent + * @return string + */ + protected function getColorLevel($percent) + { + if ($percent <= $this->lowUpperBound) { + return 'danger'; + } elseif ($percent > $this->lowUpperBound && + $percent < $this->highLowerBound) { + return 'warning'; + } else { + return 'success'; + } + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php new file mode 100644 index 0000000..f648097 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php @@ -0,0 +1,295 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Renders the dashboard for a PHP_CodeCoverage_Report_Node_Directory node. + * + * @since Class available since Release 1.1.0 + */ +class PHP_CodeCoverage_Report_HTML_Renderer_Dashboard extends PHP_CodeCoverage_Report_HTML_Renderer +{ + /** + * @param PHP_CodeCoverage_Report_Node_Directory $node + * @param string $file + */ + public function render(PHP_CodeCoverage_Report_Node_Directory $node, $file) + { + $classes = $node->getClassesAndTraits(); + $template = new Text_Template( + $this->templatePath . 'dashboard.html', + '{{', + '}}' + ); + + $this->setCommonTemplateVariables($template, $node); + + $baseLink = $node->getId() . '/'; + $complexity = $this->complexity($classes, $baseLink); + $coverageDistribution = $this->coverageDistribution($classes); + $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink); + $projectRisks = $this->projectRisks($classes, $baseLink); + + $template->setVar( + array( + 'insufficient_coverage_classes' => $insufficientCoverage['class'], + 'insufficient_coverage_methods' => $insufficientCoverage['method'], + 'project_risks_classes' => $projectRisks['class'], + 'project_risks_methods' => $projectRisks['method'], + 'complexity_class' => $complexity['class'], + 'complexity_method' => $complexity['method'], + 'class_coverage_distribution' => $coverageDistribution['class'], + 'method_coverage_distribution' => $coverageDistribution['method'] + ) + ); + + $template->renderTo($file); + } + + /** + * Returns the data for the Class/Method Complexity charts. + * + * @param array $classes + * @param string $baseLink + * @return array + */ + protected function complexity(array $classes, $baseLink) + { + $result = array('class' => array(), 'method' => array()); + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($className != '*') { + $methodName = $className . '::' . $methodName; + } + + $result['method'][] = array( + $method['coverage'], + $method['ccn'], + sprintf( + '%s', + str_replace($baseLink, '', $method['link']), + $methodName + ) + ); + } + + $result['class'][] = array( + $class['coverage'], + $class['ccn'], + sprintf( + '%s', + str_replace($baseLink, '', $class['link']), + $className + ) + ); + } + + return array( + 'class' => json_encode($result['class']), + 'method' => json_encode($result['method']) + ); + } + + /** + * Returns the data for the Class / Method Coverage Distribution chart. + * + * @param array $classes + * @return array + */ + protected function coverageDistribution(array $classes) + { + $result = array( + 'class' => array( + '0%' => 0, + '0-10%' => 0, + '10-20%' => 0, + '20-30%' => 0, + '30-40%' => 0, + '40-50%' => 0, + '50-60%' => 0, + '60-70%' => 0, + '70-80%' => 0, + '80-90%' => 0, + '90-100%' => 0, + '100%' => 0 + ), + 'method' => array( + '0%' => 0, + '0-10%' => 0, + '10-20%' => 0, + '20-30%' => 0, + '30-40%' => 0, + '40-50%' => 0, + '50-60%' => 0, + '60-70%' => 0, + '70-80%' => 0, + '80-90%' => 0, + '90-100%' => 0, + '100%' => 0 + ) + ); + + foreach ($classes as $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] == 0) { + $result['method']['0%']++; + } elseif ($method['coverage'] == 100) { + $result['method']['100%']++; + } else { + $key = floor($method['coverage'] / 10) * 10; + $key = $key . '-' . ($key + 10) . '%'; + $result['method'][$key]++; + } + } + + if ($class['coverage'] == 0) { + $result['class']['0%']++; + } elseif ($class['coverage'] == 100) { + $result['class']['100%']++; + } else { + $key = floor($class['coverage'] / 10) * 10; + $key = $key . '-' . ($key + 10) . '%'; + $result['class'][$key]++; + } + } + + return array( + 'class' => json_encode(array_values($result['class'])), + 'method' => json_encode(array_values($result['method'])) + ); + } + + /** + * Returns the classes / methods with insufficient coverage. + * + * @param array $classes + * @param string $baseLink + * @return array + */ + protected function insufficientCoverage(array $classes, $baseLink) + { + $leastTestedClasses = array(); + $leastTestedMethods = array(); + $result = array('class' => '', 'method' => ''); + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] < $this->highLowerBound) { + if ($className != '*') { + $key = $className . '::' . $methodName; + } else { + $key = $methodName; + } + + $leastTestedMethods[$key] = $method['coverage']; + } + } + + if ($class['coverage'] < $this->highLowerBound) { + $leastTestedClasses[$className] = $class['coverage']; + } + } + + asort($leastTestedClasses); + asort($leastTestedMethods); + + foreach ($leastTestedClasses as $className => $coverage) { + $result['class'] .= sprintf( + ' %s%d%%' . "\n", + str_replace($baseLink, '', $classes[$className]['link']), + $className, + $coverage + ); + } + + foreach ($leastTestedMethods as $methodName => $coverage) { + list($class, $method) = explode('::', $methodName); + + $result['method'] .= sprintf( + ' %s%d%%' . "\n", + str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), + $methodName, + $method, + $coverage + ); + } + + return $result; + } + + /** + * Returns the project risks according to the CRAP index. + * + * @param array $classes + * @param string $baseLink + * @return array + */ + protected function projectRisks(array $classes, $baseLink) + { + $classRisks = array(); + $methodRisks = array(); + $result = array('class' => '', 'method' => ''); + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] < $this->highLowerBound && + $method['ccn'] > 1) { + if ($className != '*') { + $key = $className . '::' . $methodName; + } else { + $key = $methodName; + } + + $methodRisks[$key] = $method['crap']; + } + } + + if ($class['coverage'] < $this->highLowerBound && + $class['ccn'] > count($class['methods'])) { + $classRisks[$className] = $class['crap']; + } + } + + arsort($classRisks); + arsort($methodRisks); + + foreach ($classRisks as $className => $crap) { + $result['class'] .= sprintf( + ' %s%d' . "\n", + str_replace($baseLink, '', $classes[$className]['link']), + $className, + $crap + ); + } + + foreach ($methodRisks as $methodName => $crap) { + list($class, $method) = explode('::', $methodName); + + $result['method'] .= sprintf( + ' %s%d' . "\n", + str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), + $methodName, + $method, + $crap + ); + } + + return $result; + } + + protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node) + { + return sprintf( + '
  • %s
  • ' . "\n" . + '
  • (Dashboard)
  • ' . "\n", + $node->getName() + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php new file mode 100644 index 0000000..4415c52 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Renders a PHP_CodeCoverage_Report_Node_Directory node. + * + * @since Class available since Release 1.1.0 + */ +class PHP_CodeCoverage_Report_HTML_Renderer_Directory extends PHP_CodeCoverage_Report_HTML_Renderer +{ + /** + * @param PHP_CodeCoverage_Report_Node_Directory $node + * @param string $file + */ + public function render(PHP_CodeCoverage_Report_Node_Directory $node, $file) + { + $template = new Text_Template($this->templatePath . 'directory.html', '{{', '}}'); + + $this->setCommonTemplateVariables($template, $node); + + $items = $this->renderItem($node, true); + + foreach ($node->getDirectories() as $item) { + $items .= $this->renderItem($item); + } + + foreach ($node->getFiles() as $item) { + $items .= $this->renderItem($item); + } + + $template->setVar( + array( + 'id' => $node->getId(), + 'items' => $items + ) + ); + + $template->renderTo($file); + } + + /** + * @param PHP_CodeCoverage_Report_Node $item + * @param bool $total + * @return string + */ + protected function renderItem(PHP_CodeCoverage_Report_Node $item, $total = false) + { + $data = array( + 'numClasses' => $item->getNumClassesAndTraits(), + 'numTestedClasses' => $item->getNumTestedClassesAndTraits(), + 'numMethods' => $item->getNumMethods(), + 'numTestedMethods' => $item->getNumTestedMethods(), + 'linesExecutedPercent' => $item->getLineExecutedPercent(false), + 'linesExecutedPercentAsString' => $item->getLineExecutedPercent(), + 'numExecutedLines' => $item->getNumExecutedLines(), + 'numExecutableLines' => $item->getNumExecutableLines(), + 'testedMethodsPercent' => $item->getTestedMethodsPercent(false), + 'testedMethodsPercentAsString' => $item->getTestedMethodsPercent(), + 'testedClassesPercent' => $item->getTestedClassesAndTraitsPercent(false), + 'testedClassesPercentAsString' => $item->getTestedClassesAndTraitsPercent() + ); + + if ($total) { + $data['name'] = 'Total'; + } else { + if ($item instanceof PHP_CodeCoverage_Report_Node_Directory) { + $data['name'] = sprintf( + '%s', + $item->getName(), + $item->getName() + ); + + $data['icon'] = ' '; + } else { + $data['name'] = sprintf( + '%s', + $item->getName(), + $item->getName() + ); + + $data['icon'] = ' '; + } + } + + return $this->renderItemTemplate( + new Text_Template($this->templatePath . 'directory_item.html', '{{', '}}'), + $data + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php new file mode 100644 index 0000000..d52345d --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php @@ -0,0 +1,556 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +// @codeCoverageIgnoreStart +if (!defined('T_TRAIT')) { + define('T_TRAIT', 1001); +} + +if (!defined('T_INSTEADOF')) { + define('T_INSTEADOF', 1002); +} + +if (!defined('T_CALLABLE')) { + define('T_CALLABLE', 1003); +} + +if (!defined('T_FINALLY')) { + define('T_FINALLY', 1004); +} + +if (!defined('T_YIELD')) { + define('T_YIELD', 1005); +} +// @codeCoverageIgnoreEnd + +/** + * Renders a PHP_CodeCoverage_Report_Node_File node. + * + * @since Class available since Release 1.1.0 + */ +class PHP_CodeCoverage_Report_HTML_Renderer_File extends PHP_CodeCoverage_Report_HTML_Renderer +{ + /** + * @var int + */ + private $htmlspecialcharsFlags; + + /** + * Constructor. + * + * @param string $templatePath + * @param string $generator + * @param string $date + * @param int $lowUpperBound + * @param int $highLowerBound + */ + public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound) + { + parent::__construct( + $templatePath, + $generator, + $date, + $lowUpperBound, + $highLowerBound + ); + + $this->htmlspecialcharsFlags = ENT_COMPAT; + + if (PHP_VERSION_ID >= 50400 && defined('ENT_SUBSTITUTE')) { + $this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE; + } + } + + /** + * @param PHP_CodeCoverage_Report_Node_File $node + * @param string $file + */ + public function render(PHP_CodeCoverage_Report_Node_File $node, $file) + { + $template = new Text_Template($this->templatePath . 'file.html', '{{', '}}'); + + $template->setVar( + array( + 'items' => $this->renderItems($node), + 'lines' => $this->renderSource($node) + ) + ); + + $this->setCommonTemplateVariables($template, $node); + + $template->renderTo($file); + } + + /** + * @param PHP_CodeCoverage_Report_Node_File $node + * @return string + */ + protected function renderItems(PHP_CodeCoverage_Report_Node_File $node) + { + $template = new Text_Template($this->templatePath . 'file_item.html', '{{', '}}'); + + $methodItemTemplate = new Text_Template( + $this->templatePath . 'method_item.html', + '{{', + '}}' + ); + + $items = $this->renderItemTemplate( + $template, + array( + 'name' => 'Total', + 'numClasses' => $node->getNumClassesAndTraits(), + 'numTestedClasses' => $node->getNumTestedClassesAndTraits(), + 'numMethods' => $node->getNumMethods(), + 'numTestedMethods' => $node->getNumTestedMethods(), + 'linesExecutedPercent' => $node->getLineExecutedPercent(false), + 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(), + 'numExecutedLines' => $node->getNumExecutedLines(), + 'numExecutableLines' => $node->getNumExecutableLines(), + 'testedMethodsPercent' => $node->getTestedMethodsPercent(false), + 'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(), + 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false), + 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(), + 'crap' => 'CRAP' + ) + ); + + $items .= $this->renderFunctionItems( + $node->getFunctions(), + $methodItemTemplate + ); + + $items .= $this->renderTraitOrClassItems( + $node->getTraits(), + $template, + $methodItemTemplate + ); + + $items .= $this->renderTraitOrClassItems( + $node->getClasses(), + $template, + $methodItemTemplate + ); + + return $items; + } + + /** + * @param array $items + * @param Text_Template $template + * @param Text_Template $methodItemTemplate + * @return string + */ + protected function renderTraitOrClassItems(array $items, Text_Template $template, Text_Template $methodItemTemplate) + { + if (empty($items)) { + return ''; + } + + $buffer = ''; + + foreach ($items as $name => $item) { + $numMethods = count($item['methods']); + $numTestedMethods = 0; + + foreach ($item['methods'] as $method) { + if ($method['executedLines'] == $method['executableLines']) { + $numTestedMethods++; + } + } + + $buffer .= $this->renderItemTemplate( + $template, + array( + 'name' => $name, + 'numClasses' => 1, + 'numTestedClasses' => $numTestedMethods == $numMethods ? 1 : 0, + 'numMethods' => $numMethods, + 'numTestedMethods' => $numTestedMethods, + 'linesExecutedPercent' => PHP_CodeCoverage_Util::percent( + $item['executedLines'], + $item['executableLines'], + false + ), + 'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent( + $item['executedLines'], + $item['executableLines'], + true + ), + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'testedMethodsPercent' => PHP_CodeCoverage_Util::percent( + $numTestedMethods, + $numMethods, + false + ), + 'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent( + $numTestedMethods, + $numMethods, + true + ), + 'testedClassesPercent' => PHP_CodeCoverage_Util::percent( + $numTestedMethods == $numMethods ? 1 : 0, + 1, + false + ), + 'testedClassesPercentAsString' => PHP_CodeCoverage_Util::percent( + $numTestedMethods == $numMethods ? 1 : 0, + 1, + true + ), + 'crap' => $item['crap'] + ) + ); + + foreach ($item['methods'] as $method) { + $buffer .= $this->renderFunctionOrMethodItem( + $methodItemTemplate, + $method, + ' ' + ); + } + } + + return $buffer; + } + + /** + * @param array $functions + * @param Text_Template $template + * @return string + */ + protected function renderFunctionItems(array $functions, Text_Template $template) + { + if (empty($functions)) { + return ''; + } + + $buffer = ''; + + foreach ($functions as $function) { + $buffer .= $this->renderFunctionOrMethodItem( + $template, + $function + ); + } + + return $buffer; + } + + /** + * @param Text_Template $template + * @return string + */ + protected function renderFunctionOrMethodItem(Text_Template $template, array $item, $indent = '') + { + $numTestedItems = $item['executedLines'] == $item['executableLines'] ? 1 : 0; + + return $this->renderItemTemplate( + $template, + array( + 'name' => sprintf( + '%s%s', + $indent, + $item['startLine'], + htmlspecialchars($item['signature']), + isset($item['functionName']) ? $item['functionName'] : $item['methodName'] + ), + 'numMethods' => 1, + 'numTestedMethods' => $numTestedItems, + 'linesExecutedPercent' => PHP_CodeCoverage_Util::percent( + $item['executedLines'], + $item['executableLines'], + false + ), + 'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent( + $item['executedLines'], + $item['executableLines'], + true + ), + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'testedMethodsPercent' => PHP_CodeCoverage_Util::percent( + $numTestedItems, + 1, + false + ), + 'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent( + $numTestedItems, + 1, + true + ), + 'crap' => $item['crap'] + ) + ); + } + + /** + * @param PHP_CodeCoverage_Report_Node_File $node + * @return string + */ + protected function renderSource(PHP_CodeCoverage_Report_Node_File $node) + { + $coverageData = $node->getCoverageData(); + $testData = $node->getTestData(); + $codeLines = $this->loadFile($node->getPath()); + $lines = ''; + $i = 1; + + foreach ($codeLines as $line) { + $trClass = ''; + $popoverContent = ''; + $popoverTitle = ''; + + if (array_key_exists($i, $coverageData)) { + $numTests = count($coverageData[$i]); + + if ($coverageData[$i] === null) { + $trClass = ' class="warning"'; + } elseif ($numTests == 0) { + $trClass = ' class="danger"'; + } else { + $lineCss = 'covered-by-large-tests'; + $popoverContent = '
      '; + + if ($numTests > 1) { + $popoverTitle = $numTests . ' tests cover line ' . $i; + } else { + $popoverTitle = '1 test covers line ' . $i; + } + + foreach ($coverageData[$i] as $test) { + if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') { + $lineCss = 'covered-by-medium-tests'; + } elseif ($testData[$test]['size'] == 'small') { + $lineCss = 'covered-by-small-tests'; + } + + switch ($testData[$test]['status']) { + case 0: + switch ($testData[$test]['size']) { + case 'small': + $testCSS = ' class="covered-by-small-tests"'; + break; + + case 'medium': + $testCSS = ' class="covered-by-medium-tests"'; + break; + + default: + $testCSS = ' class="covered-by-large-tests"'; + break; + } + break; + + case 1: + case 2: + $testCSS = ' class="warning"'; + break; + + case 3: + $testCSS = ' class="danger"'; + break; + + case 4: + $testCSS = ' class="danger"'; + break; + + default: + $testCSS = ''; + } + + $popoverContent .= sprintf( + '%s', + $testCSS, + htmlspecialchars($test) + ); + } + + $popoverContent .= '
    '; + $trClass = ' class="' . $lineCss . ' popin"'; + } + } + + if (!empty($popoverTitle)) { + $popover = sprintf( + ' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"', + $popoverTitle, + htmlspecialchars($popoverContent) + ); + } else { + $popover = ''; + } + + $lines .= sprintf( + ' %s' . "\n", + $trClass, + $popover, + $i, + $i, + $i, + $line + ); + + $i++; + } + + return $lines; + } + + /** + * @param string $file + * @return array + */ + protected function loadFile($file) + { + $buffer = file_get_contents($file); + $tokens = token_get_all($buffer); + $result = array(''); + $i = 0; + $stringFlag = false; + $fileEndsWithNewLine = substr($buffer, -1) == "\n"; + + unset($buffer); + + foreach ($tokens as $j => $token) { + if (is_string($token)) { + if ($token === '"' && $tokens[$j - 1] !== '\\') { + $result[$i] .= sprintf( + '%s', + htmlspecialchars($token) + ); + + $stringFlag = !$stringFlag; + } else { + $result[$i] .= sprintf( + '%s', + htmlspecialchars($token) + ); + } + + continue; + } + + list($token, $value) = $token; + + $value = str_replace( + array("\t", ' '), + array('    ', ' '), + htmlspecialchars($value, $this->htmlspecialcharsFlags) + ); + + if ($value === "\n") { + $result[++$i] = ''; + } else { + $lines = explode("\n", $value); + + foreach ($lines as $jj => $line) { + $line = trim($line); + + if ($line !== '') { + if ($stringFlag) { + $colour = 'string'; + } else { + switch ($token) { + case T_INLINE_HTML: + $colour = 'html'; + break; + + case T_COMMENT: + case T_DOC_COMMENT: + $colour = 'comment'; + break; + + case T_ABSTRACT: + case T_ARRAY: + case T_AS: + case T_BREAK: + case T_CALLABLE: + case T_CASE: + case T_CATCH: + case T_CLASS: + case T_CLONE: + case T_CONTINUE: + case T_DEFAULT: + case T_ECHO: + case T_ELSE: + case T_ELSEIF: + case T_EMPTY: + case T_ENDDECLARE: + case T_ENDFOR: + case T_ENDFOREACH: + case T_ENDIF: + case T_ENDSWITCH: + case T_ENDWHILE: + case T_EXIT: + case T_EXTENDS: + case T_FINAL: + case T_FINALLY: + case T_FOREACH: + case T_FUNCTION: + case T_GLOBAL: + case T_IF: + case T_IMPLEMENTS: + case T_INCLUDE: + case T_INCLUDE_ONCE: + case T_INSTANCEOF: + case T_INSTEADOF: + case T_INTERFACE: + case T_ISSET: + case T_LOGICAL_AND: + case T_LOGICAL_OR: + case T_LOGICAL_XOR: + case T_NAMESPACE: + case T_NEW: + case T_PRIVATE: + case T_PROTECTED: + case T_PUBLIC: + case T_REQUIRE: + case T_REQUIRE_ONCE: + case T_RETURN: + case T_STATIC: + case T_THROW: + case T_TRAIT: + case T_TRY: + case T_UNSET: + case T_USE: + case T_VAR: + case T_WHILE: + case T_YIELD: + $colour = 'keyword'; + break; + + default: + $colour = 'default'; + } + } + + $result[$i] .= sprintf( + '%s', + $colour, + $line + ); + } + + if (isset($lines[$jj + 1])) { + $result[++$i] = ''; + } + } + } + } + + if ($fileEndsWithNewLine) { + unset($result[count($result)-1]); + } + + return $result; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist new file mode 100644 index 0000000..5a09c35 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist @@ -0,0 +1,5 @@ +
    +
    + {{percent}}% covered ({{level}}) +
    +
    diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.css b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.css new file mode 100644 index 0000000..cd1c616 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.4 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px)and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px)and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px)and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.min.css b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.min.css new file mode 100644 index 0000000..7a6f7fe --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.min.css @@ -0,0 +1 @@ +.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/style.css b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/style.css new file mode 100644 index 0000000..824fb31 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/css/style.css @@ -0,0 +1,122 @@ +body { + padding-top: 10px; +} + +.popover { + max-width: none; +} + +.glyphicon { + margin-right:.25em; +} + +.table-bordered>thead>tr>td { + border-bottom-width: 1px; +} + +.table tbody>tr>td, .table thead>tr>td { + padding-top: 3px; + padding-bottom: 3px; +} + +.table-condensed tbody>tr>td { + padding-top: 0; + padding-bottom: 0; +} + +.table .progress { + margin-bottom: inherit; +} + +.table-borderless th, .table-borderless td { + border: 0 !important; +} + +.table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success { + background-color: #dff0d8; +} + +.table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests { + background-color: #c3e3b5; +} + +.table tbody tr.covered-by-small-tests, li.covered-by-small-tests { + background-color: #99cb84; +} + +.table tbody tr.danger, .table tbody td.danger, li.danger, span.danger { + background-color: #f2dede; +} + +.table tbody td.warning, li.warning, span.warning { + background-color: #fcf8e3; +} + +.table tbody td.info { + background-color: #d9edf7; +} + +td.big { + width: 117px; +} + +td.small { +} + +td.codeLine { + font-family: monospace; + white-space: pre; +} + +td span.comment { + color: #888a85; +} + +td span.default { + color: #2e3436; +} + +td span.html { + color: #888a85; +} + +td span.keyword { + color: #2e3436; + font-weight: bold; +} + +pre span.string { + color: #2e3436; +} + +span.success, span.warning, span.danger { + margin-right: 2px; + padding-left: 10px; + padding-right: 10px; + text-align: center; +} + +#classCoverageDistribution, #classComplexity { + height: 200px; + width: 475px; +} + +#toplink { + position: fixed; + left: 5px; + bottom: 5px; + outline: 0; +} + +svg text { + font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #666; + fill: #666; +} + +.scrollbox { + height:245px; + overflow-x:hidden; + overflow-y:scroll; +} diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.dist b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.dist new file mode 100644 index 0000000..ed18988 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.dist @@ -0,0 +1,284 @@ + + + + + Dashboard for {{full_path}} + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Classes

    +
    +
    +
    +
    +

    Coverage Distribution

    +
    + +
    +
    +
    +

    Complexity

    +
    + +
    +
    +
    +
    +
    +

    Insufficient Coverage

    +
    + + + + + + + + +{{insufficient_coverage_classes}} + +
    ClassCoverage
    +
    +
    +
    +

    Project Risks

    +
    + + + + + + + + +{{project_risks_classes}} + +
    ClassCRAP
    +
    +
    +
    +
    +
    +

    Methods

    +
    +
    +
    +
    +

    Coverage Distribution

    +
    + +
    +
    +
    +

    Complexity

    +
    + +
    +
    +
    +
    +
    +

    Insufficient Coverage

    +
    + + + + + + + + +{{insufficient_coverage_methods}} + +
    MethodCoverage
    +
    +
    +
    +

    Project Risks

    +
    + + + + + + + + +{{project_risks_methods}} + +
    MethodCRAP
    +
    +
    +
    + +
    + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/directory.html.dist b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/directory.html.dist new file mode 100644 index 0000000..efe743f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/directory.html.dist @@ -0,0 +1,61 @@ + + + + + Code Coverage for {{full_path}} + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + +{{items}} + +
     
    Code Coverage
     
    Lines
    Functions and Methods
    Classes and Traits
    + +
    + + + + + diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist new file mode 100644 index 0000000..78dbb35 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist @@ -0,0 +1,13 @@ + + {{icon}}{{name}} + {{lines_bar}} +
    {{lines_executed_percent}}
    +
    {{lines_number}}
    + {{methods_bar}} +
    {{methods_tested_percent}}
    +
    {{methods_number}}
    + {{classes_bar}} +
    {{classes_tested_percent}}
    +
    {{classes_number}}
    + + diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/file.html.dist b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/file.html.dist new file mode 100644 index 0000000..59a0684 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/file.html.dist @@ -0,0 +1,90 @@ + + + + + Code Coverage for {{full_path}} + + + + + + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + +{{items}} + +
     
    Code Coverage
     
    Classes and Traits
    Functions and Methods
    Lines
    + + +{{lines}} + +
    + +
    + + + + + + diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.dist b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.dist new file mode 100644 index 0000000..756fdd6 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.dist @@ -0,0 +1,14 @@ + + {{name}} + {{classes_bar}} +
    {{classes_tested_percent}}
    +
    {{classes_number}}
    + {{methods_bar}} +
    {{methods_tested_percent}}
    +
    {{methods_number}}
    + {{crap}} + {{lines_bar}} +
    {{lines_executed_percent}}
    +
    {{lines_number}}
    + + diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.eot b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..b93a4953fff68df523aa7656497ee339d6026d64 GIT binary patch literal 20127 zcma%hV{j!vx9y2-`@~L8?1^pLwlPU2wr$&<*tR|KBoo`2;LUg6eW-eW-tKDb)vH%` z^`A!Vd<6hNSRMcX|Cb;E|1qflDggj6Kmr)xA10^t-vIc3*Z+F{r%|K(GyE^?|I{=9 zNq`(c8=wS`0!RZy0g3{M(8^tv41d}oRU?8#IBFtJy*9zAN5dcxqGlMZGL>GG%R#)4J zDJ2;)4*E1pyHia%>lMv3X7Q`UoFyoB@|xvh^)kOE3)IL&0(G&i;g08s>c%~pHkN&6 z($7!kyv|A2DsV2mq-5Ku)D#$Kn$CzqD-wm5Q*OtEOEZe^&T$xIb0NUL}$)W)Ck`6oter6KcQG9Zcy>lXip)%e&!lQgtQ*N`#abOlytt!&i3fo)cKV zP0BWmLxS1gQv(r_r|?9>rR0ZeEJPx;Vi|h1!Eo*dohr&^lJgqJZns>&vexP@fs zkPv93Nyw$-kM5Mw^{@wPU47Y1dSkiHyl3dtHLwV&6Tm1iv{ve;sYA}Z&kmH802s9Z zyJEn+cfl7yFu#1^#DbtP7k&aR06|n{LnYFYEphKd@dJEq@)s#S)UA&8VJY@S2+{~> z(4?M();zvayyd^j`@4>xCqH|Au>Sfzb$mEOcD7e4z8pPVRTiMUWiw;|gXHw7LS#U< zsT(}Z5SJ)CRMXloh$qPnK77w_)ctHmgh}QAe<2S{DU^`!uwptCoq!Owz$u6bF)vnb zL`bM$%>baN7l#)vtS3y6h*2?xCk z>w+s)@`O4(4_I{L-!+b%)NZcQ&ND=2lyP+xI#9OzsiY8$c)ys-MI?TG6 zEP6f=vuLo!G>J7F4v|s#lJ+7A`^nEQScH3e?B_jC&{sj>m zYD?!1z4nDG_Afi$!J(<{>z{~Q)$SaXWjj~%ZvF152Hd^VoG14rFykR=_TO)mCn&K$ z-TfZ!vMBvnToyBoKRkD{3=&=qD|L!vb#jf1f}2338z)e)g>7#NPe!FoaY*jY{f)Bf>ohk-K z4{>fVS}ZCicCqgLuYR_fYx2;*-4k>kffuywghn?15s1dIOOYfl+XLf5w?wtU2Og*f z%X5x`H55F6g1>m~%F`655-W1wFJtY>>qNSdVT`M`1Mlh!5Q6#3j={n5#za;!X&^OJ zgq;d4UJV-F>gg?c3Y?d=kvn3eV)Jb^ zO5vg0G0yN0%}xy#(6oTDSVw8l=_*2k;zTP?+N=*18H5wp`s90K-C67q{W3d8vQGmr zhpW^>1HEQV2TG#8_P_0q91h8QgHT~8=-Ij5snJ3cj?Jn5_66uV=*pq(j}yHnf$Ft;5VVC?bz%9X31asJeQF2jEa47H#j` zk&uxf3t?g!tltVP|B#G_UfDD}`<#B#iY^i>oDd-LGF}A@Fno~dR72c&hs6bR z2F}9(i8+PR%R|~FV$;Ke^Q_E_Bc;$)xN4Ti>Lgg4vaip!%M z06oxAF_*)LH57w|gCW3SwoEHwjO{}}U=pKhjKSZ{u!K?1zm1q? zXyA6y@)}_sONiJopF}_}(~}d4FDyp|(@w}Vb;Fl5bZL%{1`}gdw#i{KMjp2@Fb9pg ziO|u7qP{$kxH$qh8%L+)AvwZNgUT6^zsZq-MRyZid{D?t`f|KzSAD~C?WT3d0rO`0 z=qQ6{)&UXXuHY{9g|P7l_nd-%eh}4%VVaK#Nik*tOu9lBM$<%FS@`NwGEbP0&;Xbo zObCq=y%a`jSJmx_uTLa{@2@}^&F4c%z6oe-TN&idjv+8E|$FHOvBqg5hT zMB=7SHq`_-E?5g=()*!V>rIa&LcX(RU}aLm*38U_V$C_g4)7GrW5$GnvTwJZdBmy6 z*X)wi3=R8L=esOhY0a&eH`^fSpUHV8h$J1|o^3fKO|9QzaiKu>yZ9wmRkW?HTkc<*v7i*ylJ#u#j zD1-n&{B`04oG>0Jn{5PKP*4Qsz{~`VVA3578gA+JUkiPc$Iq!^K|}*p_z3(-c&5z@ zKxmdNpp2&wg&%xL3xZNzG-5Xt7jnI@{?c z25=M>-VF|;an2Os$Nn%HgQz7m(ujC}Ii0Oesa(y#8>D+P*_m^X##E|h$M6tJr%#=P zWP*)Px>7z`E~U^2LNCNiy%Z7!!6RI%6fF@#ZY3z`CK91}^J$F!EB0YF1je9hJKU7!S5MnXV{+#K;y zF~s*H%p@vj&-ru7#(F2L+_;IH46X(z{~HTfcThqD%b{>~u@lSc<+f5#xgt9L7$gSK ziDJ6D*R%4&YeUB@yu@4+&70MBNTnjRyqMRd+@&lU#rV%0t3OmouhC`mkN}pL>tXin zY*p)mt=}$EGT2E<4Q>E2`6)gZ`QJhGDNpI}bZL9}m+R>q?l`OzFjW?)Y)P`fUH(_4 zCb?sm1=DD0+Q5v}BW#0n5;Nm(@RTEa3(Y17H2H67La+>ptQHJ@WMy2xRQT$|7l`8c zYHCxYw2o-rI?(fR2-%}pbs$I%w_&LPYE{4bo}vRoAW>3!SY_zH3`ofx3F1PsQ?&iq z*BRG>?<6%z=x#`NhlEq{K~&rU7Kc7Y-90aRnoj~rVoKae)L$3^z*Utppk?I`)CX&& zZ^@Go9fm&fN`b`XY zt0xE5aw4t@qTg_k=!-5LXU+_~DlW?53!afv6W(k@FPPX-`nA!FBMp7b!ODbL1zh58 z*69I}P_-?qSLKj}JW7gP!la}K@M}L>v?rDD!DY-tu+onu9kLoJz20M4urX_xf2dfZ zORd9Zp&28_ff=wdMpXi%IiTTNegC}~RLkdYjA39kWqlA?jO~o1`*B&85Hd%VPkYZT z48MPe62;TOq#c%H(`wX5(Bu>nlh4Fbd*Npasdhh?oRy8a;NB2(eb}6DgwXtx=n}fE zx67rYw=(s0r?EsPjaya}^Qc-_UT5|*@|$Q}*|>V3O~USkIe6a0_>vd~6kHuP8=m}_ zo2IGKbv;yA+TBtlCpnw)8hDn&eq?26gN$Bh;SdxaS04Fsaih_Cfb98s39xbv)=mS0 z6M<@pM2#pe32w*lYSWG>DYqB95XhgAA)*9dOxHr{t)er0Xugoy)!Vz#2C3FaUMzYl zCxy{igFB901*R2*F4>grPF}+G`;Yh zGi@nRjWyG3mR(BVOeBPOF=_&}2IWT%)pqdNAcL{eP`L*^FDv#Rzql5U&Suq_X%JfR_lC!S|y|xd5mQ0{0!G#9hV46S~A` z0B!{yI-4FZEtol5)mNWXcX(`x&Pc*&gh4k{w%0S#EI>rqqlH2xv7mR=9XNCI$V#NG z4wb-@u{PfQP;tTbzK>(DF(~bKp3;L1-A*HS!VB)Ae>Acnvde15Anb`h;I&0)aZBS6 z55ZS7mL5Wp!LCt45^{2_70YiI_Py=X{I3>$Px5Ez0ahLQ+ z9EWUWSyzA|+g-Axp*Lx-M{!ReQO07EG7r4^)K(xbj@%ZU=0tBC5shl)1a!ifM5OkF z0w2xQ-<+r-h1fi7B6waX15|*GGqfva)S)dVcgea`lQ~SQ$KXPR+(3Tn2I2R<0 z9tK`L*pa^+*n%>tZPiqt{_`%v?Bb7CR-!GhMON_Fbs0$#|H}G?rW|{q5fQhvw!FxI zs-5ZK>hAbnCS#ZQVi5K0X3PjL1JRdQO+&)*!oRCqB{wen60P6!7bGiWn@vD|+E@Xq zb!!_WiU^I|@1M}Hz6fN-m04x=>Exm{b@>UCW|c8vC`aNbtA@KCHujh^2RWZC}iYhL^<*Z93chIBJYU&w>$CGZDRcHuIgF&oyesDZ#&mA;?wxx4Cm#c0V$xYG?9OL(Smh}#fFuX(K;otJmvRP{h ze^f-qv;)HKC7geB92_@3a9@MGijS(hNNVd%-rZ;%@F_f7?Fjinbe1( zn#jQ*jKZTqE+AUTEd3y6t>*=;AO##cmdwU4gc2&rT8l`rtKW2JF<`_M#p>cj+)yCG zgKF)y8jrfxTjGO&ccm8RU>qn|HxQ7Z#sUo$q)P5H%8iBF$({0Ya51-rA@!It#NHN8MxqK zrYyl_&=}WVfQ?+ykV4*@F6)=u_~3BebR2G2>>mKaEBPmSW3(qYGGXj??m3L zHec{@jWCsSD8`xUy0pqT?Sw0oD?AUK*WxZn#D>-$`eI+IT)6ki>ic}W)t$V32^ITD zR497@LO}S|re%A+#vdv-?fXsQGVnP?QB_d0cGE+U84Q=aM=XrOwGFN3`Lpl@P0fL$ zKN1PqOwojH*($uaQFh8_)H#>Acl&UBSZ>!2W1Dinei`R4dJGX$;~60X=|SG6#jci} z&t4*dVDR*;+6Y(G{KGj1B2!qjvDYOyPC}%hnPbJ@g(4yBJrViG1#$$X75y+Ul1{%x zBAuD}Q@w?MFNqF-m39FGpq7RGI?%Bvyyig&oGv)lR>d<`Bqh=p>urib5DE;u$c|$J zwim~nPb19t?LJZsm{<(Iyyt@~H!a4yywmHKW&=1r5+oj*Fx6c89heW@(2R`i!Uiy* zp)=`Vr8sR!)KChE-6SEIyi(dvG3<1KoVt>kGV=zZiG7LGonH1+~yOK-`g0)r#+O|Q>)a`I2FVW%wr3lhO(P{ksNQuR!G_d zeTx(M!%brW_vS9?IF>bzZ2A3mWX-MEaOk^V|4d38{1D|KOlZSjBKrj7Fgf^>JyL0k zLoI$adZJ0T+8i_Idsuj}C;6jgx9LY#Ukh;!8eJ^B1N}q=Gn4onF*a2vY7~`x$r@rJ z`*hi&Z2lazgu{&nz>gjd>#eq*IFlXed(%$s5!HRXKNm zDZld+DwDI`O6hyn2uJ)F^{^;ESf9sjJ)wMSKD~R=DqPBHyP!?cGAvL<1|7K-(=?VO zGcKcF1spUa+ki<`6K#@QxOTsd847N8WSWztG~?~ z!gUJn>z0O=_)VCE|56hkT~n5xXTp}Ucx$Ii%bQ{5;-a4~I2e|{l9ur#*ghd*hSqO= z)GD@ev^w&5%k}YYB~!A%3*XbPPU-N6&3Lp1LxyP@|C<{qcn&?l54+zyMk&I3YDT|E z{lXH-e?C{huu<@~li+73lMOk&k)3s7Asn$t6!PtXJV!RkA`qdo4|OC_a?vR!kE_}k zK5R9KB%V@R7gt@9=TGL{=#r2gl!@3G;k-6sXp&E4u20DgvbY$iE**Xqj3TyxK>3AU z!b9}NXuINqt>Htt6fXIy5mj7oZ{A&$XJ&thR5ySE{mkxq_YooME#VCHm2+3D!f`{) zvR^WSjy_h4v^|!RJV-RaIT2Ctv=)UMMn@fAgjQV$2G+4?&dGA8vK35c-8r)z9Qqa=%k(FU)?iec14<^olkOU3p zF-6`zHiDKPafKK^USUU+D01>C&Wh{{q?>5m zGQp|z*+#>IIo=|ae8CtrN@@t~uLFOeT{}vX(IY*;>wAU=u1Qo4c+a&R);$^VCr>;! zv4L{`lHgc9$BeM)pQ#XA_(Q#=_iSZL4>L~8Hx}NmOC$&*Q*bq|9Aq}rWgFnMDl~d*;7c44GipcpH9PWaBy-G$*MI^F0 z?Tdxir1D<2ui+Q#^c4?uKvq=p>)lq56=Eb|N^qz~w7rsZu)@E4$;~snz+wIxi+980O6M#RmtgLYh@|2}9BiHSpTs zacjGKvwkUwR3lwTSsCHlwb&*(onU;)$yvdhikonn|B44JMgs*&Lo!jn`6AE>XvBiO z*LKNX3FVz9yLcsnmL!cRVO_qv=yIM#X|u&}#f%_?Tj0>8)8P_0r0!AjWNw;S44tst zv+NXY1{zRLf9OYMr6H-z?4CF$Y%MdbpFIN@a-LEnmkcOF>h16cH_;A|e)pJTuCJ4O zY7!4FxT4>4aFT8a92}84>q0&?46h>&0Vv0p>u~k&qd5$C1A6Q$I4V(5X~6{15;PD@ ze6!s9xh#^QI`J+%8*=^(-!P!@9%~buBmN2VSAp@TOo6}C?az+ALP8~&a0FWZk*F5N z^8P8IREnN`N0i@>O0?{i-FoFShYbUB`D7O4HB`Im2{yzXmyrg$k>cY6A@>bf7i3n0 z5y&cf2#`zctT>dz+hNF&+d3g;2)U!#vsb-%LC+pqKRTiiSn#FH#e!bVwR1nAf*TG^ z!RKcCy$P>?Sfq6n<%M{T0I8?p@HlgwC!HoWO>~mT+X<{Ylm+$Vtj9};H3$EB}P2wR$3y!TO#$iY8eO-!}+F&jMu4%E6S>m zB(N4w9O@2=<`WNJay5PwP8javDp~o~xkSbd4t4t8)9jqu@bHmJHq=MV~Pt|(TghCA}fhMS?s-{klV>~=VrT$nsp7mf{?cze~KKOD4 z_1Y!F)*7^W+BBTt1R2h4f1X4Oy2%?=IMhZU8c{qk3xI1=!na*Sg<=A$?K=Y=GUR9@ zQ(ylIm4Lgm>pt#%p`zHxok%vx_=8Fap1|?OM02|N%X-g5_#S~sT@A!x&8k#wVI2lo z1Uyj{tDQRpb*>c}mjU^gYA9{7mNhFAlM=wZkXcA#MHXWMEs^3>p9X)Oa?dx7b%N*y zLz@K^%1JaArjgri;8ptNHwz1<0y8tcURSbHsm=26^@CYJ3hwMaEvC7 z3Wi-@AaXIQ)%F6#i@%M>?Mw7$6(kW@?et@wbk-APcvMCC{>iew#vkZej8%9h0JSc? zCb~K|!9cBU+))^q*co(E^9jRl7gR4Jihyqa(Z(P&ID#TPyysVNL7(^;?Gan!OU>au zN}miBc&XX-M$mSv%3xs)bh>Jq9#aD_l|zO?I+p4_5qI0Ms*OZyyxA`sXcyiy>-{YN zA70%HmibZYcHW&YOHk6S&PQ+$rJ3(utuUra3V0~@=_~QZy&nc~)AS>v&<6$gErZC3 zcbC=eVkV4Vu0#}E*r=&{X)Kgq|8MGCh(wsH4geLj@#8EGYa})K2;n z{1~=ghoz=9TSCxgzr5x3@sQZZ0FZ+t{?klSI_IZa16pSx6*;=O%n!uXVZ@1IL;JEV zfOS&yyfE9dtS*^jmgt6>jQDOIJM5Gx#Y2eAcC3l^lmoJ{o0T>IHpECTbfYgPI4#LZq0PKqnPCD}_ zyKxz;(`fE0z~nA1s?d{X2!#ZP8wUHzFSOoTWQrk%;wCnBV_3D%3@EC|u$Ao)tO|AO z$4&aa!wbf}rbNcP{6=ajgg(`p5kTeu$ji20`zw)X1SH*x zN?T36{d9TY*S896Ijc^!35LLUByY4QO=ARCQ#MMCjudFc7s!z%P$6DESz%zZ#>H|i zw3Mc@v4~{Eke;FWs`5i@ifeYPh-Sb#vCa#qJPL|&quSKF%sp8*n#t?vIE7kFWjNFh zJC@u^bRQ^?ra|%39Ux^Dn4I}QICyDKF0mpe+Bk}!lFlqS^WpYm&xwIYxUoS-rJ)N9 z1Tz*6Rl9;x`4lwS1cgW^H_M*)Dt*DX*W?ArBf?-t|1~ge&S}xM0K;U9Ibf{okZHf~ z#4v4qc6s6Zgm8iKch5VMbQc~_V-ZviirnKCi*ouN^c_2lo&-M;YSA>W>>^5tlXObg zacX$k0=9Tf$Eg+#9k6yV(R5-&F{=DHP8!yvSQ`Y~XRnUx@{O$-bGCksk~3&qH^dqX zkf+ZZ?Nv5u>LBM@2?k%k&_aUb5Xjqf#!&7%zN#VZwmv65ezo^Y4S#(ed0yUn4tFOB zh1f1SJ6_s?a{)u6VdwUC!Hv=8`%T9(^c`2hc9nt$(q{Dm2X)dK49ba+KEheQ;7^0) ziFKw$%EHy_B1)M>=yK^=Z$U-LT36yX>EKT zvD8IAom2&2?bTmX@_PBR4W|p?6?LQ+&UMzXxqHC5VHzf@Eb1u)kwyfy+NOM8Wa2y@ zNNDL0PE$F;yFyf^jy&RGwDXQwYw6yz>OMWvJt98X@;yr!*RQDBE- zE*l*u=($Zi1}0-Y4lGaK?J$yQjgb+*ljUvNQ!;QYAoCq@>70=sJ{o{^21^?zT@r~hhf&O;Qiq+ ziGQQLG*D@5;LZ%09mwMiE4Q{IPUx-emo*;a6#DrmWr(zY27d@ezre)Z1BGZdo&pXn z+);gOFelKDmnjq#8dL7CTiVH)dHOqWi~uE|NM^QI3EqxE6+_n>IW67~UB#J==QOGF zp_S)c8TJ}uiaEiaER}MyB(grNn=2m&0yztA=!%3xUREyuG_jmadN*D&1nxvjZ6^+2 zORi7iX1iPi$tKasppaR9$a3IUmrrX)m*)fg1>H+$KpqeB*G>AQV((-G{}h=qItj|d zz~{5@{?&Dab6;0c7!!%Se>w($RmlG7Jlv_zV3Ru8b2rugY0MVPOOYGlokI7%nhIy& z-B&wE=lh2dtD!F?noD{z^O1~Tq4MhxvchzuT_oF3-t4YyA*MJ*n&+1X3~6quEN z@m~aEp=b2~mP+}TUP^FmkRS_PDMA{B zaSy(P=$T~R!yc^Ye0*pl5xcpm_JWI;@-di+nruhqZ4gy7cq-)I&s&Bt3BkgT(Zdjf zTvvv0)8xzntEtp4iXm}~cT+pi5k{w{(Z@l2XU9lHr4Vy~3ycA_T?V(QS{qwt?v|}k z_ST!s;C4!jyV5)^6xC#v!o*uS%a-jQ6< z)>o?z7=+zNNtIz1*F_HJ(w@=`E+T|9TqhC(g7kKDc8z~?RbKQ)LRMn7A1p*PcX2YR zUAr{);~c7I#3Ssv<0i-Woj0&Z4a!u|@Xt2J1>N-|ED<3$o2V?OwL4oQ%$@!zLamVz zB)K&Ik^~GOmDAa143{I4?XUk1<3-k{<%?&OID&>Ud%z*Rkt*)mko0RwC2=qFf-^OV z=d@47?tY=A;=2VAh0mF(3x;!#X!%{|vn;U2XW{(nu5b&8kOr)Kop3-5_xnK5oO_3y z!EaIb{r%D{7zwtGgFVri4_!yUIGwR(xEV3YWSI_+E}Gdl>TINWsIrfj+7DE?xp+5^ zlr3pM-Cbse*WGKOd3+*Qen^*uHk)+EpH-{u@i%y}Z!YSid<}~kA*IRSk|nf+I1N=2 zIKi+&ej%Al-M5`cP^XU>9A(m7G>58>o|}j0ZWbMg&x`*$B9j#Rnyo0#=BMLdo%=ks zLa3(2EinQLXQ(3zDe7Bce%Oszu%?8PO648TNst4SMFvj=+{b%)ELyB!0`B?9R6aO{i-63|s@|raSQGL~s)9R#J#duFaTSZ2M{X z1?YuM*a!!|jP^QJ(hAisJuPOM`8Y-Hzl~%d@latwj}t&0{DNNC+zJARnuQfiN`HQ# z?boY_2?*q;Qk)LUB)s8(Lz5elaW56p&fDH*AWAq7Zrbeq1!?FBGYHCnFgRu5y1jwD zc|yBz+UW|X`zDsc{W~8m$sh@VVnZD$lLnKlq@Hg^;ky!}ZuPdKNi2BI70;hrpvaA4+Q_+K)I@|)q1N-H zrycZU`*YUW``Qi^`bDX-j7j^&bO+-Xg$cz2#i##($uyW{Nl&{DK{=lLWV3|=<&si||2)l=8^8_z+Vho-#5LB0EqQ3v5U#*DF7 zxT)1j^`m+lW}p$>WSIG1eZ>L|YR-@Feu!YNWiw*IZYh03mq+2QVtQ}1ezRJM?0PA< z;mK(J5@N8>u@<6Y$QAHWNE};rR|)U_&bv8dsnsza7{=zD1VBcxrALqnOf-qW(zzTn zTAp|pEo#FsQ$~*$j|~Q;$Zy&Liu9OM;VF@#_&*nL!N2hH!Q6l*OeTxq!l>dEc{;Hw zCQni{iN%jHU*C;?M-VUaXxf0FEJ_G=C8)C-wD!DvhY+qQ#FT3}Th8;GgV&AV94F`D ztT6=w_Xm8)*)dBnDkZd~UWL|W=Glu!$hc|1w7_7l!3MAt95oIp4Xp{M%clu&TXehO z+L-1#{mjkpTF@?|w1P98OCky~S%@OR&o75P&ZHvC}Y=(2_{ib(-Al_7aZ^U?s34#H}= zGfFi5%KnFVCKtdO^>Htpb07#BeCXMDO8U}crpe1Gm`>Q=6qB4i=nLoLZ%p$TY=OcP z)r}Et-Ed??u~f09d3Nx3bS@ja!fV(Dfa5lXxRs#;8?Y8G+Qvz+iv7fiRkL3liip}) z&G0u8RdEC9c$$rdU53=MH`p!Jn|DHjhOxHK$tW_pw9wCTf0Eo<){HoN=zG!!Gq4z4 z7PwGh)VNPXW-cE#MtofE`-$9~nmmj}m zlzZscQ2+Jq%gaB9rMgVJkbhup0Ggpb)&L01T=%>n7-?v@I8!Q(p&+!fd+Y^Pu9l+u zek(_$^HYFVRRIFt@0Fp52g5Q#I`tC3li`;UtDLP*rA{-#Yoa5qp{cD)QYhldihWe+ zG~zuaqLY~$-1sjh2lkbXCX;lq+p~!2Z=76cvuQe*Fl>IFwpUBP+d^&E4BGc{m#l%Kuo6#{XGoRyFc%Hqhf|%nYd<;yiC>tyEyk z4I+a`(%%Ie=-*n z-{mg=j&t12)LH3R?@-B1tEb7FLMePI1HK0`Ae@#)KcS%!Qt9p4_fmBl5zhO10n401 zBSfnfJ;?_r{%R)hh}BBNSl=$BiAKbuWrNGQUZ)+0=Mt&5!X*D@yGCSaMNY&@`;^a4 z;v=%D_!K!WXV1!3%4P-M*s%V2b#2jF2bk!)#2GLVuGKd#vNpRMyg`kstw0GQ8@^k^ zuqK5uR<>FeRZ#3{%!|4X!hh7hgirQ@Mwg%%ez8pF!N$xhMNQN((yS(F2-OfduxxKE zxY#7O(VGfNuLv-ImAw5+h@gwn%!ER;*Q+001;W7W^waWT%@(T+5k!c3A-j)a8y11t zx4~rSN0s$M8HEOzkcWW4YbKK9GQez2XJ|Nq?TFy;jmGbg;`m&%U4hIiarKmdTHt#l zL=H;ZHE?fYxKQQXKnC+K!TAU}r086{4m}r()-QaFmU(qWhJlc$eas&y?=H9EYQy8N$8^bni9TpDp zkA^WRs?KgYgjxX4T6?`SMs$`s3vlut(YU~f2F+id(Rf_)$BIMibk9lACI~LA+i7xn z%-+=DHV*0TCTJp~-|$VZ@g2vmd*|2QXV;HeTzt530KyK>v&253N1l}bP_J#UjLy4) zBJili9#-ey8Kj(dxmW^ctorxd;te|xo)%46l%5qE-YhAjP`Cc03vT)vV&GAV%#Cgb zX~2}uWNvh`2<*AuxuJpq>SyNtZwzuU)r@@dqC@v=Ocd(HnnzytN+M&|Qi#f4Q8D=h ziE<3ziFW%+!yy(q{il8H44g^5{_+pH60Mx5Z*FgC_3hKxmeJ+wVuX?T#ZfOOD3E4C zRJsj#wA@3uvwZwHKKGN{{Ag+8^cs?S4N@6(Wkd$CkoCst(Z&hp+l=ffZ?2m%%ffI3 zdV7coR`R+*dPbNx=*ivWeNJK=Iy_vKd`-_Hng{l?hmp=|T3U&epbmgXXWs9ySE|=G zeQ|^ioL}tveN{s72_&h+F+W;G}?;?_s@h5>DX(rp#eaZ!E=NivgLI zWykLKev+}sHH41NCRm7W>K+_qdoJ8x9o5Cf!)|qLtF7Izxk*p|fX8UqEY)_sI_45O zL2u>x=r5xLE%s|d%MO>zU%KV6QKFiEeo12g#bhei4!Hm+`~Fo~4h|BJ)%ENxy9)Up zOxupSf1QZWun=)gF{L0YWJ<(r0?$bPFANrmphJ>kG`&7E+RgrWQi}ZS#-CQJ*i#8j zM_A0?w@4Mq@xvk^>QSvEU|VYQoVI=TaOrsLTa`RZfe8{9F~mM{L+C`9YP9?OknLw| zmkvz>cS6`pF0FYeLdY%>u&XpPj5$*iYkj=m7wMzHqzZ5SG~$i_^f@QEPEC+<2nf-{ zE7W+n%)q$!5@2pBuXMxhUSi*%F>e_g!$T-_`ovjBh(3jK9Q^~OR{)}!0}vdTE^M+m z9QWsA?xG>EW;U~5gEuKR)Ubfi&YWnXV;3H6Zt^NE725*`;lpSK4HS1sN?{~9a4JkD z%}23oAovytUKfRN87XTH2c=kq1)O5(fH_M3M-o{{@&~KD`~TRot-gqg7Q2U2o-iiF}K>m?CokhmODaLB z1p6(6JYGntNOg(s!(>ZU&lzDf+Ur)^Lirm%*}Z>T)9)fAZ9>k(kvnM;ab$ptA=hoh zVgsVaveXbMpm{|4*d<0>?l_JUFOO8A3xNLQOh%nVXjYI6X8h?a@6kDe5-m&;M0xqx z+1U$s>(P9P)f0!{z%M@E7|9nn#IWgEx6A6JNJ(7dk`%6$3@!C!l;JK-p2?gg+W|d- ziEzgk$w7k48NMqg$CM*4O~Abj3+_yUKTyK1p6GDsGEs;}=E_q>^LI-~pym$qhXPJf z2`!PJDp4l(TTm#|n@bN!j;-FFOM__eLl!6{*}z=)UAcGYloj?bv!-XY1TA6Xz;82J zLRaF{8ayzGa|}c--}|^xh)xgX>6R(sZD|Z|qX50gu=d`gEwHqC@WYU7{%<5VOnf9+ zB@FX?|UL%`8EIAe!*UdYl|6wRz6Y>(#8x92$#y}wMeE|ZM2X*c}dKJ^4NIf;Fm zNwzq%QcO?$NR-7`su!*$dlIKo2y(N;qgH@1|8QNo$0wbyyJ2^}$iZ>M{BhBjTdMjK z>gPEzgX4;g3$rU?jvDeOq`X=>)zdt|jk1Lv3u~bjHI=EGLfIR&+K3ldcc4D&Um&04 z3^F*}WaxR(ZyaB>DlmF_UP@+Q*h$&nsOB#gwLt{1#F4i-{A5J@`>B9@{^i?g_Ce&O z<<}_We-RUFU&&MHa1#t56u_oM(Ljn7djja!T|gcxSoR=)@?owC*NkDarpBj=W4}=i1@)@L|C) zQKA+o<(pMVp*Su(`zBC0l1yTa$MRfQ#uby|$mlOMs=G`4J|?apMzKei%jZql#gP@IkOaOjB7MJM=@1j(&!jNnyVkn5;4lvro1!vq ztXiV8HYj5%)r1PPpIOj)f!>pc^3#LvfZ(hz}C@-3R(Cx7R427*Fwd!XO z4~j&IkPHcBm0h_|iG;ZNrYdJ4HI!$rSyo&sibmwIgm1|J#g6%>=ML1r!kcEhm(XY& zD@mIJt;!O%WP7CE&wwE3?1-dt;RTHdm~LvP7K`ccWXkZ0kfFa2S;wGtx_a}S2lslw z$<4^Jg-n#Ypc(3t2N67Juasu=h)j&UNTPNDil4MQMTlnI81kY46uMH5B^U{~nmc6+ z9>(lGhhvRK9ITfpAD!XQ&BPphL3p8B4PVBN0NF6U49;ZA0Tr75AgGw7(S=Yio+xg_ zepZ*?V#KD;sHH+15ix&yCs0eSB-Z%D%uujlXvT#V$Rz@$+w!u#3GIo*AwMI#Bm^oO zLr1e}k5W~G0xaO!C%Mb{sarxWZ4%Dn9vG`KHmPC9GWZwOOm11XJp#o0-P-${3m4g( z6~)X9FXw%Xm~&99tj>a-ri})ZcnsfJtc10F@t9xF5vq6E)X!iUXHq-ohlO`gQdS&k zZl})3k||u)!_=nNlvMbz%AuIr89l#I$;rG}qvDGiK?xTd5HzMQkw*p$YvFLGyQM!J zNC^gD!kP{A84nGosi~@MLKqWQNacfs7O$dkZtm4-BZ~iA8xWZPkTK!HpA5zr!9Z&+icfAJ1)NWkTd!-9`NWU>9uXXUr;`Js#NbKFgrNhTcY4GNv*71}}T zFJh?>=EcbUd2<|fiL+H=wMw8hbX6?+_cl4XnCB#ddwdG>bki* zt*&6Dy&EIPluL@A3_;R%)shA-tDQA1!Tw4ffBRyy;2n)vm_JV06(4Or&QAOKNZB5f(MVC}&_!B>098R{Simr!UG}?CW1Ah+X+0#~0`X)od zLYablwmFxN21L))!_zc`IfzWi`5>MxPe(DmjjO1}HHt7TJtAW+VXHt!aKZk>y6PoMsbDXRJnov;D~Ur~2R_7(Xr)aa%wJwZhS3gr7IGgt%@;`jpL@gyc6bGCVx!9CE7NgIbUNZ!Ur1RHror0~ zr(j$^yM4j`#c2KxSP61;(Tk^pe7b~}LWj~SZC=MEpdKf;B@on9=?_n|R|0q;Y*1_@ z>nGq>)&q!;u-8H)WCwtL&7F4vbnnfSAlK1mwnRq2&gZrEr!b1MA z(3%vAbh3aU-IX`d7b@q`-WiT6eitu}ZH9x#d&qx}?CtDuAXak%5<-P!{a`V=$|XmJ zUn@4lX6#ulB@a=&-9HG)a>KkH=jE7>&S&N~0X0zD=Q=t|7w;kuh#cU=NN7gBGbQTT z;?bdSt8V&IIi}sDTzA0dkU}Z-Qvg;RDe8v>468p3*&hbGT1I3hi9hh~Z(!H}{+>eUyF)H&gdrX=k$aB%J6I;6+^^kn1mL+E+?A!A}@xV(Qa@M%HD5C@+-4Mb4lI=Xp=@9+^x+jhtOc zYgF2aVa(uSR*n(O)e6tf3JEg2xs#dJfhEmi1iOmDYWk|wXNHU?g23^IGKB&yHnsm7 zm_+;p?YpA#N*7vXCkeN2LTNG`{QDa#U3fcFz7SB)83=<8rF)|udrEbrZL$o6W?oDR zQx!178Ih9B#D9Ko$H(jD{4MME&<|6%MPu|TfOc#E0B}!j^MMpV69D#h2`vsEQ{(?c zJ3Lh!3&=yS5fWL~;1wCZ?)%nmK`Eqgcu)O6rD^3%ijcxL50^z?OI(LaVDvfL0#zjZ z2?cPvC$QCzpxpt5jMFp05OxhK0F!Q`rPhDi5)y=-0C} zIM~ku&S@pl1&0=jl+rlS<4`riV~LC-#pqNde@44MB(j%)On$0Ko(@q?4`1?4149Z_ zZi!5aU@2vM$dHR6WSZpj+VboK+>u-CbNi7*lw4K^ZxxM#24_Yc`jvb9NPVi75L+MlM^U~`;a7`4H0L|TYK>%hfEfXLsu1JGM zbh|8{wuc7ucV+`Ys1kqxsj`dajwyM;^X^`)#<+a~$WFy8b2t_RS{8yNYKKlnv+>vB zX(QTf$kqrJ;%I@EwEs{cIcH@Z3|#^S@M+5jsP<^`@8^I4_8MlBb`~cE^n+{{;qW2q z=p1=&+fUo%T{GhVX@;56kH8K_%?X=;$OTYqW1L*)hzelm^$*?_K;9JyIWhsn4SK(| zSmXLTUE8VQX{se#8#Rj*lz`xHtT<61V~fb;WZUpu(M)f#;I+2_zR+)y5Jv?l`CxAinx|EY!`IJ*x9_gf_k&Gx2alL!hK zUWj1T_pk|?iv}4EP#PZvYD_-LpzU!NfcLL%fK&r$W8O1KH9c2&GV~N#T$kaXGvAOl)|T zuF9%6(i=Y3q?X%VK-D2YIYFPH3f|g$TrXW->&^Ab`WT z7>Oo!u1u40?jAJ8Hy`bv}qbgs8)cF0&qeVjD?e+3Ggn1Im>K77ZSpbU*08 zfZkIFcv?y)!*B{|>nx@cE{KoutP+seQU?bCGE`tS0GKUO3PN~t=2u7q_6$l;uw^4c zVu^f{uaqsZ{*a-N?2B8ngrLS8E&s6}Xtv9rR9C^b`@q8*iH)pFzf1|kCfiLw6u{Z%aC z!X^5CzF6qofFJgklJV3oc|Qc2XdFl+y5M9*P8}A>Kh{ zWRgRwMSZ(?Jw;m%0etU5BsWT-Dj-5F;Q$OQJrQd+lv`i6>MhVo^p*^w6{~=fhe|bN z*37oV0kji)4an^%3ABbg5RC;CS50@PV5_hKfXjYx+(DqQdKC^JIEMo6X66$qDdLRc z!YJPSKnbY`#Ht6`g@xGzJmKzzn|abYbP+_Q(v?~~ z96%cd{E0BCsH^0HaWt{y(Cuto4VE7jhB1Z??#UaU(*R&Eo+J`UN+8mcb51F|I|n*J zJCZ3R*OdyeS9hWkc_mA7-br>3Tw=CX2bl(=TpVt#WP8Bg^vE_9bP&6ccAf3lFMgr` z{3=h@?Ftb$RTe&@IQtiJfV;O&4fzh)e1>7seG; z=%mA4@c7{aXeJnhEg2J@Bm;=)j=O=cl#^NNkQ<{r;Bm|8Hg}bJ-S^g4`|itx)~!LN zXtL}?f1Hs6UQ+f0-X6&TBCW=A4>bU0{rv8C4T!(wD-h>VCK4YJk`6C9$by!fxOYw- zV#n+0{E(0ttq_#16B} ze8$E#X9o{B!0vbq#WUwmv5Xz6{(!^~+}sBW{xctdNHL4^vDk!0E}(g|W_q;jR|ZK< z8w>H-8G{%R#%f!E7cO_^B?yFRKLOH)RT9GJsb+kAKq~}WIF)NRLwKZ^Q;>!2MNa|} z-mh?=B;*&D{Nd-mQRcfVnHkChI=DRHU4ga%xJ%+QkBd|-d9uRI76@BT(bjsjwS+r) zvx=lGNLv1?SzZ;P)Gnn>04fO7Culg*?LmbEF0fATG8S@)oJ>NT3pYAXa*vX!eUTDF ziBrp(QyDqr0ZMTr?4uG_Nqs6f%S0g?h`1vO5fo=5S&u#wI2d4+3hWiolEU!=3_oFo zfie?+4W#`;1dd#X@g9Yj<53S<6OB!TM8w8})7k-$&q5(smc%;r z(BlXkTp`C47+%4JA{2X}MIaPbVF!35P#p;u7+fR*46{T+LR8+j25oduCfDzDv6R-hU{TVVo9fz?^N3ShMt!t0NsH)pB zRK8-S{Dn*y3b|k^*?_B70<2gHt==l7c&cT>r`C#{S}J2;s#d{M)ncW(#Y$C*lByLQ z&?+{dR7*gpdT~(1;M(FfF==3z`^eW)=5a9RqvF-)2?S-(G zhS;p(u~_qBum*q}On@$#08}ynd0+spzyVco0%G6;<-i5&016cV5UKzhQ~)fX03|>L z8ej+HzzgVr6_5ZUpa4HW0Ca!=r1%*}Oo;2no&Zz8DfR)L!@r<5 z2viSZpmvo5XqXyAz{Ms7`7kX>fnr1gi4X~7KpznRT0{Xc5Cfz@43PjBMBoH@z_{~( z(Wd}IPJ9hH+%)Fc)0!hrV+(A;76rhtI|YHbEDeERV~Ya>SQg^IvlazFkSK(KG9&{q zkPIR~EeQaaBmwA<20}mBO?)N$(z1@p)5?%}rM| zGF()~Z&Kx@OIDRI$d0T8;JX@vj3^2%pd_+@l9~a4lntZ;AvUIjqIZbuNTR6@hNJoV zk4F;ut)LN4ARuyn2M6F~eg-e#UH%2P;8uPGFW^vq1vj8mdIayFOZo(tphk8C7hpT~ z1Fv8?b_LNR3QD9J+!v=p%}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.ttf b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 zcmd?Sd0-pWwLh*qi$?oCk~i6sWlOeWJC3|4juU5JNSu9hSVACzERcmjLV&P^utNzg zIE4Kr1=5g!SxTX#Ern9_%4&01rlrW`Z!56xXTGQR4C z3vR~wXq>NDx$c~e?;ia3YjJ*$!C>69a?2$lLyhpI!CFfJsP=|`8@K0|bbMpWwVUEygg0=0x_)HeHpGSJagJNLA3c!$EuOV>j$wi! zbo{vZ(s8tl>@!?}dmNHXo)ABy7ohD7_1G-P@SdJWT8*oeyBVYVW9*vn}&VI4q++W;Z+uz=QTK}^C75!`aFYCX# zf7fC2;o`%!huaTNJAB&VWrx=szU=VLhwnbT`vc<#<`4WI6n_x@AofA~2d90o?1L3w z9!I|#P*NQ)$#9aASijuw>JRld^-t)Zhmy|i-`Iam|IWkguaMR%lhi4p~cX-9& zjfbx}yz}s`4-6>D^+6FzihR)Y!GsUy=_MWi_v7y#KmYi-{iZ+s@ekkq!@Wxz!~BQwiI&ti z>hC&iBe2m(dpNVvSbZe3DVgl(dxHt-k@{xv;&`^c8GJY%&^LpM;}7)B;5Qg5J^E${ z7z~k8eWOucjX6)7q1a%EVtmnND8cclz8R1=X4W@D8IDeUGXxEWe&p>Z*voO0u_2!! zj3dT(Ki+4E;uykKi*yr?w6!BW2FD55PD6SMj`OfBLwXL5EA-9KjpMo4*5Eqs^>4&> z8PezAcn!9jk-h-Oo!E9EjX8W6@EkTHeI<@AY{f|5fMW<-Ez-z)xCvW3()Z#x0oydB zzm4MzY^NdpIF9qMp-jU;99LjlgY@@s+=z`}_%V*xV7nRV*Kwrx-i`FzI0BZ#yOI8# z!SDeNA5b6u9!Imj89v0(g$;dT_y|Yz!3V`i{{_dez8U@##|X9A};s^7vEd!3AcdyVlhVk$v?$O442KIM1-wX^R{U7`JW&lPr3N(%kXfXT_`7w^? z=#ntx`tTF|N$UT?pELvw7T*2;=Q-x@KmDUIbLyXZ>f5=y7z1DT<7>Bp0k;eItHF?1 zErzhlD2B$Tm|^7DrxnTYm-tgg`Mt4Eivp5{r$o9e)8(fXBO4g|G^6Xy?y$SM*&V52 z6SR*%`%DZC^w(gOWQL?6DRoI*hBNT)xW9sxvmi@!vI^!mI$3kvAMmR_q#SGn3zRb_ zGe$=;Tv3dXN~9XuIHow*NEU4y&u}FcZEZoSlXb9IBOA}!@J3uovp}yerhPMaiI8|SDhvWVr z^BE&yx6e3&RYqIg;mYVZ*3#A-cDJ;#ms4txEmwm@g^s`BB}KmSr7K+ruIoKs=s|gOXP|2 zb1!)87h9?(+1^QRWb(Vo8+@G=o24gyuzF3ytfsKjTHZJ}o{YznGcTDm!s)DRnmOX} z3pPL4wExoN$kyc2>#J`k+<67sy-VsfbQ-1u+HkyFR?9G`9r6g4*8!(!c65Be-5hUg zZHY$M0k(Yd+DT1*8)G(q)1&tDl=g9H7!bZTOvEEFnBOk_K=DXF(d4JOaH zI}*A3jGmy{gR>s}EQzyJa_q_?TYPNXRU1O;fcV_&TQZhd{@*8Tgpraf~nT0BYktu*n{a~ub^UUqQPyr~yBY{k2O zgV)honv{B_CqY|*S~3up%Wn%7i*_>Lu|%5~j)}rQLT1ZN?5%QN`LTJ}vA!EE=1`So z!$$Mv?6T)xk)H8JTrZ~m)oNXxS}pwPd#);<*>zWsYoL6iK!gRSBB{JCgB28C#E{T? z5VOCMW^;h~eMke(w6vLlKvm!!TyIf;k*RtK)|Q>_@nY#J%=h%aVb)?Ni_By)XNxY)E3`|}_u}fn+Kp^3p4RbhFUBRtGsDyx9Eolg77iWN z2iH-}CiM!pfYDIn7;i#Ui1KG01{3D<{e}uWTdlX4Vr*nsb^>l0%{O?0L9tP|KGw8w z+T5F}md>3qDZQ_IVkQ|BzuN08uN?SsVt$~wcHO4pB9~ykFTJO3g<4X({-Tm1w{Ufo zI03<6KK`ZjqVyQ(>{_aMxu7Zm^ck&~)Q84MOsQ-XS~{6j>0lTl@lMtfWjj;PT{nlZ zIn0YL?kK7CYJa)(8?unZ)j8L(O}%$5S#lTcq{rr5_gqqtZ@*0Yw4}OdjL*kBv+>+@ z&*24U=y{Nl58qJyW1vTwqsvs=VRAzojm&V zEn6=WzdL1y+^}%Vg!ap>x%%nFi=V#wn# zUuheBR@*KS)5Mn0`f=3fMwR|#-rPMQJg(fW*5e`7xO&^UUH{L(U8D$JtI!ac!g(Ze89<`UiO@L+)^D zjPk2_Ie0p~4|LiI?-+pHXuRaZKG$%zVT0jn!yTvvM^jlcp`|VSHRt-G@_&~<4&qW@ z?b#zIN)G(}L|60jer*P7#KCu*Af;{mpWWvYK$@Squ|n-Vtfgr@ZOmR5Xpl;0q~VILmjk$$mgp+`<2jP z@+nW5Oap%fF4nFwnVwR7rpFaOdmnfB$-rkO6T3#w^|*rft~acgCP|ZkgA6PHD#Of| zY%E!3tXtsWS`udLsE7cSE8g@p$ceu*tI71V31uA7jwmXUCT7+Cu3uv|W>ZwD{&O4Nfjjvl43N#A$|FWxId! z%=X!HSiQ-#4nS&smww~iXRn<-`&zc)nR~js?|Ei-cei$^$KsqtxNDZvl1oavXK#Pz zT&%Wln^Y5M95w=vJxj0a-ko_iQt(LTX_5x#*QfQLtPil;kkR|kz}`*xHiLWr35ajx zHRL-QQv$|PK-$ges|NHw8k6v?&d;{A$*q15hz9{}-`e6ys1EQ1oNNKDFGQ0xA!x^( zkG*-ueZT(GukSnK&Bs=4+w|(kuWs5V_2#3`!;f}q?>xU5IgoMl^DNf+Xd<=sl2XvkqviJ>d?+G@Z5nxxd5Sqd$*ENUB_mb8Z+7CyyU zA6mDQ&e+S~w49csl*UePzY;^K)Fbs^%?7;+hFc(xz#mWoek4_&QvmT7Fe)*{h-9R4 zqyXuN5{)HdQ6yVi#tRUO#M%;pL>rQxN~6yoZ)*{{!?jU)RD*oOxDoTjVh6iNmhWNC zB5_{R=o{qvxEvi(khbRS`FOXmOO|&Dj$&~>*oo)bZz%lPhEA@ zQ;;w5eu5^%i;)w?T&*=UaK?*|U3~{0tC`rvfEsRPgR~16;~{_S2&=E{fE2=c>{+y} zx1*NTv-*zO^px5TA|B```#NetKg`19O!BK*-#~wDM@KEllk^nfQ2quy25G%)l72<> zzL$^{DDM#jKt?<>m;!?E2p0l12`j+QJjr{Lx*47Nq(v6i3M&*P{jkZB{xR?NOSPN% zU>I+~d_ny=pX??qjF*E78>}Mgts@_yn`)C`wN-He_!OyE+gRI?-a>Om>Vh~3OX5+& z6MX*d1`SkdXwvb7KH&=31RCC|&H!aA1g_=ZY0hP)-Wm6?A7SG0*|$mC7N^SSBh@MG z9?V0tv_sE>X==yV{)^LsygK2=$Mo_0N!JCOU?r}rmWdHD%$h~~G3;bt`lH& zAuOOZ=G1Mih**0>lB5x+r)X^8mz!0K{SScj4|a=s^VhUEp#2M=^#WRqe?T&H9GnWa zYOq{+gBn9Q0e0*Zu>C(BAX=I-Af9wIFhCW6_>TsIH$d>|{fIrs&BX?2G>GvFc=<8` zVJ`#^knMU~65dWGgXcht`Kb>{V2oo%<{NK|iH+R^|Gx%q+env#Js*(EBT3V0=w4F@W+oLFsA)l7Qy8mx_;6Vrk;F2RjKFvmeq} zro&>@b^(?f))OoQ#^#s)tRL>b0gzhRYRG}EU%wr9GjQ#~Rpo|RSkeik^p9x2+=rUr}vfnQoeFAlv=oX%YqbLpvyvcZ3l$B z5bo;hDd(fjT;9o7g9xUg3|#?wU2#BJ0G&W1#wn?mfNR{O7bq747tc~mM%m%t+7YN}^tMa24O4@w<|$lk@pGx!;%pKiq&mZB z?3h<&w>un8r?Xua6(@Txu~Za9tI@|C4#!dmHMzDF_-_~Jolztm=e)@vG11bZQAs!tFvd9{C;oxC7VfWq377Y(LR^X_TyX9bn$)I765l=rJ%9uXcjggX*r?u zk|0!db_*1$&i8>d&G3C}A`{Fun_1J;Vx0gk7P_}8KBZDowr*8$@X?W6v^LYmNWI)lN92yQ;tDpN zOUdS-W4JZUjwF-X#w0r;97;i(l}ZZT$DRd4u#?pf^e2yaFo zbm>I@5}#8FjsmigM8w_f#m4fEP~r~_?OWB%SGWcn$ThnJ@Y`ZI-O&Qs#Y14To( zWAl>9Gw7#}eT(!c%D0m>5D8**a@h;sLW=6_AsT5v1Sd_T-C4pgu_kvc?7+X&n_fct znkHy(_LExh=N%o3I-q#f$F4QJpy>jZBW zRF7?EhqTGk)w&Koi}QQY3sVh?@e-Z3C9)P!(hMhxmXLC zF_+ZSTQU`Gqx@o(~B$dbr zHlEUKoK&`2gl>zKXlEi8w6}`X3kh3as1~sX5@^`X_nYl}hlbpeeVlj#2sv)CIMe%b zBs7f|37f8qq}gA~Is9gj&=te^wN8ma?;vF)7gce;&sZ64!7LqpR!fy)?4cEZposQ8 zf;rZF7Q>YMF1~eQ|Z*!5j0DuA=`~VG$Gg6B?Om1 z6fM@`Ck-K*k(eJ)Kvysb8sccsFf@7~3vfnC=<$q+VNv)FyVh6ZsWw}*vs>%k3$)9| zR9ek-@pA23qswe1io)(Vz!vS1o*XEN*LhVYOq#T`;rDkgt86T@O`23xW~;W_#ZS|x zvwx-XMb7_!hIte-#JNpFxskMMpo2OYhHRr0Yn8d^(jh3-+!CNs0K2B!1dL$9UuAD= zQ%7Ae(Y@}%Cd~!`h|wAdm$2WoZ(iA1(a_-1?znZ%8h72o&Mm*4x8Ta<4++;Yr6|}u zW8$p&izhdqF=m8$)HyS2J6cKyo;Yvb>DTfx4`4R{ zPSODe9E|uflE<`xTO=r>u~u=NuyB&H!(2a8vwh!jP!yfE3N>IiO1jI>7e&3rR#RO3_}G23W?gwDHgSgekzQ^PU&G5z&}V5GO? zfg#*72*$DP1T8i`S7=P;bQ8lYF9_@8^C(|;9v8ZaK2GnWz4$Th2a0$)XTiaxNWfdq z;yNi9veH!j)ba$9pke8`y2^63BP zIyYKj^7;2don3se!P&%I2jzFf|LA&tQ=NDs{r9fIi-F{-yiG-}@2`VR^-LIFN8BC4 z&?*IvLiGHH5>NY(Z^CL_A;yISNdq58}=u~9!Ia7 zm7MkDiK~lsfLpvmPMo!0$keA$`%Tm`>Fx9JpG^EfEb(;}%5}B4Dw!O3BCkf$$W-dF z$BupUPgLpHvr<<+QcNX*w@+Rz&VQz)Uh!j4|DYeKm5IC05T$KqVV3Y|MSXom+Jn8c zgUEaFW1McGi^44xoG*b0JWE4T`vka7qTo#dcS4RauUpE{O!ZQ?r=-MlY#;VBzhHGU zS@kCaZ*H73XX6~HtHd*4qr2h}Pf0Re@!WOyvres_9l2!AhPiV$@O2sX>$21)-3i+_ z*sHO4Ika^!&2utZ@5%VbpH(m2wE3qOPn-I5Tbnt&yn9{k*eMr3^u6zG-~PSr(w$p> zw)x^a*8Ru$PE+{&)%VQUvAKKiWiwvc{`|GqK2K|ZMy^Tv3g|zENL86z7i<c zW`W>zV1u}X%P;Ajn+>A)2iXZbJ5YB_r>K-h5g^N=LkN^h0Y6dPFfSBh(L`G$D%7c` z&0RXDv$}c7#w*7!x^LUes_|V*=bd&aP+KFi((tG*gakSR+FA26%{QJdB5G1F=UuU&koU*^zQA=cEN9}Vd?OEh| zgzbFf1?@LlPkcXH$;YZe`WEJ3si6&R2MRb}LYK&zK9WRD=kY-JMPUurX-t4(Wy{%` zZ@0WM2+IqPa9D(^*+MXw2NWwSX-_WdF0nMWpEhAyotIgqu5Y$wA=zfuXJ0Y2lL3#ji26-P3Z?-&0^KBc*`T$+8+cqp`%g0WB zTH9L)FZ&t073H4?t=(U6{8B+uRW_J_n*vW|p`DugT^3xe8Tomh^d}0k^G7$3wLgP& zn)vTWiMA&=bR8lX9H=uh4G04R6>C&Zjnx_f@MMY!6HK5v$T%vaFm;E8q=`w2Y}ucJ zkz~dKGqv9$E80NTtnx|Rf_)|3wxpnY6nh3U9<)fv2-vhQ6v=WhKO@~@X57N-`7Ppc zF;I7)eL?RN23FmGh0s;Z#+p)}-TgTJE%&>{W+}C`^-sy{gTm<$>rR z-X7F%MB9Sf%6o7A%ZHReD4R;imU6<9h81{%avv}hqugeaf=~^3A=x(Om6Lku-Pn9i zC;LP%Q7Xw*0`Kg1)X~nAsUfdV%HWrpr8dZRpd-#%)c#Fu^mqo|^b{9Mam`^Zw_@j@ zR&ZdBr3?@<@%4Z-%LT&RLgDUFs4a(CTah_5x4X`xDRugi#vI-cw*^{ncwMtA4NKjByYBza)Y$hozZCpuxL{IP&=tw6ZO52WY3|iwGf&IJCn+u(>icK zZB1~bWXCmwAUz|^<&ysd#*!DSp8}DLNbl5lRFat4NkvItxy;9tpp9~|@ z;JctShv^Iq4(z+y7^j&I?GCdKMVg&jCwtCkc4*@O7HY*veGDBtAIn*JgD$QftP}8= zxFAdF=(S>Ra6(4slk#h%b?EOU-96TIX$Jbfl*_7IY-|R%H zF8u|~hYS-YwWt5+^!uGcnKL~jM;)ObZ#q68ZkA?}CzV-%6_vPIdzh_wHT_$mM%vws9lxUj;E@#1UX?WO2R^41(X!nk$+2oJGr!sgcbn1f^yl1 z#pbPB&Bf;1&2+?};Jg5qgD1{4_|%X#s48rOLE!vx3@ktstyBsDQWwDz4GYlcgu$UJ zp|z_32yN72T*oT$SF8<}>e;FN^X&vWNCz>b2W0rwK#<1#kbV)Cf`vN-F$&knLo5T& z8!sO-*^x4=kJ$L&*h%rQ@49l?7_9IG99~xJDDil00<${~D&;kiqRQqeW5*22A`8I2 z(^@`qZoF7_`CO_e;8#qF!&g>UY;wD5MxWU>azoo=E{kW(GU#pbOi%XAn%?W{b>-bTt&2?G=E&BnK9m0zs{qr$*&g8afR_x`B~o zd#dxPpaap;I=>1j8=9Oj)i}s@V}oXhP*{R|@DAQXzQJekJnmuQ;vL90_)H_nD1g6e zS1H#dzg)U&6$fz0g%|jxDdz|FQN{KJ&Yx0vfuzAFewJjv`pdMRpY-wU`-Y6WQnJ(@ zGVb!-8DRJZvHnRFiR3PG3Tu^nCn(CcZHh7hQvyd7i6Q3&ot86XI{jo%WZqCPcTR0< zMRg$ZE=PQx66ovJDvI_JChN~k@L^Pyxv#?X^<)-TS5gk`M~d<~j%!UOWG;ZMi1af< z+86U0=sm!qAVJAIqqU`Qs1uJhQJA&n@9F1PUrYuW!-~IT>l$I!#5dBaiAK}RUufjg{$#GdQBkxF1=KU2E@N=i^;xgG2Y4|{H>s` z$t`k8c-8`fS7Yfb1FM#)vPKVE4Uf(Pk&%HLe z%^4L>@Z^9Z{ZOX<^e)~adVRkKJDanJ6VBC_m@6qUq_WF@Epw>AYqf%r6qDzQ~AEJ!jtUvLp^CcqZ^G-;Kz3T;O4WG45Z zFhrluCxlY`M+OKr2SeI697btH7Kj`O>A!+2DTEQ=48cR>Gg2^5uqp(+y5Sl09MRl* zp|28!v*wvMd_~e2DdKDMMQ|({HMn3D%%ATEecGG8V9>`JeL)T0KG}=}6K8NiSN5W< z79-ZdYWRUb`T}(b{RjN8>?M~opnSRl$$^gT`B27kMym5LNHu-k;A;VF8R(HtDYJHS zU7;L{a@`>jd0svOYKbwzq+pWSC(C~SPgG~nWR3pBA8@OICK$Cy#U`kS$I;?|^-SBC zBFkoO8Z^%8Fc-@X!KebF2Ob3%`8zlVHj6H;^(m7J35(_bS;cZPd}TY~qixY{MhykQ zV&7u7s%E=?i`}Ax-7dB0ih47w*7!@GBt<*7ImM|_mYS|9_K7CH+i}?*#o~a&tF-?C zlynEu1DmiAbGurEX2Flfy$wEVk7AU;`k#=IQE*6DMWafTL|9-vT0qs{A3mmZGzOyN zcM9#Rgo7WgB_ujU+?Q@Ql?V-!E=jbypS+*chI&zA+C_3_@aJal}!Q54?qsL0In({Ly zjH;e+_SK8yi0NQB%TO+Dl77jp#2pMGtwsgaC>K!)NimXG3;m7y`W+&<(ZaV>N*K$j zLL~I+6ouPk6_(iO>61cIsinx`5}DcKSaHjYkkMuDoVl>mKO<4$F<>YJ5J9A2Vl}#BP7+u~L8C6~D zsk`pZ$9Bz3teQS1Wb|8&c2SZ;qo<#F&gS;j`!~!ADr(jJXMtcDJ9cVi>&p3~{bqaP zgo%s8i+8V{UrYTc9)HiUR_c?cfx{Yan2#%PqJ{%?Wux4J;T$#cumM0{Es3@$>}DJg zqe*c8##t;X(4$?A`ve)e@YU3d2Balcivot{1(ahlE5qg@S-h(mPNH&`pBX$_~HdG48~)$x5p z{>ghzqqn_t8~pY<5?-To>cy^6o~mifr;KWvx_oMtXOw$$d6jddXG)V@a#lL4o%N@A zNJlQAz6R8{7jax-kQsH6JU_u*En%k^NHlvBB!$JAK!cYmS)HkLAkm0*9G3!vwMIWv zo#)+EamIJHEUV|$d|<)2iJ`lqBQLx;HgD}c3mRu{iK23C>G{0Mp1K)bt6OU?xC4!_ zZLqpFzeu&+>O1F>%g-%U^~yRg(-wSp@vmD-PT#bCWy!%&H;qT7rfuRCEgw67V!Qob z&tvPU@*4*$YF#2_>M0(75QxqrJr3Tvh~iDeFhxl=MzV@(psx%G8|I{~9;tv#BBE`l z3)_98eZqFNwEF1h)uqhBmT~mSmT8k$7vSHdR97K~kM)P9PuZdS;|Op4A?O<*%!?h` zn`}r_j%xvffs46x2hCWuo0BfIQWCw9aKkH==#B(TJ%p}p-RuIVzsRlaPL_Co{&R0h zQrqn=g1PGjQg3&sc2IlKG0Io#v%@p>tFwF)RG0ahYs@Zng6}M*d}Xua)+h&?$`%rb z;>M=iMh5eIHuJ5c$aC`y@CYjbFsJnSPH&}LQz4}za9YjDuao>Z^EdL@%saRm&LGQWXs*;FzwN#pH&j~SLhDZ+QzhplV_ij(NyMl z;v|}amvxRddO81LJFa~2QFUs z+Lk zZck)}9uK^buJNMo4G(rSdX{57(7&n=Q6$QZ@lIO9#<3pA2ceDpO_340B*pHlh_y{>i&c1?vdpN1j>3UN-;;Yq?P+V5oY`4Z(|P8SwWq<)n`W@AwcQ?E9 zd5j8>FT^m=MHEWfN9jS}UHHsU`&SScib$qd0i=ky0>4dz5ADy70AeIuSzw#gHhQ_c zOp1!v6qU)@8MY+ zMNIID?(CysRc2uZQ$l*QZVY)$X?@4$VT^>djbugLQJdm^P>?51#lXBkdXglYm|4{L zL%Sr?2f`J+xrcN@=0tiJt(<-=+v>tHy{XaGj7^cA6felUn_KPa?V4ebfq7~4i~GKE zpm)e@1=E;PP%?`vK6KVPKXjUXyLS1^NbnQ&?z>epHCd+J$ktT1G&L~T)nQeExe;0Z zlei}<_ni ztFo}j7nBl$)s_3odmdafVieFxc)m!wM+U`2u%yhJ90giFcU1`dR6BBTKc2cQ*d zm-{?M&%(={xYHy?VCx!ogr|4g5;V{2q(L?QzJGsirn~kWHU`l`rHiIrc-Nan!hR7zaLsPr4uR zG{En&gaRK&B@lyWV@yfFpD_^&z>84~_0Rd!v(Nr%PJhFF_ci3D#ixf|(r@$igZiWw za*qbXIJ_Hm4)TaQ=zW^g)FC6uvyO~Hg-#Z5Vsrybz6uOTF>Rq1($JS`imyNB7myWWpxYL(t7`H8*voI3Qz6mvm z$JxtArLJ(1wlCO_te?L{>8YPzQ})xJlvc5wv8p7Z=HviPYB#^#_vGO#*`<0r%MR#u zN_mV4vaBb2RwtoOYCw)X^>r{2a0kK|WyEYoBjGxcObFl&P*??)WEWKU*V~zG5o=s@ z;rc~uuQQf9wf)MYWsWgPR!wKGt6q;^8!cD_vxrG8GMoFGOVV=(J3w6Xk;}i)9(7*U zwR4VkP_5Zx7wqn8%M8uDj4f1aP+vh1Wue&ry@h|wuN(D2W;v6b1^ z`)7XBZ385zg;}&Pt@?dunQ=RduGRJn^9HLU&HaeUE_cA1{+oSIjmj3z+1YiOGiu-H zf8u-oVnG%KfhB8H?cg%@#V5n+L$MO2F4>XoBjBeX>css^h}Omu#)ExTfUE^07KOQS znMfQY2wz?!7!{*C^)aZ^UhMZf=TJNDv8VrrW;JJ9`=|L0`w9DE8MS>+o{f#{7}B4P z{I34>342vLsP}o=ny1eZkEabr@niT5J2AhByUz&i3Ck0H*H`LRHz;>3C_ru!X+EhJ z6(+(lI#4c`2{`q0o9aZhI|jRjBZOV~IA_km7ItNtUa(Wsr*Hmb;b4=;R(gF@GmsRI`pF+0tmq0zy~wnoJD(LSEwHjTOt4xb0XB-+ z&4RO{Snw4G%gS9w#uSUK$Zbb#=jxEl;}6&!b-rSY$0M4pftat-$Q)*y!bpx)R%P>8 zrB&`YEX2%+s#lFCIV;cUFUTIR$Gn2%F(3yLeiG8eG8&)+cpBlzx4)sK?>uIlH+$?2 z9q9wk5zY-xr_fzFSGxYp^KSY0s%1BhsI>ai2VAc8&JiwQ>3RRk?ITx!t~r45qsMnj zkX4bl06ojFCMq<9l*4NHMAtIxDJOX)H=K*$NkkNG<^nl46 zHWH1GXb?Og1f0S+8-((5yaeegCT62&4N*pNQY;%asz9r9Lfr;@Bl${1@a4QAvMLbV6JDp>8SO^q1)#(o%k!QiRSd0eTmzC< zNIFWY5?)+JTl1Roi=nS4%@5iF+%XztpR^BSuM~DX9q`;Mv=+$M+GgE$_>o+~$#?*y zAcD4nd~L~EsAjXV-+li6Lua4;(EFdi|M2qV53`^4|7gR8AJI;0Xb6QGLaYl1zr&eu zH_vFUt+Ouf4SXA~ z&Hh8K@ms^`(hJfdicecj>J^Aqd00^ccqN!-f-!=N7C1?`4J+`_f^nV!B3Q^|fuU)7 z1NDNT04hd4QqE+qBP+>ZE7{v;n3OGN`->|lHjNL5w40pePJ?^Y6bFk@^k%^5CXZ<+4qbOplxpe)l7c6m%o-l1oWmCx%c6@rx85hi(F=v(2 zJ$jN>?yPgU#DnbDXPkHLeQwED5)W5sH#-eS z%#^4dxiVs{+q(Yd^ShMN3GH)!h!@W&N`$L!SbElXCuvnqh{U7lcCvHI#{ZjwnKvu~ zAeo7Pqot+Ohm{8|RJsTr3J4GjCy5UTo_u_~p)MS&Z5UrUc|+;Mc(YS+ju|m3Y_Dvt zonVtpBWlM718YwaN3a3wUNqX;7TqvAFnVUoD5v5WTh~}r)KoLUDw%8Rrqso~bJqd> z_T!&Rmr6ebpV^4|knJZ%qmzL;OvG3~A*loGY7?YS%hS{2R0%NQ@fRoEK52Aiu%gj( z_7~a}eQUh8PnyI^J!>pxB(x7FeINHHC4zLDT`&C*XUpp@s0_B^!k5Uu)^j_uuu^T> z8WW!QK0SgwFHTA%M!L`bl3hHjPp)|wL5Var_*A1-H8LV?uY5&ou{hRjj>#X@rxV>5%-9hbP+v?$4}3EfoRH;l_wSiz{&1<+`Y5%o%q~4rdpRF0jOsCoLnWY5x?V)0ga>CDo`NpqS) z@x`mh1QGkx;f)p-n^*g5M^zRTHz%b2IkLBY{F+HsjrFC9_H(=9Z5W&Eymh~A_FUJ} znhTc9KG((OnjFO=+q>JQZJbeOoUM77M{)$)qQMcxK9f;=L;IOv_J>*~w^YOW744QZ zoG;!b9VD3ww}OX<8sZ0F##8hvfDP{hpa3HjaLsKbLJ8 z0WpY2E!w?&cWi7&N%bOMZD~o7QT*$xCRJ@{t31~qx~+0yYrLXubXh2{_L699Nl_pn z6)9eu+uUTUdjHXYs#pX^L)AIb!FjjNsTp7C399w&B{Q4q%yKfmy}T2uQdU|1EpNcY zDk~(h#AdxybjfzB+mg6rdU9mDZ^V>|U13Dl$Gj+pAL}lR2a1u!SJXU_YqP9N{ose4 zk+$v}BIHX60WSGVWv;S%zvHOWdDP(-ceo(<8`y@Goy%4wDu>57QZNJc)f>Ls+}9h7 z^N=#3q3|l?aG8K#HwiW2^PJu{v|x5;awYfahC?>_af3$LmMc4%N~JwVlRZa4c+eW2 zE!zosAjOv&UeCeu;Bn5OQUC=jtZjF;NDk9$fGbxf3d29SUBekX1!a$Vmq_VK*MHQ4)eB!dQrHH)LVYNF%-t8!d`@!cb z2CsKs3|!}T^7fSZm?0dJ^JE`ZGxA&a!jC<>6_y67On0M)hd$m*RAzo_qM?aeqkm`* zXpDYcc_>TFZYaC3JV>{>mp(5H^efu!Waa7hGTAts29jjuVd1vI*fEeB?A&uG<8dLZ z(j6;-%vJ7R0U9}XkH)1g>&uptXPHBEA*7PSO2TZ+dbhVxspNW~ZQT3fApz}2 z_@0-lZODcd>dLrYp!mHn4k>>7kibI!Em+Vh*;z}l?0qro=aJt68joCr5Jo(Vk<@i) z5BCKb4p6Gdr9=JSf(2Mgr=_6}%4?SwhV+JZj3Ox^_^OrQk$B^v?eNz}d^xRaz&~ zKVnlLnK#8^y=If2f1zmb~^5lPLe?%l}>?~wN4IN((2~U{e9fKhLMtYFj)I$(y zgnKv?R+ZpxA$f)Q2l=aqE6EPTK=i0sY&MDFJp!vQayyvzh4wee<}kybNthRlX>SHh z7S}9he^EBOqzBCww^duHu!u+dnf9veG{HjW!}aT7aJqzze9K6-Z~8pZAgdm1n~aDs z8_s7?WXMPJ3EPJHi}NL&d;lZP8hDhAXf5Hd!x|^kEHu`6QukXrVdLnq5zbI~oPo?7 z2Cbu8U?$K!Z4_yNM1a(bL!GRe!@{Qom+DxjrJ!B99qu5b*Ma%^&-=6UEbC+S2zX&= zQ!%bgJTvmv^2}hhvNQg!l=kbapAgM^hruE3k@jTxsG(B6d=4thBC*4tzVpCYXFc$a zeqgVB^zua)y-YjpiibCCdU%txXYeNFnXcbNj*D?~)5AGjL+!!ij_4{5EWKGav0^={~M^q}baAFOPzxfUM>`KPf|G z&hsaR*7(M6KzTj8Z?;45zX@L#xU{4n$9Q_<-ac(y4g~S|Hyp^-<*d8+P4NHe?~vfm z@y309=`lGdvN8*jw-CL<;o#DKc-%lb0i9a3%{v&2X($|Qxv(_*()&=xD=5oBg=$B0 zU?41h9)JKvP0yR{KsHoC>&`(Uz>?_`tlLjw1&5tPH3FoB%}j;yffm$$s$C=RHi`I3*m@%CPqWnP@B~%DEe;7ZT{9!IMTo1hT3Q347HJ&!)BM2 z3~aClf>aFh0_9||4G}(Npu`9xYY1*SD|M~9!CCFn{-J$u2&Dg*=5$_nozpoD2nxqq zB!--eA8UWZlcEDp4r#vhZ6|vq^9sFvRnA9HpHch5Mq4*T)oGbruj!U8Lx_G%Lby}o zTQ-_4A7b)5A42vA0U}hUJq6&wQ0J%$`w#ph!EGmW96)@{AUx>q6E>-r^Emk!iCR+X zdIaNH`$}7%57D1FyTccs3}Aq0<0Ei{`=S7*>pyg=Kv3nrqblqZcpsCWSQl^uMSsdj zYzh73?6th$c~CI0>%5@!Ej`o)Xm38u0fp9=HE@Sa6l2oX9^^4|Aq%GA z3(AbFR9gA_2T2i%Ck5V2Q2WW-(a&(j#@l6wE4Z`xg#S za#-UWUpU2U!TmIo`CN0JwG^>{+V#9;zvx;ztc$}@NlcyJr?q(Y`UdW6qhq!aWyB5xV1#Jb{I-ghFNO0 zFU~+QgPs{FY1AbiU&S$QSix>*rqYVma<-~s%ALhFyVhAYepId1 zs!gOB&weC18yhE-v6ltKZMV|>JwTX+X)Y_EI(Ff^3$WTD|Ea-1HlP;6L~&40Q&5{0 z$e$2KhUgH8ucMJxJV#M%cs!d~#hR^nRwk|uuCSf6irJCkSyI<%CR==tftx6d%;?ef zYIcjZrP@APzbtOeUe>m-TW}c-ugh+U*RbL1eIY{?>@8aW9bb1NGRy@MTse@>= za%;5=U}X%K2tKTYe9gjMcBvX%qrC&uZ`d(t)g)X8snf?vBe3H%dG=bl^rv8Z@YN$gd9yveHY0@Wt0$s zh^7jCp(q+6XDoekb;=%y=Wr8%6;z0ANH5dDR_VudDG|&_lYykJaiR+(y{zpR=qL3|2e${8 z2V;?jgHj7}Kl(d8C9xWRjhpf_)KOXl+@c4wrHy zL3#9U(`=N59og2KqVh>nK~g9>fX*PI0`>i;;b6KF|8zg+k2hViCt}4dfMdvb1NJ-Rfa7vL2;lPK{Lq*u`JT>S zoM_bZ_?UY6oV6Ja14X^;LqJPl+w?vf*C!nGK;uU^0GRN|UeFF@;H(Hgp8x^|;ygh? zIZx3DuO(lD01ksanR@Mn#lti=p28RTNYY6yK={RMFiVd~k8!@a&^jicZ&rxD3CCI! zVb=fI?;c#f{K4Pp2lnb8iF2mig)|6JEmU86Y%l}m>(VnI*Bj`a6qk8QL&~PFDxI8b z2mcsQBe9$q`Q$LfG2wdvK`M1}7?SwLAV&)nO;kAk`SAz%x9CDVHVbUd$O(*aI@D|s zLxJW7W(QeGpQY<$dSD6U$ja(;Hb3{Zx@)*fIQaW{8<$KJ&fS0caI2Py^clOq9@Irt z7th7F?7W`j{&UmM==Lo~T&^R7A?G=K_e-zfTX|)i`pLitlNE(~tq*}sS1x2}Jlul6 z5+r#4SpQu8h{ntIv#qCVH`uG~+I8l+7ZG&d`Dm!+(rZQDV*1LS^WfH%-!5aTAxry~ z4xl&rot5ct{xQ$w$MtVTUi6tBFSJWq2Rj@?HAX1H$eL*fk{Hq;E`x|hghRkipYNyt zKCO=*KSziiVk|+)qQCGrTYH9X!Z0$k{Nde~0Wl`P{}ca%nv<6fnYw^~9dYxTnTZB&&962jX0DM&wy&8fdxX8xeHSe=UU&Mq zRTaUKnQO|A>E#|PUo+F=Q@dMdt`P*6e92za(TH{5C*2I2S~p?~O@hYiT>1(n^Lqqn zqewq3ctAA%0E)r53*P-a8Ak32mGtUG`L^WVcm`QovX`ecB4E9X60wrA(6NZ7z~*_DV_e z8$I*eZ8m=WtChE{#QzeyHpZ%7GwFHlwo2*tAuloI-j2exx3#x7EL^&D;Re|Kj-XT- zt908^soV2`7s+Hha!d^#J+B)0-`{qIF_x=B811SZlbUe%kvPce^xu7?LY|C z@f1gRPha1jq|=f}Se)}v-7MWH9)YAs*FJ&v3ZT9TSi?e#jarin0tjPNmxZNU_JFJG z+tZi!q)JP|4pQ)?l8$hRaPeoKf!3>MM-bp06RodLa*wD=g3)@pYJ^*YrwSIO!SaZo zDTb!G9d!hb%Y0QdYxqNSCT5o0I!GDD$Z@N!8J3eI@@0AiJmD7brkvF!pJGg_AiJ1I zO^^cKe`w$DsO|1#^_|`6XTfw6E3SJ(agG*G9qj?JiqFSL|6tSD6vUwK?Cwr~gg)Do zp@$D~7~66-=p4`!!UzJDKAymb!!R(}%O?Uel|rMH>OpRGINALtg%gpg`=}M^Q#V5( zMgJY&gF)+;`e38QHI*c%B}m94o&tOfae;og&!J2;6ENW}QeL73jatbI1*9X~y=$Dm%6FwDcnCyMRL}zo`0=y7=}*Uw zo3!qZncAL{HCgY!+}eKr{P8o27ye+;qJP;kOB%RpSesGoHLT6tcYp*6v~Z9NCyb6m zP#qds0jyqXX46qMNhXDn3pyIxw2f_z;L_X9EIB}AhyC`FYI}G3$WnW>#NMy{0aw}nB%1=Z4&*(FaCn5QG(zvdG^pQRU25;{wwG4h z@kuLO0F->{@g2!;NNd!PfqM-;@F0;&wK}0fT9UrH}(8A5I zt33(+&U;CLN|8+71@g z(s!f-kZZZILUG$QXm9iYiE*>2w;gpM>lgM{R9vT3q>qI{ELO2hJHVi`)*jzOk$r)9 zq}$VrE0$GUCm6A3H5J-=Z9i*biw8ng zi<1nM0lo^KqRY@Asucc#DMmWsnCS;5uPR)GL3pL=-IqSd>4&D&NKSGHH?pG;=Xo`w zw~VV9ddkwbp~m>9G0*b?j7-0fOwR?*U#BE#n7A=_fDS>`fwatxQ+`FzhBGQUAyIRZ??eJt46vHBlR>9m!vfb6I)8!v6TmtZ%G6&E|1e zOtx5xy%yOSu+<9Ul5w5N=&~4Oph?I=ZKLX5DXO(*&Po>5KjbY7s@tp$8(fO|`Xy}Y z;NmMypLoG7r#Xz4aHz7n)MYZ7Z1v;DFHLNV{)to;(;TJ=bbMgud96xRMME#0d$z-S z-r1ROBbW^&YdQWA>U|Y>{whex#~K!ZgEEk=LYG8Wqo28NFv)!t!~}quaAt}I^y-m| z8~E{9H2VnyVxb_wCZ7v%y(B@VrM6lzk~|ywCi3HeiSV`TF>j+Ijd|p*kyn;=mqtf8&DK^|*f+y$38+9!sis9N=S)nINm9=CJ<;Y z!t&C>MIeyou4XLM*ywT_JuOXR>VkpFwuT9j5>667A=CU*{TBrMTgb4HuW&!%Yt`;#md7-`R`ouOi$rEd!ErI zo#>qggAcx?C7`rQ2;)~PYCw%CkS(@EJHZ|!!lhi@Dp$*n^mgrrImsS~(ioGak>3)w zvop0lq@IISuA0Ou*#1JkG{U>xSQV1e}c)!d$L1plFX5XDXX5N7Ns{kT{y5|6MfhBD+esT)e7&CgSW8FxsXTAY=}?0A!j_V9 zJ;IJ~d%av<@=fNPJ9)T3qE78kaz64E>dJaYab5uaU`n~Zdp2h{8DV%SKE5G^$LfuOTRRjB;TnT(Jk$r{Pfe4CO!SM_7d)I zquW~FVCpSycJ~c*B*V8?Qqo=GwU8CkmmLFugfHQ7;A{yCy1OL-+X=twLYg9|H=~8H znnN@|tCs^ZLlCBl5wHvYF}2vo>a6%mUWpTds_mt*@wMN4-r`%NTA%+$(`m6{MNpi@ zMx)8f>U4hd!row@gM&PVo&Hx+lV@$j9yWTjTue zG9n0DP<*HUmJ7ZZWwI2x+{t3QEfr6?T}2iXl=6e0b~)J>X3`!fXd9+2wc1%cj&F@Z zgYR|r5Xd5jy9;YW&=4{-0rJ*L5CgDPj9^3%bp-`HkyBs`j1iTUGD4?WilZ6RO8mIE z+~Joc?GID6K96dyuv(dWREK9Os~%?$$FxswxQsoOi8M?RnL%B~Lyk&(-09D0M?^Jy zWjP)n(b)TF<-|CG%!Vz?8Fu&6iU<>oG#kGcrcrrBlfZMVl0wOJvsq%RL9To%iCW@)#& zZAJWhgzYAq)#NTNb~3GBcD%ZZOc43!YWSyA7TD6xkk)n^FaRAz73b}%9d&YisBic(?mv=Iq^r%Ug zzHq-rRrhfOOF+yR=AN!a9*Rd#sM9ONt5h~w)yMP7Dl9lfpi$H0%GPW^lS4~~?vI8Z z%^ToK#NOe0ExmUsb`lLO$W*}yXNOxPe@zD*90uTDULnH6C?InP3J=jYEO2d)&e|mP z1DSd0QOZeuLWo*NqZzopA+LXy9)fJC00NSX=_4Mi1Z)YyZVC>C!g}cY(Amaj%QN+bev|Xxd2OPD zk!dfkY6k!(sDBvsFC2r^?}hb81(WG5Lt9|riT`2?P;B%jaf5UX<~OJ;uAL$=Ien+V zC!V8u0v?CUa)4*Q+Q_u zkx{q;NjLcvyMuU*{+uDsCQ4U{JLowYby-tn@hatL zy}X>9y08#}oytdn^qfFesF)Tt(2!XGw#r%?7&zzFFh2U;#U9XBO8W--#gOpfbJ`Ey z|M8FCKlWQrOJwE;@Sm02l9OBr7N}go4V8ur)}M@m2uWjggb)DC4s`I4d7_8O&E(j; z?3$9~R$QDxNM^rNh9Y;6P7w+bo2q}NEd6f&_raor-v`UCaTM3TT8HK2-$|n{N@U>_ zL-`P7EXoEU5JRMa)?tNUEe8XFis+w8g9k(QQ)%?&Oac}S`2V$b?%`DwXBgja&&fR@ zH_XidF$p1wA)J|Wk1;?lCl?fgc)=TB3>Y8;BoMqHwJqhL)Tgydv9(?(TBX)fq%=~C zmLj!iX-kn7QA(9snzk0LRf<%SzO&~IhLor6A3f*U^UcoAygRe!H#@UCv$JUP&vPxs zeDj$1%#<2T1!e|!7xI+~_VXLl5|jHqvOhU7ZDUGee;HnkcPP=_k_FFxPjXg*9KyI+ zIh0@+s)1JDSuKMeaDZ3|<_*J8{TUFDLl|mXmY8B>Wj_?4mC#=XjsCKPEO=p0c&t&Z zd1%kHxR#o9S*C?du*}tEHfAC7WetnvS}`<%j=o7YVna)6pw(xzkUi7f#$|^y4WQ{7 zu@@lu=j6xr*11VEIY+`B{tgd(c3zO8%nGk0U^%ec6h)G_`ki|XQXr!?NsQkxzV6Bn1ea9L+@ z(Zr7CU_oXaW>VOdfzENm+FlFQ7Se0ROrNdw(QLvb6{f}HRQ{$Je>(c&rws#{dFI^r zZ4^(`J*G0~Pu_+p5AAh>RRpkcbaS2a?Fe&JqxDTp`dIW9;DL%0wxX5;`KxyA4F{(~_`93>NF@bj4LF!NC&D6Zm+Di$Q-tb2*Q z&csGmXyqA%Z9s(AxNO3@Ij=WGt=UG6J7F;r*uqdQa z?7j!nV{8eQE-cwY7L(3AEXF3&V*9{DpSYdyCjRhv#&2johwf{r+k`QB81%!aRVN<& z@b*N^xiw_lU>H~@4MWzgHxSOGVfnD|iC7=hf0%CPm_@@4^t-nj#GHMug&S|FJtr?i z^JVrobltd(-?Ll>)6>jwgX=dUy+^n_ifzM>3)an3iOzpG9Tu;+96TP<0Jm_PIqof3 zMn=~M!#Ky{CTN_2f7Y-i#|gW~32RCWKA4-J9sS&>kYpTOx#xVNLCo)A$LUme^fVNH z@^S7VU^UJ0YR8?Oy$^IYuG*bm|g;@aX~i60%`7XLy*AYpYvZ^F^U(!|RW z*C!rJ@+7TGdL=nNd1gv^%B+;Fcr$y)i0!GRsZXRHPs>QVGVR{9r_#&Qd(wL|5;H;> zD>HUw=4CF++&{7$<8G@j*nGjhEO%BQYfjeItp4mPvY*JYb1HKd!{HJ9*)(3%BR%{Pp?AM&*yHAJsW({ivOzj*qS!-7|XEn6@zo z3L*tBT%<4RxoAh>q{0n_JBmgW6&8hx?kL(_^k%VL>?xjAyrKBmSl`$=V|SK}ELl}@ zd|d0eo#RfG`bw9SK3%r4Y+rdvc}w}~ixV%tqawbdqvE-WcgE+BUpxMT%F@btm76MG zn=oQRWWuTm+a{dy)Oc2V4yX(@M{QAkx>(QB59*`dLT`Pz3Lsj9iB=HSHAiCq()ns|Cr)1*c605Cx}3V&x}Lg?b+6Q?)z7Kl zQh&1Hx`y6JY-Cwvd*ozeps}a1xAA0CR+Da;+O(i)P1C;SjOI}Dtmf6tPqo-Bl`U78 zv$kYgPntPp@G)n1an9tEoL*Vumu9`>_@I(;+5+fBa-*?fEx=mTEjZ7wq}#@Gd5_cW z!mP{N=yqEntDo)|>oy6{9cu+-3*GTnmb^`O0^FzRPO^&aG`f@F_R*aQ_e{F+_9%NW z4KG_B`@X3EVV9L>?_RNDMddA>w=e0KfAiw5?#i1NFT%Zz#nuv(&!yIU>lVxmzYKQ` zzJ*0w9<&L4aJ6A;0j|_~i>+y(q-=;2Xxhx2v%CYY^{} z^J@LO()eLo|7!{ghQ+(u$wxO*xY#)cL(|miH2_ck2yN{mu4O9=hBW*pM_()-_YdH#Ru{JtwJ^R2}3?!>>m1pohh zrn(!xCjE0Q&EH1QK?zA%sxVh&H99cObJUY$veZhQ)MLu-h%`!*G)s$2k;~+A z)Kk->Ri?`oGDEJEtI*wijm(s5f$W78FH{+qBxiU{~kq((J3uK{m z$|C8K#j-?hm8H@x%VfFqpnvu@xn1s%J7uNZC9C99a<_b1J|mx%)$%!6gPU|~<@2&m zz99GDp`|a%m*iggvfL;4%X;~WY>)@!tMWB@P`)k?$;0x9JSrRI8?s3rlgH(o@`OAo zn{f*gZ#t2u6K??hx|aElOM`Xd0t+SAIUEHvFw%?Wsm$s zUXq{6UU?a>Nc@@Xlb_2k9M1Ctr<#+O?yd}rv z_wu&=_t$!Yngd@N_AUj}T; z#*Ce|%XZr_sQcsWcsl{pCnnj+c8ZNIMmx<;w=-g$Q>BU;9k;w|zQ;4!W32Xg2Cd?{ zvmO3kuKQ^Hv;o>6ZHP8ZJ2`4~Bx?N;cf<0fi=!*G^^WzbTF3e$b&d^qqB{>nqLG81 zs94bBh%|Vj+hLu=!8(b9brJ>ZBns9^6s(gdSVyP9qnu2_I{Sg8j-rloG6{d`De5We zDe5WeY3ga}Y3ga}Y3ga}Y3ga}Y3ga}d8y~6o|k%F>UpW>rJk31Ug~+N=cS&HdOqs; zsOO`ek9t1p`Kafko{xGy>iMbXr=FjBxZMYc8a#gL`Kjlpo}YSt>iMY`pk9DF0qO*( z6QE9jIsxhgs1u-0kUBx8D@eT{^@7w3QZGooAoYUO3sNscy%6<6)C*BBM7L`dk$Xk%6}eZQXgo#!75P`>Uy*-B{uTLGUy*-B{uTLGUy*-B{uTLG))v8{5gt_uj9!t5)^yb-JtjRGrhi zYInOUNJxNyf_yKX01)K=WP|Si>HqEj|B{eUl?MR<)%<1&{(~)D+NPwKxWqT-@~snp zg9KCz1VTZDiS?UH`PRk1VPM{29cgT9=D?!Wc_@}qzggFv;gb@2cJQAYWWtpEZ7?y@jSVqjx${B5UV@SO|wH<<0; z{><1KdVI%Ki}>~<`46C0AggwUwx-|QcU;iiZ{NZu`ur>hd*|Hb(|6veERqxu=b@5Bab=rqptGxd{QJg!4*-i_$sES~)AB46}Fjg|ea#e@?J}z%CUJ zOsLWRQR1#ng^sD)A4FDuY!iUhzlgfJh(J@BRqd&P#v2B`+saBx>m+M&q7vk-75$NH%T5pi%m z5FX?`2-5l53=a&GkC9^NZCLpN5(DMKMwwab$FDIs?q>4!!xBS}75gX_5;(luk;3Vl zLCLd5a_8`Iyz}K}+#RMwu6DVk3O_-}n>aE!4NaD*sQn`GxY?cHe!Bl9n?u&g6?aKm z-P8z&;Q3gr;h`YIxX%z^o&GZZg1=>_+hP2$$-DnL_?7?3^!WAsY4I7|@K;aL<>OTK zByfjl2PA$T83*LM9(;espx-qB%wv7H2i6CFsfAg<9V>Pj*OpwX)l?^mQfr$*OPPS$ z=`mzTYs{*(UW^ij1U8UfXjNoY7GK*+YHht(2oKE&tfZuvAyoN(;_OF>-J6AMmS5fB z^sY6wea&&${+!}@R1f$5oC-2J>J-A${@r(dRzc`wnK>a7~8{Y-scc|ETOI8 zjtNY%Y2!PI;8-@a=O}+{ap1Ewk0@T`C`q!|=KceX9gK8wtOtIC96}-^7)v23Mu;MH zhKyLGOQMujfRG$p(s`(2*nP4EH7*J57^=|%t(#PwCcW7U%e=8Jb>p6~>RAlY4a*ts=pl}_J{->@kKzxH|8XQ5{t=E zV&o`$D#ZHdv&iZWFa)(~oBh-Osl{~CS0hfM7?PyWUWsr5oYlsyC1cwULoQ4|Y5RHA2*rN+EnFPnu z`Y_&Yz*#550YJwDy@brZU>0pWV^RxRjL221@2ABq)AtA%Cz?+FG(}Yh?^v)1Lnh%D zeM{{3&-4#F9rZhS@DT0E(WRkrG!jC#5?OFjZv*xQjUP~XsaxL2rqRKvPW$zHqHr8Urp2Z)L z+)EvQeoeJ8c6A#Iy9>3lxiH3=@86uiTbnnJJJoypZ7gco_*HvKOH97B? zWiwp>+r}*Zf9b3ImxwvjL~h~j<<3shN8$k-$V1p|96I!=N6VBqmb==Bec|*;HUg?) z4!5#R*(#Fe)w%+RH#y{8&%%!|fQ5JcFzUE;-yVYR^&Ek55AXb{^w|@j|&G z|6C-+*On%j;W|f8mj?;679?!qY86c{(s1-PI2Wahoclf%1*8%JAvRh1(0)5Vu37Iz z`JY?RW@qKr+FMmBC{TC7k@}fv-k8t6iO}4K-i3WkF!Lc=D`nuD)v#Na zA|R*no51fkUN3^rmI;tty#IK284*2Zu!kG13!$OlxJAt@zLU`kvsazO25TpJLbK&;M8kw*0)*14kpf*)3;GiDh;C(F}$- z1;!=OBkW#ctacN=je*Pr)lnGzX=OwgNZjTpVbFxqb;8kTc@X&L2XR0A7oc!Mf2?u9 zcctQLCCr+tYipa_k=;1ETIpHt!Jeo;iy^xqBES^Ct6-+wHi%2g&)?7N^Yy zUrMIu){Jk)luDa@7We5U!$$3XFNbyRT!YPIbMKj5$IEpTX1IOtVP~(UPO2-+9ZFi6 z-$3<|{Xb#@tABt0M0s1TVCWKwveDy^S!!@4$s|DAqhsEv--Z}Dl)t%0G>U#ycJ7cy z^8%;|pg32=7~MJmqlC-x07Sd!2YX^|2D`?y;-$a!rZ3R5ia{v1QI_^>gi(HSS_e%2 zUbdg^zjMBBiLr8eSI^BqXM6HKKg#@-w`a**w(}RMe%XWl3MipvBODo*hi?+ykYq)z ziqy4goZw0@VIUY65+L7DaM5q=KWFd$;W3S!Zi>sOzpEF#(*3V-27N;^pDRoMh~(ZD zJLZXIam0lM7U#)119Hm947W)p3$%V`0Tv+*n=&ybF&}h~FA}7hEpA&1Y!BiYIb~~D z$TSo9#3ee02e^%*@4|*+=Nq6&JG5>zX4k5f?)z*#pI-G(+j|jye%13CUdcSP;rNlY z#Q!X%zHf|V)GWIcEz-=fW6AahfxI~y7w7i|PK6H@@twdgH>D_R@>&OtKl}%MuAQ7I zcpFmV^~w~8$4@zzh~P~+?B~%L@EM3x(^KXJSgc6I=;)B6 zpRco2LKIlURPE*XUmZ^|1vb?w*ZfF}EXvY13I4af+()bAI5V?BRbFp`Sb{8GRJHd* z4S2s%4A)6Uc=PK%4@PbJ<{1R6+2THMk0c+kif**#ZGE)w6WsqH z`r^DL&r8|OEAumm^qyrryd(HQ9olv$ltnVGB{aY?_76Uk%6p;e)2DTvF(;t=Q+|8b zqfT(u5@BP);6;jmRAEV057E*2d^wx@*aL1GqWU|$6h5%O@cQtVtC^isd%gD7PZ_Io z_BDP5w(2*)Mu&JxS@X%%ByH_@+l>y07jIc~!@;Raw)q_;9oy@*U#mCnc7%t85qa4? z%_Vr5tkN^}(^>`EFhag;!MpRh!&bKnveQZAJ4)gEJo1@wHtT$Gs6IpznN$Lk-$NcM z3ReVC&qcXvfGX$I0nfkS$a|Pm%x+lq{WweNc;K>a1M@EAVWs2IBcQPiEJNt}+Ea8~WiapASoMvo(&PdUO}AfC~>ZGzqWjd)4no( ziLi#e3lOU~sI*XPH&n&J0cWfoh*}eWEEZW%vX?YK!$?w}htY|GALx3;YZoo=JCF4@ zdiaA-uq!*L5;Yg)z-_`MciiIwDAAR3-snC4V+KA>&V%Ak;p{1u>{Lw$NFj)Yn0Ms2*kxUZ)OTddbiJM}PK!DM}Ot zczn?EZXhx3wyu6i{QMz_Ht%b?K&-@5r;8b076YDir`KXF0&2i9NQ~#JYaq*}Ylb}^ z<{{6xy&;dQ;|@k_(31PDr!}}W$zF7Jv@f%um0M$#=8ygpu%j(VU-d5JtQwT714#f0z+Cm$F9JjGr_G!~NS@L9P;C1? z;Ij2YVYuv}tzU+HugU=f9b1Wbx3418+xj$RKD;$gf$0j_A&c;-OhoF*z@DhEW@d9o zbQBjqEQnn2aG?N9{bmD^A#Um6SDKsm0g{g_<4^dJjg_l_HXdDMk!p`oFv8+@_v_9> zq;#WkQ!GNGfLT7f8m60H@$tu?p;o_It#TApmE`xnZr|_|cb3XXE)N^buLE`9R=Qbg zXJu}6r07me2HU<)S7m?@GzrQDTE3UH?FXM7V+-lT#l}P(U>Fvnyw8T7RTeP`R579m zj=Y>qDw1h-;|mX-)cSXCc$?hr;43LQt)7z$1QG^pyclQ1Bd!jbzsVEgIg~u9b38;> zfsRa%U`l%did6HzPRd;TK{_EW;n^Ivp-%pu0%9G-z@Au{Ry+EqEcqW=z-#6;-!{WA z;l+xC6Zke>dl+(R1q7B^Hu~HmrG~Kt575mzve>x*cL-shl+zqp6yuGX)DDGm`cid! znlnZY=+a5*xQ=$qM}5$N+o!^(TqTFHDdyCcL8NM4VY@2gnNXF|D?5a558Lb*Yfm4) z_;0%2EF7k{)i(tTvS`l5he^KvW%l&-suPwpIlWB_Za1Hfa$@J!emrcyPpTKKM@NqL z?X_SqHt#DucWm<3Lp}W|&YyQE27zbGP55=HtZmB(k*WZA79f##?TweCt{%5yuc+Kx zgfSrIZI*Y57FOD9l@H0nzqOu|Bhrm&^m_RK6^Z<^N($=DDxyyPLA z+J)E(gs9AfaO`5qk$IGGY+_*tEk0n_wrM}n4G#So>8Dw6#K7tx@g;U`8hN_R;^Uw9JLRUgOQ?PTMr4YD5H7=ryv)bPtl=<&4&% z*w6k|D-%Tg*F~sh0Ns(h&mOQ_Qf{`#_XU44(VDY8b})RFpLykg10uxUztD>gswTH} z&&xgt>zc(+=GdM2gIQ%3V4AGxPFW0*l0YsbA|nFZpN~ih4u-P!{39d@_MN)DC%d1w z7>SaUs-g@Hp7xqZ3Tn)e z7x^sC`xJ{V<3YrmbB{h9i5rdancCEyL=9ZOJXoVHo@$$-%ZaNm-75Z-Ry9Z%!^+STWyv~To>{^T&MW0-;$3yc9L2mhq z;ZbQ5LGNM+aN628)Cs16>p55^T^*8$Dw&ss_~4G5Go63gW^CY+0+Z07f2WB4Dh0^q z-|6QgV8__5>~&z1gq0FxDWr`OzmR}3aJmCA^d_eufde7;d|OCrKdnaM>4(M%4V`PxpCJc~UhEuddx9)@)9qe_|i z)0EA%&P@_&9&o#9eqZCUCbh?`j!zgih5sJ%c4(7_#|Xt#r7MVL&Q+^PQEg3MBW;4T zG^4-*8L%s|A}R%*eGdx&i}B1He(mLygTmIAc^G(9Si zK7e{Ngoq>r-r-zhyygK)*9cj8_%g z)`>ANlipCdzw(raeqP-+ldhyUv_VOht+!w*>Sh+Z7(7(l=9~_Vk ztsM|g1xW`?)?|@m2jyAgC_IB`Mtz(O`mwgP15`lPb2V+VihV#29>y=H6ujE#rdnK` zH`EaHzABs~teIrh`ScxMz}FC**_Ii?^EbL(n90b(F0r0PMQ70UkL}tv;*4~bKCiYm zqngRuGy`^c_*M6{*_~%7FmOMquOEZXAg1^kM`)0ZrFqgC>C%RJvQSo_OAA(WF3{euE}GaeA?tu5kF@#62mM$a051I zNhE>u>!gFE8g#Jj95BqHQS%|>DOj71MZ?EYfM+MiJcX?>*}vKfGaBfQFZ3f^Q-R1# znhyK1*RvO@nHb|^i4Ep_0s{lZwCNa;Ix<{E5cUReguJf+72QRZIc%`9-Vy)D zWKhb?FbluyDTgT^naN%l2|rm}oO6D0=3kfXO2L{tqj(kDqjbl(pYz9DykeZlk4iW5 zER`)vqJxx(NOa;so@buE!389-YLbEi@6rZG0#GBsC+Z0fzT6+d7deYVU;dy!rPXiE zmu73@Jr&~K{-9MVQD}&`)e>yLNWr>Yh8CXae9XqfvVQ&eC_;#zpoaMxZ0GpZz7xjx z`t_Q-F?u=vrRPaj3r<9&t6K=+egimiJ8D4gh-rUYvaVy zG($v+3zk5sMuOhjxkH7bQ}(5{PD3Mg?!@8PkK&w>n7tO8FmAmoF30_#^B~c(Q_`4L zYWOoDVSnK|1=p{+@`Fk^Qb81Xf89_S`RSTzv(a4ID%71nll%{Wad$!CKfeTKkyC?n zCkMKHU#*nz_(tO$M)UP&ZfJ#*q(0Gr!E(l5(ce<3xut+_i8XrK8?Xr7_oeHz(bZ?~8q5q~$Rah{5@@7SMN zx9PnJ-5?^xeW2m?yC_7A#WK*B@oIy*Y@iC1n7lYKj&m7vV;KP4TVll=II)$39dOJ^czLRU>L> z68P*PFMN+WXxdAu=Hyt3g$l(GTeTVOZYw3KY|W0Fk-$S_`@9`K=60)bEy?Z%tT+Iq z7f>%M9P)FGg3EY$ood+v$pdsXvG? zd2q3abeu-}LfAQWY@=*+#`CX8RChoA`=1!hS1x5dOF)rGjX4KFg!iPHZE2E=rv|A} zro(8h38LLFljl^>?nJkc+wdY&MOOlVa@6>vBki#gKhNVv+%Add{g6#-@Z$k*ps}0Y zQ=8$)+Nm||)mVz^aa4b-Vpg=1daRaOU)8@BY4jS>=5n#6abG@(F2`=k-eQ9@u# zxfNFHv=z2w@{p1dzSOgHokX1AUGT0DY4jQI@YMw)EWQ~q5wmR$KQ}Y;(HPMSQCwzu zdli|G?bj(>++CP)yQ4s6YfpDc3KqPmquQSxg%*EnTWumWugbDW5ef%8j-rT#3rJu? z)5n;4b2c*;2LIW%LmvUu6t1~di~}0&Svy}QX#ER|hDFZwl!~zUP&}B1oKAxIzt~so zb!GaJYOb#&qRUjEI1xe_`@7qv_-LggQ$JE8+{ryT4%ldwC5ete+{G3C#g@^oxfY3#F zcLlj(l2G8>tC<5XWV|6_DZQZ7ow?MD8EZ9mM2oV~WoV-uoExmbwpzc6eMV}%J_{3l zW(4t2a-o}XRlU|NSiYn!*nR(Sc>*@TuU*(S77gfCi7+WR%2b;4#RiyxWR3(u5BIdf zo@#g4wQjtG3T$PqdX$2z8Zi|QP~I^*9iC+(!;?qkyk&Q7v>DLJGjS44q|%yBz}}>i z&Ve%^6>xY<=Pi9WlwpWB%K10Iz`*#gS^YqMeV9$4qFchMFO}(%y}xs2Hn_E}s4=*3 z+lAeCKtS}9E{l(P=PBI;rsYVG-gw}-_x;KwUefIB@V%RLA&}WU2XCL_?hZHoR<7ED zY}4#P_MmX(_G_lqfp=+iX|!*)RdLCr-1w`4rB_@bI&Uz# z!>9C3&LdoB$r+O#n);WTPi;V52OhNeKfW6_NLnw zpFTuLC^@aPy~ZGUPZr;)=-p|b$-R8htO)JXy{ecE5a|b{{&0O%H2rN&9(VHxmvNly zbY?sVk}@^{aw)%#J}|UW=ucLWs%%j)^n7S%8D1Woi$UT}VuU6@Sd6zc2+t_2IMBxd zb4R#ykMr8s5gKy=v+opw6;4R&&46$V+OOpDZwp3iR0Osqpjx))joB*iX+diVl?E~Q zc|$qmb#T#7Kcal042LUNAoPTPUxF-iGFw>ZFnUqU@y$&s8%h-HGD`EoNBbe#S>Y-4 zlkeAP>62k~-N zHQqXXyN67hGD6CxQIq_zoepU&j0 zYO&}<4cS^2sp!;5))(aAD!KmUED#QGr48DVlwbyft31WlS2yU<1>#VMp?>D1BCFfB z_JJ-kxTB{OLI}5XcPHXUo}x~->VP%of!G_N-(3Snvq`*gX3u0GR&}*fFwHo3-vIw0 zeiWskq3ZT9hTg^je{sC^@+z3FAd}KNhbpE5RO+lsLgv$;1igG7pRwI|;BO7o($2>mS(E z$CO@qYf5i=Zh6-xB=U8@mR7Yjk%OUp;_MMBfe_v1A(Hqk6!D})x%JNl838^ZA13Xu zz}LyD@X2;5o1P61Rc$%jcUnJ>`;6r{h5yrEbnbM$$ntA@P2IS1PyW^RyG0$S2tUlh z8?E(McS?7}X3nAAJs2u_n{^05)*D7 zW{Y>o99!I9&KQdzgtG(k@BT|J*;{Pt*b|?A_})e98pXCbMWbhBZ$t&YbNQOwN^=F) z_yIb_az2Pyya2530n@Y@s>s>n?L79;U-O9oPY$==~f1gXro5Y z*3~JaenSl_I}1*&dpYD?i8s<7w%~sEojqq~iFnaYyLgM#so%_ZZ^WTV0`R*H@{m2+ zja4MX^|#>xS9YQo{@F1I)!%RhM{4ZUapHTKgLZLcn$ehRq(emb8 z9<&Nx*RLcS#)SdTxcURrJhxPM2IBP%I zf1bWu&uRf{60-?Gclb5(IFI*!%tU*7d`i!l@>TaHzYQqH4_Y*6!Wy0d-B#Lz7Rg3l zqKsvXUk9@6iKV6#!bDy5n&j9MYpcKm!vG7z*2&4G*Yl}iccl*@WqKZWQSJCgQSj+d ze&}E1mAs^hP}>`{BJ6lv*>0-ft<;P@`u&VFI~P3qRtufE11+|#Y6|RJccqo27Wzr}Tp|DH z`G4^v)_8}R24X3}=6X&@Uqu;hKEQV^-)VKnBzI*|Iskecw~l?+R|WKO*~(1LrpdJ? z0!JKnCe<|m*WR>m+Qm+NKNH<_yefIml z+x32qzkNRrhR^IhT#yCiYU{3oq196nC3ePkB)f%7X1G^Ibog$ZnYu4(HyHUiFB`6x zo$ty-8pknmO|B9|(5TzoHG|%>s#7)CM(i=M7Nl=@GyDi-*ng6ahK(&-_4h(lyUN-oOa$` zo+P;C4d@m^p9J4c~rbi$rq9nhGxayFjhg+Rqa{l#`Y z!(P6K7fK3T;y!VZhGiC#)|pl$QX?a)a9$(4l(usVSH>2&5pIu5ALn*CqBt)9$yAl; z-{fOmgu><7YJ5k>*0Q~>lq72!XFX6P5Z{vW&zLsraKq5H%Z26}$OKDMv=sim;K?vsoVs(JNbgTU8-M%+ zN(+7Xl}`BDl=KDkUHM9fLlV)gN&PqbyX)$86!Wv!y+r*~kAyjFUKPDWL3A)m$@ir9 zjJ;uQV9#3$*`Dqo1Cy5*;^8DQcid^Td=CivAP+D;gl4b7*xa9IQ-R|lY5tIpiM~9- z%Hm9*vDV@_1FfiR|Kqh_5Ml0sm?abD>@peo(cnhiSWs$uy&$RYcd+m`6%X9FN%?w}s~Q=3!pJzbN~iJ}bbM*PPi@!E0eN zhKcuT=kAsz8TQo76CMO+FW#hr6da({mqpGK2K4T|xv9SNIXZ}a=4_K5pbz1HE6T}9 zbApW~m0C`q)S^F}B9Kw5!eT)Bj_h9vlCX8%VRvMOg8PJ*>PU>%yt-hyGOhjg!2pZR4{ z=VR_*?Hw|aai##~+^H>3p$W@6Zi`o4^iO2Iy=FPdEAI58Ebc~*%1#sh8KzUKOVHs( z<3$LMSCFP|!>fmF^oESZR|c|2JI3|gucuLq4R(||_!8L@gHU8hUQZKn2S#z@EVf3? zTroZd&}JK(mJLe>#x8xL)jfx$6`okcHP?8i%dW?F%nZh=VJ)32CmY;^y5C1^?V0;M z<3!e8GZcPej-h&-Osc>6PU2f4x=XhA*<_K*D6U6R)4xbEx~{3*ldB#N+7QEXD^v=I z+i^L+V7_2ld}O2b-(#bmv*PyZI4|U#Q5|22a(-VLOTZc3!9ns1RI-? zA<~h|tPH0y*bO1#EMrsWN>4yJM7vqFZr?uw$H8*PhiHRQg1U9YoscX-G|gck+SSRX!(e7@~eeUEw+POsT;=W9J&=EV`cUc{PIg_#TQVGnZsQbCs7#Q-)v#BicxLw#Fb?#)8TYbu zN)5R=MI1i7FHhF|X}xEl=sW~`-kf;fOR^h1yjthSw?%#F{HqrY2$q>7!nbw~nZ8q9 zh{vY! z%i=H!!P&wh z7_E%pB7l5)*VU>_O-S~d5Z!+;f{pQ4e86*&);?G<9*Q$JEJ!ZxY;Oj5&@^eg0Zs!iLCAR`2K?MSFzjX;kHD6)^`&=EZOIdW>L#O`J zf~$M4}JiV}v6B-e{NUBGFgj-*H%NG zfY0X(@|S8?V)drF;2OQcpDl2LV=~=%gGx?_$fbSsi@%J~taHcMTLLpjNF8FkjnjyM zW;4sSf6RHaa~LijL#EJ0W2m!BmQP(f=%Km_N@hsBFw%q#7{Er?y1V~UEPEih87B`~ zv$jE%>Ug9&=o+sZVZL7^+sp)PSrS;ZIJac4S-M>#V;T--4FXZ*>CI7w%583<{>tb6 zOZ8gZ#B0jplyTbzto2VOs)s9U%trre`m=RlKf{I_Nwdxn(xNG%zaVNurEYiMV3*g| z``3;{j7`UyfFrjlEbIJN{0db|r>|LA@=vX9CHFZYiexnkn$b%8Rvw0TZOQIXa;oTI zv@j;ZP+#~|!J(aBz9S{wL7W%Dr1H)G-XUNt9-lP?ijJ-XEj1e*CI~-Xz@4(Xg;UoG z{uzBf-U+(SHe}6oG%;A*93Zb=oE>uTb^%qsL>|bQf?7_6=KIiPU`I|r;YcZ!YG7y~ zQu@UldAwz$^|uoz3mz1;An-WVBtefSh-pv<`n&TU3oM!hrEI?l@v8A4#^$4t&~T32 zl*J=1q~h+60sNc43>0aVvhzyfjshgPYZoQ(OOh>LbUIoblb@1z~zp?))n?^)q6WGuDh}gMUaA9|X z3qq-XlcNldy5==T4rq*~g@XVY!9sYZjo#R7 zr{n)r5^S{9+$+8l7IVB*3_k5%-TBY@C%`P@&tZf>82sm#nfw7L%92>nN$663yW!yt zhS>EfLcE_Z)gv-Y^h1;xj(<4nD4GY{C-nWUgQc9cMmH{qpa!uEznrGF^?bbJHApScQ$j>$JZHAX80DdXu z--AMgrA0$Otdd#N9#!cg2Z~N8&lj1d+wDh+^ZObWJ$J)_h(&2#msu>q0B$DEERy{1 zCJN{7M@%#E@8pda`@u!v@{gcT3bA*>g*xYLXlbb&o@1vX*x+l}Voys6o~^_7>#GB| z*r!R%kA9k%J`?m>1tMHB9x$ZRe0$r~ui}X}jOC)9LH=Po*2SLdtf3^4?VKnu2ox&mV~0oDgi` z;9d}P$g~9%ThTK8s}5ow2V4?(-lU*ed8ro|}mU}pk% z;bqB0bx3AOk<0Joeh}Vl@_7Po&C`Cg>>gff>e7fu41U3Ic{JQu1W%+!Gvz3GDO2ixKd;KF6UEw8F_cDAh08gB>@ zaRH2Q96sBJ>`4aXvrF0xPtIWoA1pPsRQtU~xDtnEfTJnl{A9u5pR^K8=UdNq%T8F$)FbN> zgK+_(BF#D>R>kK!M#OT~=@@}3yAYqm33?{Bv?2iBr|-aRK0@uapzuXI)wE0=R@m^7 zQ`wLBn(M*wg!mgmQT1d!@3<2z>~rmDW)KG0*B4>_R6LjiI0^9QT8gtDDT|Lclxppm z+OeL6H3QpearJAB%1ellZ6d*)wBQ(hPbE=%?y6i^uf%`RXm*JW*WQ%>&J+=V(=qf{ zri~yItvTZbII+7S0>4Q0U9@>HnMP$X>8TqAfD(vAh};2P{QK)ik`a6$W$nG<{bR2Ufd!^iE z#1K58$gW!xpeYHeehuhQCXZ9p%N8m zB+l~T_u-Ycr!U>!?xu!!*6rNxq37{`DhMMfY6NpD3Jw zkYQDstvt30Hc_SaZuuMP2YrdW@HsPMbf^Y9lI<9$bnMil2X7`Ba-DGLbzgqP>mxwe zf1&JkDH54D3nLar2KjJ3z`*R+rUABq4;>>4Kjc2iQEj7pVLcZYZ~pteAG4rm1{>PQy=!QiV5G|tVk)53 zP?Azw+N)Yq3zZ`dW7Q9Bq@Y*jSK0<1f`HM;_>GH57pf_S%Ounz_yhTY8lplQSM`xx zU{r-Deqs+*I~sLI$Oq`>i`J1kJ(+yNOYy$_>R3Jfi680<|^u#J@aY%Q>O zqfI~sCbk#3--^zMkV&Yj0D(R^rK}+_npgPr_4^kYuG=pO%$C_7v{s@-{M-P@RL3^<`kO@b=YdKMuccfO1ZW# zeRYE%D~CMAgPlo?T!O6?b|pOZv{iMWb;sN=jF%=?$Iz_5zH?K;aFGU^8l7u%zHgiy z%)~y|k;Es-7YX69AMj^epGX#&^c@pp+lc}kKc`5CjPN4Z$$e58$Yn*J?81%`0~A)D zPg-db*pj-t4-G9>ImW4IMi*v#9z^9VD9h@9t;3jMAUVxt=oor+16yHf{lT|G4 zya6{4#BxFw!!~UTRwXXawKU4iz$$GMY6=Z8VM{2@0{=5A0+A#p6$aT3ubRyWMWPq9 zCEH5(Il0v4e4=Yxg(tDglfYAy!UpC>&^4=x7#6_S&Ktds)a8^`^tp6RnRd{KImB^o z2n=t#>iKx<*evmvoE{+fH#@WXGWs$)Uxrtf?r>AaxV0?kf0o@oDboJ6z0cgP@A$;k>SK1UqC?Q_ zk_I?j74;}uNXhOf_5ZxQSgB4otDEb9JJrX1kq`-o%T>g%M5~xXf!2_4P~K64tKgXq z&KHZ0@!cPvUJG4kw-0;tPo$zJrU-Nop>Uo65Pm|yaNvKjhi7V1g98;^N1~V3% zTR>yWa+X2FJ_wpPwz3i^6AGwOa_VMS-&`*KoKgF2&oR10Jn6{!pvVG@n=Jk@vjNuY zL~P7aDGhg~O9G^!bHi$8?G9v9Gp0cmekYkK;(q=47;~gI>h-kx-ceM{ml$#8KI$4ltyjaqP zki^cyDERloAb)dcDBU4na9C(pfD{P@eBGA}0|Rb)p{ISqi60=^FUEdF!ok{Gs;vb) zfj9(#1QA64w*ud^YsN5&PeiI>c`VioE8h)e}W%S9NMA55Gs zrWL6l+@3CKd@8(UQLTwe12SGWMqRn+j)QZRj*g)Xua)%ayzpqs{pD(WWESJYL3{M$ z%qkpM`jFoqLYVv6{IbCkL?fEiJj$VG=$taup&RL9e{s(Sgse2xVJlw0h74EXJKt2eX|dxz{->0)3W`JN7Bv!rLvRZc z0tAOZ2yVe4g9iq826qXAg`f!*+}(o1;1FDb>kKexumFS40KvK0yH1_@Z=LgWZ+}(Y zwYsa;OLz6tTA%gS=>8$=Z7pLh>|K2QElL)E=Q*(n*H`8R`8={-@4mTD-SWBOYRxV? zmF(-rJB8^Wlp?319rTrh^?QEP?|Msxrv?WbJ-+id+V#F2Y4(JPJ6U9bv+U1cIIH^W z)lg$_=g^Ma>2~Pyd_YOAv29Cb-U6DJO?NxnW7~QP*SmYi*vdUVuW#LWQ_u0`hymZi zaQS3Nb^4`ro$>0G%zbXmr5|D|iq0R<;S@?kr0j5Ruq87-Z1>crx%EzVZ9#U;{?}ti zW2W%*9MQg3Nbh%Ti6LhDd|-aFSgXoPG`mHlUU1iCHr>ru>DX?W_#13(`u*!Plu2OP z6jk=2>BC0l)aw;HCmxoYD1i4b%m$1`DYC_^L~ zIEAnFcHvad=-aO3(_MI=9#`z6-9*_!&$?<%meb5;jGd5Qp=MGf z6BD{%`L#TAOq%z%@*ib95Ey7NbUF=BlszVk3Iu3imD&*91N-ij%hW?W@~2TtdHTfP z#n0@Xd7X8Dyu36n{k#PwQ~T~X7mAO^cNV+z<HO@3X-# z_@rAn$k~(l@kciCC;&Qd*fWRI>=;fL{UPlciNDWyj$bX<#r^(r;EE8wwUVQm&7~QY zCXRj!**r^xybAEPq>h3W$uvI1j=yNIyzkE_D7fpGw)OV{U*Uwm{xB;mEg2(|y|ICd zMdQVqzMb-=XM6|E-a9kNh)^9lY`-DjhhHD1w5lufRcy+QLgJ47!fFne86#F; zX{ufroVBEZJOY?rDo!;Te6aOZ^1SO!dYRxQ*2njyA~dCWawn)>!*k7~>8Ikt&e*0>>V5ZbO|*1+2LFOqVe zXHb!aMk03^h%&9L8GMy7UDI2Kev>V@(R}*Iu6x+!Hn4~D@wj`P%#Hdbf(lK{+DD7f zJ&(v*mhn_e(R$^5L#bM^^Q@-!*b!l|+Xrb(q*MRFJYnrE7*xko!SJOy9LngR2|q5k zY`Ioiu+YBfzF{Labszk-E#*BYQk>$()=xWEGZRKwY)*UxP}0dGuPLZOkNJDI9Hy zFjfwiK6RjhH#rHW#B0(MW}i%V`943<6@Z*Nd^JEP5uZonXm=u%AM>{H^U@&Jy*i0s za_Da^xI6pMtXzHc{e~_ZcnKP*;=YL2Z^RmzDl{dJTk7*}E_h*NvgnhnxVKB59Duh~ zqouS_WoOR*{UvUw_K#OWz;gMracr%8>QQ&V*jv!8)ho;U8}9~8EU{N<=Z_gR%IpMT zbkePUG_afm=#|iIfFmdqkpLMGxY5D$`?I}&T7>TexU@v zkBx09kG)O;09ckj#(_Uov6vv{{HOcr-%H#DUQ@*GzF8Zh{iSM13%fuB%>wjdU@3Nf zlnYE!GTyNrqes|;nLFXfWU*Wg-9wmr=NBd$nCk+H?iwNvcd0Wab^3CT9a`>3V~oWI z9=_H+N-Q=MQ(io4u4mpdQ;k&5FXnKV5M7R`@WJ9h(GrAirO#XXOU{qQpk^B^Vd=Dt{wiqT zg-#j9J~@o%H2;W9mg)o6@*Vo;BSs2*4HAHpDk02mndAsov08R_48zJZ@J)s7+hyCo zy*0L#y)?AqZt-wX%+_Vx`8*A95OLHvs1$k~{h-_N_vov_gHJE=`X>L?5K+ zD?u59=mjtImMvd1GsDytuYp{IyUkW&?h zF>$#`n$~bZ)KN0B$XGeMYh&`;g8 zo_2-koaO6+8O!+L>SpIQbG(i;QW9UJi{Ecewlo?s&D!^>i$|#jaW}#HJuxt|W48=? zb^Y&O$a1s5ddr8DIt!sD!t=y1g(d4GR(s;s-HfV$GXl&m;+sAAxB^rk(3_NjE$p#L z*t4em?tA0d+XwRxN^OQwzbDZMuSE0J1)Ky{mq)^t4bnSl*)s>zNM@mMdtd78&ebHN z`!(|lE5q-p+TsRaNnMXwALaN5QIZ2IUi^Z22tsN5>nvIO+YU}Q*xh6}ee6@rR~<&1 z(PB4z>9ZBUMXZwSMmd9-aKKsmJeJq^G|#JclOh*xf0?^e0(`40nsg1z)(48;4}B_( zGwPI)yo|{oX{dVDL-5-aMGr;~vU1cPtJP5JM(sswz&Q`e<@0?y{YhsO9YK8EYJA;L z>7oG_Mts+(wCBC*Md82#XdKw&J*IizR?9k^rf1r{Ot-&>V^ke{9nI9zavlcNkIJtN z7T>?o|4rENk-?|lewZ(EfdR;%BUrzKJ^UkCpsM)EA9QHBVV8trT&*O(9?FO{MLTFL z=5P0H+T6C^jAuX0k4U;~GM!x`!X2N~3_n?qXY$HI>x@(DHEy&Q3ucT1R6fj28wX!I zC=&d$@bJ_v^%?W2Ngl}e8ww`b%BrN-PzGH;$@B2Ky1?%GMkm#~Okj(-Admyy;qya| zOi73kr_pwt?5Nj3p=&H>81!w#>Agj z(QXx{j0r=pTl>micAI_5vUw<3`Sht?Z}-j2Wx~F8DKCUQrsXl2?W8hur42(F_ zsSJ)_36&x6A|YkY6c<2a94SXbv~d>4CC4nkDPvf9Z5Fys^6^5r0j5=E>Cgy_Dk@tS z%?c}9!qB?t6t8(XMH%le8UeNWp@Nsma~Ql+^3Bo%_npMryeQJz4V=BAqE~T?dejng z3ge{fjCHoNAfYBvsfq;G%VL|j7t z`X0sy1EEgpyD;)tS1x+fnv-?C@glP0{RCW}Ma?3qpoq_&IJAYOy3G#s`rsh5=3>`K zkj``=;|*x5HSjZC zXNvPLh372q;=+6ja|SC!R-`JcL}}wwskajjTUGTpL(1zkN-p?BA2lmf+J3WsB7!k`0Brx8^cLTF9h)r+LZ$vsZo}`OpOs)?c6$hclR!R#MAeh|_DY|9r zy+_3c%IO9h9X?ksp?an&>Lw;QeQ`T-Ku6HaK~H?E9-Z5$cZu{YU;1+-6B$|JD;%!^ zt(4l>F8}a-UkC4YtOxFHckhl4VKr6P$P_O*U!)IDory%}Wz`YeFx6TO{y2Y${SBm?H9cTWV=WWJ z`_*CGso!ZN>l@~_jkeXtV}fczfA{TUkyeD>)i3|NFGcCsBmK3HXp&ol_@GVs7PIpfULy!hi zs+%KYgS%(n7_z_}6)hblk~W#LZ@&2)fwm6xkFP%&Ju|MFWbNiTwy{{g-pV1RK`L&=RE2D z4|g;~vd8xd|teYS%w!IlT4W$&FTrk-hcTADX!P?*f1YWEIRwq$Ys%^(Z9w&HT$>} zsMD#6Df=uJrX!JHP7<>Or;e_Cf=}`!`qR=i8fBj)$6Lxx{HRzd8Tnzd0p>kSps{OG zKJkml>bUj8$u|F=``l(-aMxWBC@CGZ#FXClQZ<4|&%jN}Tkg#q8z)=>Ly{$i0`rjU zvt|QddO&i=91e?h3>s~i;+6{ z8X4i6a1wDLrSuE#W(zhan+U*Zq+8p3a))JFVF4ffaV51K^YgTso~3;Y*NmM; zx8T?y-N0uyWY(8=me-HUC9xtABvX5~%yg+Cp&XF$Bq=OcK6T*D7eZ2EmIoCFWm{$S z1PNw8HDpe5hHeCusN8kdeb&f2#=3M^A~7YwJ7FRrhq*)PG9x?JIAaC{MV}5}g#7R$-Ly%)4=IUkRCGOR|XTMjn&okRmFjaO^YF5^* z@)#MCBOBezD)*xQNxydlUyN?dW{fS(s-T`gv*0BEnk}`BdmrbmPO8q8y(X$AA}*RH%I7Av!~84pudHb&%Q5-j zt?=6x(iR?<^_7X0v6Ys#VAL}dKk^hcjI=|EY;kPcZ_w<*H`_*|N7SacaM1ERD@6ab zg`!iTm7$URV+lpW_{V$ruR&A>jrX68k4x2wo$45}&wf7o<|o(@B!u-L@bKyQBAGwy z4#}UrRAu>^>Vb6k2-th^>WjvP;Nl|i3WrjWv3ISkj{m{eAcQIW^_ndxSX@|8T(ASJ z?_$fcP2u*6uOBk-{d>^ z0vWlfGQMvysI%R=iE|A+!!Nw?C917EU*_$`;;)px?s83CRd3i_jBN)k#nR5t$dJ(+ z_sP;wG@Ad)^(3LRj7q}0b2O(b`|i0~5SYb%Sjk^*5ISZ-Ab+}DGu$-X1n^TF1Ndw_ zF|e*1)cI2%`TR&AW~XpqpFb!=3cHbS>np9hYD_Mr5}y5Y`SY^r7isA2Q4(z zazRQEqWDKT2zIEbjSYdCPi1ZOGz80Nsl}gxO^DWMY0AV<2K&OL{&^6#@L1?lXu#6xSMh%3^5c*}oM6DQGY#(a^@z<&D zF(43I9e&5`h|A$5!+UFuOH0>F3$shBV4`0#M4RSB8=6F0ZgIbq<2LQ$Hh^(kAJu=! zt8ZGXTacD{(3W{V1$j_{Jc)Ka7t6u}ho`4kF+4@t_0!mCBn z)}o%eA}L)_L?=jw6BIfll7tb3n}?*yLt&XADa=rW>qz=_6s9ziOd5sXjil>FVFx3r zf>Feewk0v#W9>Gp4GacTRr>Sd2T6dWi-{YX`v!D)kCWzG5xQB=?es5ON(%nkwUhNl zV>@xkWWWv*N+{e$(SrExvN6BXzU(Hxlx27{VYHf+LpIbTO+Yu(ltMk<;)3A(LU@ytVYFkYvTa79idMtUFhfxx?P!)2F`prNWW#Fub#l>N2s@nh&n_ zA4{#}|AIs9|A4P0ZF%fy=hDN!t#ifH<)4u2kirK~JUpjQ-J+~cXOZI&dIts;P}UeXslP6zKvpEKSN-$y>kJ^nw2tC9bv zo(|lT@?vZ!{_l|d^8Yh)eEBh*5ABh+Lzjw+?V)o z#P-W7361>E(Y4;@`sv;VKn G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff2 b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 zcmV(~K+nH-Pew8T0RR9107h&84*&oF0I^&E07eM_0Rl|`00000000000000000000 z0000#Mn+Uk92y`7U;vDA2m}!b3WBL5f#qcZHUcCAhI9*rFaQJ~1&1OBl~F%;WnyLq z8)b|&?3j;$^FW}&KmNW53flIFARDZ7_Wz%hpoWaWlgHTHEHf()GI0&dMi#DFPaEt6 zCO)z0v0~C~q&0zBj^;=tv8q{$8JxX)>_`b}WQGgXi46R*CHJ}6r+;}OrvwA{_SY+o zK)H-vy{l!P`+NG*`*x6^PGgHH4!dsolgU4RKj@I8Xz~F6o?quCX&=VQ$Q{w01;M0? zKe|5r<_7CD z=eO3*x!r$aX2iFh3;}xNfx0v;SwBfGG+@Z;->HhvqfF4r__4$mU>Dl_1w;-9`~5rF~@!3;r~xP-hZvOfOx)A z#>8O3N{L{naf215f>m=bzbp7_(ssu&cx)Qo-{)!)Yz3A@Z0uZaM2yJ8#OGlzm?JO5gbrj~@)NB4@?>KE(K-$w}{};@dKY#K3+Vi64S<@!Z{(I{7l=!p9 z&kjG^P~0f46i13(w!hEDJga;*Eb z`!n|++@H8VaKG<9>VDh(y89J#=;Z$ei=GnD5TesW#|Wf)^D+9NKN4J3H5PF_t=V+Z zdeo8*h9+8&Zfc?>>1|E4B7MAx)^uy$L>szyXre7W|81fjy+RZ1>Gd}@@${~PCOXo) z$#HZd3)V3@lNGG%(3PyIbvyJTOJAWcN@Uh!FqUkx^&BuAvc)G}0~SKI`8ZZXw$*xP zum-ZdtPciTAUn$XWb6vrS=JX~f5?M%9S(=QsdYP?K%Odn0S0-Ad<-tBtS3W06I^FK z8}d2eR_n!(uK~APZ-#tl@SycxkRJ@5wmypdWV{MFtYBUY#g-Vv?5AEBj1 z`$T^tRKca*sn7gt%s@XUD-t>bij-4q-ilku9^;QJ3Mpc`HJ_EX4TGGQ-Og)`c~qm51<|gp7D@ zp#>Grssv^#A)&M8>ulnDM_5t#Al`#jaFpZ<#YJ@>!a$w@kEZ1<@PGs#L~kxOSz7jj zEhb?;W)eS}0IQQuk4~JT30>4rFJ3!b+77}>$_>v#2FFEnN^%(ls*o80pv0Q>#t#%H z@`Yy-FXQ9ULKh{Up&oA_A4B!(x^9&>i`+T|eD!&QOLVd(_avv-bFX~4^>o{%mzzrg_i~SBnr%DeE|i+^}|8?kaV(Z32{`vA^l!sp15>Z72z52FgXf z^8ZITvJ9eXBT1~iQjW|Q`Fac^ak$^N-vI^*geh5|*CdMz;n16gV_zk|Z7q8tFfCvU zJK^Pptnn0Rc~egGIAK}uv99VZm2WLPezQQ5K<`f zg{8Ll|GioPYfNheMj-7-S87=w4N0WxHP`1V6Y)0M&SkYzVrwp>yfsEF7wj&T0!}dB z)R~gGfP9pOR;GY_e0~K^^oJ-3AT+m~?Al!{>>5gNe17?OWz)$)sMH*xuQiB>FT2{i zQ>6U_8}Ay~r4li;jzG+$&?S12{)+<*k9 z<^SX#xY|jvlvTxt(m~C7{y{3g>7TX#o2q$xQO|fc<%8rE@A3=UW(o?gVg?gDV!0q6O!{MlX$6-Bu_m&0ms66 znWS&zr{O_4O&{2uCLQvA?xC5vGZ}KV1v6)#oTewgIMSnBur0PtM0&{R5t#UEy3I9) z`LVP?3f;o}sz*7g5qdTxJl^gk3>;8%SOPH@B)rmFOJ)m6?PlYa$y=RX%;}KId{m9R#2=LNwosF@OTivgMqxpRGe}5=LtAn?VVl6VWCFLD z7l#^^H8jY~42hR)OoVF#YDW(md!g(&pJ;yMj|UBAQa}UH?ED@%ci=*(q~Opn>kE2Q z_4Kgf|0kEA6ary41A;)^Ku(*nirvP!Y>{FZYBLXLP6QL~vRL+uMlZ?jWukMV*(dsn zL~~KA@jU)(UeoOz^4Gkw{fJsYQ%|UA7i79qO5=DOPBcWlv%pK!A+)*F`3WJ}t9FU3 zXhC4xMV7Z%5RjDs0=&vC4WdvD?Zi5tg4@xg8-GLUI>N$N&3aS4bHrp%3_1u9wqL)i z)XQLsI&{Hd&bQE!3m&D0vd!4D`l1$rt_{3NS?~lj#|$GN5RmvP(j3hzJOk=+0B*2v z)Bw133RMUM%wu_+$vbzOy?yk#kvR?xGsg-ipX4wKyXqd zROKp5))>tNy$HByaEHK%$mqd>-{Yoj`oSBK;w>+eZ&TVcj^DyXjo{DDbZ>vS2cCWB z(6&~GZ}kUdN(*2-nI!hvbnVy@z2E#F394OZD&Jb04}`Tgaj?MoY?1`{ejE2iud51% zQ~J0sijw(hqr_Ckbj@pm$FAVASKY(D4BS0GYPkSMqSDONRaFH+O2+jL{hIltJSJT~e)TNDr(}=Xt7|UhcU9eoXl&QZRR<9WomW%&m)FT~j zTgGd3-j}Uk%CRD;$@X)NNV9+RJbifYu>yr{FkO;p>_&njI> zyBHh_72bW;8}oGeY0gpHOxiV597j7mY<#?WMmkf5x~Kfk*re(&tG_mX<3&2cON*2u%V29tsXUv{#-ijs2>EuNH-x3) zPBpi+V6gI=wn}u164_j8xi-y(B?Au2o;UO=r6&)i5S3Mx*)*{_;u}~i4dh$`VgUS- zMG6t*?DXDYX0D2Oj31MI!HF>|aG8rjrOPnxHu4wZl;!=NGjjDoBpXf?ntrwt^dqxm zs(lE@*QB3NH)!`rH)5kks-D89g@UX&@DU9jvrsY)aI=9b4nPy3bfdX_U;#?zsan{G>DKob2LnhCJv8o}duQK)qP{7iaaf2=K`a-VNcfC582d4a z>sBJA*%S|NEazDxXcGPW_uZ&d7xG`~JB!U>U(}acUSn=FqOA~(pn^!aMXRnqiL0;? zebEZYouRv}-0r;Dq&z9>s#Rt1HL`0p4bB)A&sMyn|rE_9nh z?NO*RrjET8D4s(-`nS{MrdYtv*kyCnJKbsftG2D#ia@;42!8xd?a3P(&Y?vCf9na< zQ&Ni*1Qel&Xq{Z?=%f0SRqQt5m|Myg+8T=GDc)@^};=tM>9IDr7hdvE9-M@@<0pqv45xZTeNecbL- zWFQt4t`9>j8~X%lz}%We>Kzh_=`XO}!;4!OWH?=p*DOs#Nt({k^IvtBEL~Qafn)I^ zm*k{y7_bIs9YE}0B6%r`EIUH8US+MGY!KQA1fi-jCx9*}oz2k1nBsXp;4K<_&SN}}w<)!EylI_)v7}3&c)V;Cfuj*eJ2yc8LK=vugqTL><#65r6%#2e| zdYzZ)9Uq7)A$ol&ynM!|RDHc_7?FlWqjW>8TIHc`jExt)f5W|;D%GC#$u!%B*S%Z0 zsj&;bIU2jrt_7%$=!h4Q29n*A^^AI8R|stsW%O@?i+pN0YOU`z;TVuPy!N#~F8Z29 zzZh1`FU(q31wa>kmw{$q=MY>XBprL<1)Py~5TW4mgY%rg$S=4C^0qr+*A^T)Q)Q-U zGgRb9%MdE-&i#X3xW=I`%xDzAG95!RG9)s?v_5+qx`7NdkQ)If5}BoEp~h}XoeK>kweAMxJ8tehagx~;Nr_WP?jXa zJ&j7%Ef3w*XWf?V*nR)|IOMrX;$*$e23m?QN` zk>sC^GE=h6?*Cr~596s_QE@>Nnr?{EU+_^G=LZr#V&0fEXQ3IWtrM{=t^qJ62Sp=e zrrc>bzX^6yFV!^v7;>J9>j;`qHDQ4uc92eVe6nO@c>H=ouLQot``E~KLNqMqJ7(G+?GWO9Ol+q$w z!^kMv!n{vF?RqLnxVk{a_Ar;^sw0@=+~6!4&;SCh^utT=I zo&$CwvhNOjQpenw2`5*a6Gos6cs~*TD`8H9P4=#jOU_`%L!W;$57NjN%4 z39(61ZC#s7^tv`_4j}wMRT9rgDo*XtZwN-L;Qc$6v8kKkhmRrxSDkUAzGPgJ?}~_t zkwoGS4=6lsD`=RL|8L3O9L()N)lmEn-M15fRC{dhZ}7eYV%O-R^gsAp{q4 z!C1}_T8gy^v@SZ5R&Li5JMJy+K8iZw3LOGA0pN1~y@w7RRl#F()ii6Y5mr~Mdy@Kz z@FT4cm^I&#Fu_9IX(HAFP{XLbRALqm&)>m_we>a`hfv?eE|t z?YdDp2yAhj-~vuw^wzVDuj%w?exOcOT(ls(F*ceCe(C5HlN{lcQ;}|mRPqFDqLEzw zR7ldY+M6xe$$qLwekmk{Z&5cME$gpC?-8)f0m$rqaS|mj9ATNJvvyCgs(f2{r;2E!oy$k5{jik#(;S>do<#m0wVcU<}>)VtYmF9O0%(C>GDzPgh6X z9OkQLMR~y7=|MtaU!LDPPY7O)L{X#SC+M|v^X2CZ?$GS>U_|aC(VA(mIvCNk+biD| zSpj>gd(v>_Cbq>~-x^Y3o|?eHmuC?E&z>;Ij`%{$Pm$hI}bl0Kd`9KD~AchY+goL1?igDxf$qxL9< z4sW@sD)nwWr`T>e2B8MQN|p*DVTT8)3(%AZ&D|@Zh6`cJFT4G^y6`(UdPLY-&bJYJ z*L06f2~BX9qX}u)nrpmHPG#La#tiZ23<>`R@u8k;ueM6 znuSTY7>XEc+I-(VvL?Y>)adHo(cZ;1I7QP^q%hu#M{BEd8&mG_!EWR7ZV_&EGO;d(hGGJzX|tqyYEg2-m0zLT}a{COi$9!?9yK zGN7&yP$a|0gL`dPUt=4d^}?zrLN?HfKP0_gdRvb}1D73Hx!tXq>7{DWPV;^X{-)cm zFa^H5oBDL3uLkaFDWgFF@HL6Bt+_^g~*o*t`Hgy3M?nHhWvTp^|AQDc9_H< zg>IaSMzd7c(Sey;1SespO=8YUUArZaCc~}}tZZX80w%)fNpMExki-qB+;8xVX@dr; z#L52S6*aM-_$P9xFuIui;dN#qZ_MYy^C^hrY;YAMg;K`!ZpKKFc z9feHsool)`tFSS}Su|cL0%F;h!lpR+ym|P>kE-O`3QnHbJ%gJ$dQ_HPTT~>6WNX41 zoDEUpX-g&Hh&GP3koF4##?q*MX1K`@=W6(Gxm1=2Tb{hn8{sJyhQBoq}S>bZT zisRz-xDBYoYxt6--g2M1yh{#QWFCISux}4==r|7+fYdS$%DZ zXVQu{yPO<)Hn=TK`E@;l!09aY{!TMbT)H-l!(l{0j=SEj@JwW0a_h-2F0MZNpyucb zPPb+4&j?a!6ZnPTB>$t`(XSf-}`&+#rI#`GB> zl=$3HORwccTnA2%>$Nmz)u7j%_ywoGri1UXVNRxSf(<@vDLKKxFo;5pTI$R~a|-sQ zd5Rfwj+$k1t0{J`qOL^q>vZUHc7a^`cKKVa{66z?wMuQAfdZBaVVv@-wamPmes$d! z>gv^xx<0jXOz;7HIQS z4RBIFD?7{o^IQ=sNQ-k!ao*+V*|-^I2=UF?{d>bE9avsWbAs{sRE-y`7r zxVAKA9amvo4T}ZAHSF-{y1GqUHlDp4DO9I3mz5h8n|}P-9nKD|$r9AS3gbF1AX=2B zyaK3TbKYqv%~JHKQH8v+%zQ8UVEGDZY|mb>Oe3JD_Z{+Pq%HB+J1s*y6JOlk`6~H) zKt)YMZ*RkbU!GPHzJltmW-=6zqO=5;S)jz{ zFSx?ryqSMxgx|Nhv3z#kFBTuTBHsViaOHs5e&vXZ@l@mVI37<+^KvTE51!pB4Tggq zz!NlRY2ZLno0&6bA|KHPYOMY;;LZG&_lzuLy{@i$&B(}_*~Zk2 z>bkQ7u&Ww%CFh{aqkT{HCbPbRX&EvPRp=}WKmyHc>S_-qbwAr0<20vEoJ(!?-ucjE zKQ+nSlRL^VnOX0h+WcjGb6WI(8;7bsMaHXDb6ynPoOXMlf9nLKre;w*#E_whR#5!! z!^%_+X3eJVKc$fMZP;+xP$~e(CIP1R&{2m+iTQhDoC8Yl@kLM=Wily_cu>7C1wjVU z-^~I0P06ZSNVaN~A`#cSBH2L&tk6R%dU1(u1XdAx;g+5S^Hn9-L$v@p7CCF&PqV{Z?R$}4EJi36+u2JP7l(@fYfP!=e#76LGy^f>~vs0%s*x@X8`|5 zGd6JOHsQ=feES4Vo8%1P_7F5qjiIm#oRT0kO1(?Z_Dk6oX&j=Xd8Klk(;gk3S(ZFnc^8Gc=d;8O-R9tlGyp=2I@1teAZpGWUi;}`n zbJOS_Z2L16nVtDnPpMn{+wR9&yU9~C<-ncppPee`>@1k7hTl5Fn_3_KzQ)u{iJPp3 z)df?Xo%9ta%(dp@DhKuQj4D8=_!*ra#Ib&OXKrsYvAG%H7Kq|43WbayvsbeeimSa= z8~{7ya9ZUAIgLLPeuNmSB&#-`Je0Lja)M$}I41KHb7dQq$wgwX+EElNxBgyyLbA2* z=c1VJR%EPJEw(7!UE?4w@94{pI3E%(acEYd8*Wmr^R7|IM2RZ-RVXSkXy-8$!(iB* zQA`qh2Ze!EY6}Zs7vRz&nr|L60NlIgnO3L*Yz2k2Ivfen?drnVzzu3)1V&-t5S~S? zw#=Sdh>K@2vA25su*@>npw&7A%|Uh9T1jR$mV*H@)pU0&2#Se`7iJlOr$mp79`DKM z5vr*XLrg7w6lc4&S{So1KGKBqcuJ!E|HVFB?vTOjQHi)g+FwJqX@Y3q(qa#6T@3{q zhc@2T-W}XD9x4u+LCdce$*}x!Sc#+rH-sCz6j}0EE`Tk*irUq)y^za`}^1gFnF)C!yf_l_}I<6qfbT$Gc&Eyr?!QwJR~RE4!gKVmqjbI+I^*^ z&hz^7r-dgm@Mbfc#{JTH&^6sJCZt-NTpChB^fzQ}?etydyf~+)!d%V$0faN(f`rJb zm_YaJZ@>Fg>Ay2&bzTx3w^u-lsulc{mX4-nH*A(32O&b^EWmSuk{#HJk}_ULC}SB(L7`YAs>opp9o5UcnB^kVB*rmW6{s0&~_>J!_#+cEWib@v-Ms`?!&=3fDot`oH9v&$f<52>{n2l* z1FRzJ#yQbTHO}}wt0!y8Eh-0*|Um3vjX-nWH>`JN5tWB_gnW%; zUJ0V?_a#+!=>ahhrbGvmvObe8=v1uI8#gNHJ#>RwxL>E^pT05Br8+$@a9aDC1~$@* zicSQCbQcr=DCHM*?G7Hsovk|{$3oIwvymi#YoXeVfWj{Gd#XmnDgzQPRUKNAAI44y z{1WG&rhIR4ipmvBmq$BZ*5tmPIZmhhWgq|TcuR{6lA)+vhj(cH`0;+B^72{&a7ff* zkrIo|pd-Yxm+VVptC@QNCDk0=Re%Sz%ta7y{5Dn9(EapBS0r zLbDKeZepar5%cAcb<^;m>1{QhMzRmRem=+0I3ERot-)gb`i|sII^A#^Gz+x>TW5A& z3PQcpM$lDy`zb%1yf!e8&_>D02RN950KzW>GN6n@2so&Wu09x@PB=&IkIf|zZ1W}P zAKf*&Mo5@@G=w&290aG1@3=IMCB^|G4L7*xn;r3v&HBrD4D)Zg+)f~Ls$7*P-^i#B z4X7ac=0&58j^@2EBZCs}YPe3rqgLAA1L3Y}o?}$%u~)7Rk=LLFbAdSy@-Uw6lv?0K z&P@@M`o2Rll3GoYjotf@WNNjHbe|R?IKVn*?Rzf9v9QoFMq)ODF~>L}26@z`KA82t z43e!^z&WGqAk$Ww8j6bc3$I|;5^BHwt`?e)zf|&+l#!8uJV_Cwy-n1yS0^Q{W*a8B zTzTYL>tt&I&9vzGQUrO?YIm6C1r>eyh|qw~-&;7s7u1achP$K3VnXd8sV8J7ZTxTh z5+^*J5%_#X)XL2@>h(Gmv$@)fZ@ikR$v(2Rax89xscFEi!3_;ORI0dBxw)S{r50qf zg&_a*>2Xe{s@)7OX9O!C?^6fD8tc3bQTq9}fxhbx2@QeaO9Ej+2m!u~+u%Q6?Tgz{ zjYS}bleKcVhW~1$?t*AO^p!=Xkkgwx6OTik*R3~yg^L`wUU9Dq#$Z*iW%?s6pO_f8 zJ8w#u#Eaw7=8n{zJ}C>w{enA6XYHfUf7h)!Qaev)?V=yW{b@-z`hAz;I7^|DoFChP z1aYQnkGauh*ps6x*_S77@z1wwGmF8ky9fMbM$dr*`vsot4uvqWn)0vTRwJqH#&D%g zL3(0dP>%Oj&vm5Re%>*4x|h1J2X*mK5BH1?Nx_#7( zepgF`+n)rHXj!RiipusEq!X81;QQBXlTvLDj=Qub(ha&D=BDx3@-V*d!D9PeXUY?l zwZ0<4=iY!sUj4G>zTS+eYX7knN-8Oynl=NdwHS*nSz_5}*5LQ@=?Yr?uj$`C1m2OR zK`f5SD2|;=BhU#AmaTKe9QaSHQ_DUj1*cUPa*JICFt1<&S3P3zsrs^yUE;tx=x^cmW!Jq!+hohv_B> zPDMT0D&08dC4x@cTD$o1$x%So1Ir(G3_AVQMvQ13un~sP(cEWi$2%5q93E7t{3VJf%K? zuwSyDke~7KuB2?*#DV8YzJw z&}SCDexnUPD!%4|y~7}VzvJ4ch)WT4%sw@ItwoNt(C*RP)h?&~^g##vnhR0!HvIYx z0td2yz9=>t3JNySl*TszmfH6`Ir;ft@RdWs3}!J88UE|gj_GMQ6$ZYphUL2~4OY7} zB*33_bjkRf_@l;Y!7MIdb~bVe;-m78Pz|pdy=O*3kjak63UnLt!{^!!Ljg0rJD3a~ z1Q;y5Z^MF<=Hr}rdoz>yRczx+p3RxxgJE2GX&Si)14B@2t21j4hnnP#U?T3g#+{W+Zb z5s^@>->~-}4|_*!5pIzMCEp|3+i1XKcfUxW`8|ezAh>y{WiRcjSG*asw6;Ef(k#>V ztguN?EGkV_mGFdq!n#W)<7E}1#EZN8O$O|}qdoE|7K?F4zo1jL-v}E8v?9qz(d$&2 zMwyK&xlC9rXo_2xw7Qe0caC?o?Pc*-QAOE!+UvRuKjG+;dk|jQhDDBe?`XT7Y5lte zqSu0t5`;>Wv%|nhj|ZiE^IqA_lZu7OWh!2Y(627zb=r7Ends}wVk7Q5o09a@ojhH7 zU0m&h*8+j4e|OqWyJ&B`V`y=>MVO;K9=hk^6EsmVAGkLT{oUtR{JqSRY{Qi{kKw1k z6s;0SMPJOLp!som|A`*q3t0wIj-=bG8a#MC)MHcMSQU98Juv$?$CvYX)(n`P^!`5| zv3q@@|G@6wMqh;d;m4qvdibx2Yjml}vG9mDv&!0ne02M#D`Bo}xIB0VWh8>>WtNZQ z$&ISlJX;*ORQIO;k62qA{^6P%3!Z=Y1EbmY02{w^yB$`;%!{kur&XTGDiO2cjA)lr zsY^XZWy^DSAaz;kZ_VG?uWnJR7qdN18$~)>(kOoybY0~QYu9||K#|$Mby{3GduV~N zk9H7$7=RSo+?CUYF502`b76ytBy}sFak&|HIwRvB=0D|S`c#QCJPq zP)uOWI)#(n&{6|C4A^G~%B~BY21aOMoz9RuuM`Ip%oBz+NoAlb7?#`E^}7xXo!4S? zFg8I~G%!@nXi8&aJSGFcZAxQf;0m}942=i#p-&teLvE{AKm7Sl2f}Io?!IqbC|J;h z`=5LFOnU5?^w~SV@YwNZx$k_(kLNxZDE z3cf08^-rIT_>A$}B%IJBPcN^)4;90BQtiEi!gT#+EqyAUZ|}*b_}R>SGloq&6?opL zuT_+lwQMgg6!Cso$BwUA;k-1NcrzyE>(_X$B0HocjY~=Pk~Q08+N}(|%HjO_i+*=o z%G6C6A30Ch<0UlG;Zdj@ed!rfUY_i9mYwK8(aYuzcUzlTJ1yPz|Bb-9b33A9zRhGl>Ny-Q#JAq-+qtI@B@&w z$;PJbyiW=!py@g2hAi0)U1v=;avka`gd@8LC4=BEbNqL&K^UAQ5%r95#x%^qRB%KLaqMnG|6xKAm}sx!Qwo}J=2C;NROi$mfADui4)y(3wVA3k~{j^_5%H)C6K zlYAm1eY**HZOj($)xfKIQFtIVw$4&yvz9>(Crs>Gh{ zya6-FG7Dgi92#K)64=9Csj5?Zqe~_9TwSI!2quAwa1w-*uC5!}xY`?tltb0Hq740< zsq2QelPveZ4chr$=~U3!+c&>xyfvA1`)owOqj=i4wjY=A1577Gwg&Ko7;?il9r|_* z8P&IDV_g2D{in5OLFxsO!kx3AhO$5aKeoM|!q|VokqMlYM@HtsRuMtBY%I35#5$+G zpp|JOeoj^U=95HLemB04Yqv{a8X<^K9G2`&ShM_6&Bi1n?o?@MXsDj9Z*A3>#XK%J zRc*&SlFl>l)9DyRQ{*%Z+^e1XpH?0@vhpXrnPPU*d%vOhKkimm-u3c%Q^v3RKp9kx@A2dS?QfS=iigGr7m><)YkV=%LA5h@Uj@9=~ABPMJ z1UE;F&;Ttg5Kc^Qy!1SuvbNEqdgu3*l`=>s5_}dUv$B%BJbMiWrrMm7OXOdi=GOmh zZBvXXK7VqO&zojI2Om9};zCB5i|<210I{iwiGznGCx=FT89=Ef)5!lB1cZ6lbzgDn07*he}G&w7m!;|E(L-?+cz@0<9ZI~LqYQE7>HnPA436}oeN2Y(VfG6 zxNZuMK3Crm^Z_AFeHc~CVRrSl0W^?+Gbteu1g8NGYa3(8f*P{(ZT>%!jtSl6WbYVv zmE(37t0C8vJ6O-5+o*lL9XRcFbd~GSBGbGh3~R!67g&l)7n!kJlWd)~TUyXus#!&G6sR%(l(h1$xyrR5j_jM1zj#giA&@(Xl26@n<9>folx!92bQ z24h570+<)4!$!IQ(5yOU|4_E6aN@4v0+{Kx~Z z;q7fp%0cHziuI%!kB~w}g9@V+1wDz0wFlzX2UOvOy|&;e;t!lAR8tV2KQHgtfk8Uf zw;rs!(4JPODERk4ckd5I2Vq|0rd@@Mwd8MID%0^fITjYIQom^q;qhP8@|eJx{?5xX zc1@Fj*kDknlk{c-rnCloQ3hGh7OU+@efO3>fkRMcM>J?AeVP& zlfzX%cdp=N+4S#E*%^=BQ+N`A7C}|k%$|QUn0yI6S3$MS-NjO!4hm55uyju)Q6e!} z*OVO@A#-mfC9Pha6ng((Xl^V7{d+&u+yx)_B1{~t7d5e8L^i4J>;x<7@5;+l7-Gge zf#9diXJ$&v^rbN5V(ee%q0xBMEgS6%qZm7hNUP%G;^J44I!BmI@M*+FWz0!+s;+iQ zU4CuI+27bvNK8v>?7PZnVxB=heJ&_ymE0nN^W#-rqB%+JXkYGDuRw>JM_LdtLkiq* z6%%3&^BX$jnM@2bjiGc-DymKly)wVkA-pq;jSWL#7_*moZZ4I|-N}o8SK?sIv)p|c zu~9-B%tMc=!)YMFp*SiC0>kfnH8+X5>;+FFVN{~a9YVdIg1uGkZ~kegFy{^PU(4{( z`CbY`XmVA3esai686Yw8djCEyF7`bfB^F1)nwv+AqYLZ&Zy=eFhYT2uMd@{sP_qS4 zbJ&>PxajjZt?&c<1^!T|pLHfX=E^FJ>-l_XCZzvRV%x}@u(FtF(mS+Umw$e+IA74e>gCdTqi;6&=euAIpxd=Y3I5xWR zBhGoT+T`V1@91OlQ}2YO*~P4ukd*TBBdt?Plt)_ou6Y@Db`ss+Q~A-48s>?eaJYA2 zRGOa8^~Em}EFTmKIVVbMb|ob)hJJ7ITg>yHAn2i|{2ZJU!cwt9YNDT0=*WO7Bq#Xj zg@FjEaKoolrF8%c;49|`IT&25?O$dq8kp3#la9&6aH z6G|{>^C(>yP7#Dr$aeFyS0Ai_$ILhL43#*mgEl(c*4?Ae;tRL&S7Vc}Szl>B`mBuI zB9Y%xp%CZwlH!3V(`6W4-ZuETssvI&B~_O;CbULfl)X1V%(H7VSPf`_Ka9ak@8A=z z1l|B1QKT}NLI`WVTRd;2En5u{0CRqy9PTi$ja^inu){LJ&E&6W%JJPw#&PaTxpt?k zpC~gjN*22Q8tpGHR|tg~ye#9a8N<%odhZJnk7Oh=(PKfhYfzLAxdE36r<6a?A;rO&ELp_Y?8Pdw(PT^Fxn!eG_|LEbSYoBrsBA|6Fgr zt5LntyusI{Q2fdy=>ditS;}^B;I2MD4=(>7fWt0Jp~y=?VvfvzHvQhj6dyIef46J$ zl4Xu7U9v_NJV?uBBC0!kcTS0UcrV7+@~is?Fi+jrr@l3XwD|uG zr26jUWiv>Ju48Y^#qn7r9mwIH-Pv6Y|V|V-GZ&+&gQ?S?-`&ts{@5GXPqbmyZjUACC&oVXfNwUX0}ba(v978 zp8z!v9~8Zx8qB@7>oFPDm^iR@+yw`79YF)w^OHB_N;&&x7c3l^3!)IY#)}x)@D(iNaOm9 zC=^*!{`7={3*S=%iU=KsPXh=DDZcc``Ss>057i{pdW8M@4q+Ba@Tt%OytH!4>rbIbQw^-pR zGGYNPzw@n=PV@)b7yVbFr;glF*Qq3>F9oBN5PUXt!?2mdGcpv^o1?Thp`jP10G2Yi z(c93td3F3SW!Le5DUwdub!aDKoVLU6g!O?Ret21l$qOC;kdd@L#M&baVu&JZGt&<6 z!VCkvgRaav6QDW2x}tUy4~Y5(B+#Ej-8vM?DM-1?J_*&PntI3E96M!`WL#<&Z5n2u zo`P!~vBT$YOT~gU9#PB)%JZ zcd_u=m^LYzC!pH#W`yA1!(fA;D~b zG#73@l)NNd;n#XrKXZEfab;@kQRnOFU2Th-1m<4mJzlj9b3pv-GF$elX7ib9!uILM_$ke zHIGB*&=5=;ynQA{y7H93%i^d)T}y@(p>8vVhJ4L)M{0Q*@D^+SPp`EW+G6E%+`Z;u zS3goV@Dic7vc5`?!pCN44Ts@*{)zwy)9?B||AM{zKlN4T}qQRL2 zgv+{K8bv7w)#xge16;kI1fU87!W4pX)N&|cq8&i^1r`W|Hg4366r(?-ecEJ9u&Eaw zrhyikXQB>C9d>cpPGiu=VU3Z-u4|0V_iap!_J3o+K_R5EXk@sfu~zHwwYkpncVh!R zqNe7Cmf_|Wmeq4#(mIO&(wCK@b4(x0?W1Qtk(`$?+$uCJCGZm_%k?l32vuShgDFMa ztc`{$8DhB9)&?~(m&EUc=LzI1=qo#zjy#2{hLT_*aj<618qQ7mD#k2ZFGou&69;=2 z1j7=Su8k}{L*h&mfs7jg^PN&9C1Z@U!p6gXk&-7xM~{X`nqH#aGO`;Xy_zbz^rYacIq0AH%4!Oh93TzJ820%ur)8OyeS@K?sF1V(iFO z37Nnqj1z#1{|v7=_CX`lQA|$<1gtuNMHGNJYp1D_k;WQk-b+T6VmUK(x=bWviOZ~T z|4e%SpuaWLWD?qN2%`S*`P;BQBw(B__wTD6epvGdJ+>DBq2oVlf&F*lz+#avb4)3P1c^Mf#olQheVvZ|Z5 z>xXfgmv!5Z^SYn+_x}K5B%G^sRwiez&z9|f!E!#oJlT2kCOV0000$L_|bHBqAarB4TD{W@grX1CUr72@caw0faEd7-K|4L_|cawbojjHdpd6 zI6~Iv5J?-Q4*&oF000000FV;^004t70Z6Qk1Xl{X9oJ{sRC2(cs?- literal 0 HcmV?d00001 diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.js b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.js new file mode 100644 index 0000000..c8f82e5 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.4 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-mp.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.4",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.js b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.js new file mode 100644 index 0000000..34d5513 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n.toLowerCase()))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)0?0:3:ga(r[0]-e)0?2:1:ga(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c +},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)Ca?{x:f,y:ga(t-f)Ca?{x:ga(e-p)Ca?{x:h,y:ga(t-h)Ca?{x:ga(e-g)=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++oe;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++oe?[0/0,0/0]:[e>0?a[e-1]:n[0],et?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++ur)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.5"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++uu){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++rr;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||n({type:"zoomend"}),d=null}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(v=e(d=m||ta.mouse(this)),Dl.call(this),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t +},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nyc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++lf?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++ai;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/holder.min.js b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/holder.min.js new file mode 100644 index 0000000..6bfc844 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/holder.min.js @@ -0,0 +1,12 @@ +/*! + +Holder - client side image placeholders +Version 2.7.1+6hydf +© 2015 Ivan Malopinsky - http://imsky.co + +Site: http://holderjs.com +Issues: https://github.com/imsky/holder/issues +License: http://opensource.org/licenses/MIT + +*/ +!function(a){if(a.document){var b=a.document;b.querySelectorAll||(b.querySelectorAll=function(c){var d,e=b.createElement("style"),f=[];for(b.documentElement.firstChild.appendChild(e),b._qsa=[],e.styleSheet.cssText=c+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",a.scrollBy(0,0),e.parentNode.removeChild(e);b._qsa.length;)d=b._qsa.shift(),d.style.removeAttribute("x-qsa"),f.push(d);return b._qsa=null,f}),b.querySelector||(b.querySelector=function(a){var c=b.querySelectorAll(a);return c.length?c[0]:null}),b.getElementsByClassName||(b.getElementsByClassName=function(a){return a=String(a).replace(/^|\s+/g,"."),b.querySelectorAll(a)}),Object.keys||(Object.keys=function(a){if(a!==Object(a))throw TypeError("Object.keys called on non-object");var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c}),function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a.atob=a.atob||function(a){a=String(a);var c,d=0,e=[],f=0,g=0;if(a=a.replace(/\s/g,""),a.length%4===0&&(a=a.replace(/=+$/,"")),a.length%4===1)throw Error("InvalidCharacterError");if(/[^+/0-9A-Za-z]/.test(a))throw Error("InvalidCharacterError");for(;d>16&255)),e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f)),g=0,f=0),d+=1;return 12===g?(f>>=4,e.push(String.fromCharCode(255&f))):18===g&&(f>>=2,e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f))),e.join("")},a.btoa=a.btoa||function(a){a=String(a);var c,d,e,f,g,h,i,j=0,k=[];if(/[^\x00-\xFF]/.test(a))throw Error("InvalidCharacterError");for(;j>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,j===a.length+2?(h=64,i=64):j===a.length+1&&(i=64),k.push(b.charAt(f),b.charAt(g),b.charAt(h),b.charAt(i));return k.join("")}}(a),Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(a){var b=this.__proto__||this.constructor.prototype;return a in this&&(!(a in b)||b[a]!==this[a])}),function(){if("performance"in a==!1&&(a.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in a.performance==!1){var b=Date.now();performance.timing&&performance.timing.navigationStart&&(b=performance.timing.navigationStart),a.performance.now=function(){return Date.now()-b}}}(),a.requestAnimationFrame||(a.webkitRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return webkitRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=webkitCancelAnimationFrame}(a):a.mozRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return mozRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=mozCancelAnimationFrame}(a):!function(a){a.requestAnimationFrame=function(b){return a.setTimeout(b,1e3/60)},a.cancelAnimationFrame=a.clearTimeout}(a))}}(this),function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):"object"==typeof exports?exports.Holder=b():a.Holder=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){(function(b){function d(a,b,c,d){var f=e(c.substr(c.lastIndexOf(a.domain)),a);f&&h({mode:null,el:d,flags:f,engineSettings:b})}function e(a,b){var c={theme:B(J.settings.themes.gray,null),stylesheets:b.stylesheets,instanceOptions:b};return a.match(/([\d]+p?)x([\d]+p?)(?:\?|$)/)?f(a,c):g(a,c)}function f(a,b){var c=a.split("?"),d=c[0].split("/");b.holderURL=a;var e=d[1],f=e.match(/([\d]+p?)x([\d]+p?)/);if(!f)return!1;if(b.fluid=-1!==e.indexOf("p"),b.dimensions={width:f[1].replace("p","%"),height:f[2].replace("p","%")},2===c.length){var g=A.parse(c[1]);if(g.bg&&(b.theme.background=(-1===g.bg.indexOf("#")?"#":"")+g.bg),g.fg&&(b.theme.foreground=(-1===g.fg.indexOf("#")?"#":"")+g.fg),g.theme&&b.instanceOptions.themes.hasOwnProperty(g.theme)&&(b.theme=B(b.instanceOptions.themes[g.theme],null)),g.text&&(b.text=g.text),g.textmode&&(b.textmode=g.textmode),g.size&&(b.size=g.size),g.font&&(b.font=g.font),g.align&&(b.align=g.align),b.nowrap=z.truthy(g.nowrap),b.auto=z.truthy(g.auto),z.truthy(g.random)){J.vars.cache.themeKeys=J.vars.cache.themeKeys||Object.keys(b.instanceOptions.themes);var h=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(b.instanceOptions.themes[h],null)}}return b}function g(a,b){var c=!1,d=String.fromCharCode(11),e=a.replace(/([^\\])\//g,"$1"+d).split(d),f=/%[0-9a-f]{2}/gi,g=b.instanceOptions;b.holderURL=[];for(var h=e.length,i=0;h>i;i++){var j=e[i];if(j.match(f))try{j=decodeURIComponent(j)}catch(k){j=e[i]}var l=!1;if(J.flags.dimensions.match(j))c=!0,b.dimensions=J.flags.dimensions.output(j),l=!0;else if(J.flags.fluid.match(j))c=!0,b.dimensions=J.flags.fluid.output(j),b.fluid=!0,l=!0;else if(J.flags.textmode.match(j))b.textmode=J.flags.textmode.output(j),l=!0;else if(J.flags.colors.match(j)){var m=J.flags.colors.output(j);b.theme=B(b.theme,m),l=!0}else if(g.themes[j])g.themes.hasOwnProperty(j)&&(b.theme=B(g.themes[j],null)),l=!0;else if(J.flags.font.match(j))b.font=J.flags.font.output(j),l=!0;else if(J.flags.auto.match(j))b.auto=!0,l=!0;else if(J.flags.text.match(j))b.text=J.flags.text.output(j),l=!0;else if(J.flags.size.match(j))b.size=J.flags.size.output(j),l=!0;else if(J.flags.random.match(j)){null==J.vars.cache.themeKeys&&(J.vars.cache.themeKeys=Object.keys(g.themes));var n=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(g.themes[n],null),l=!0}l&&b.holderURL.push(j)}return b.holderURL.unshift(g.domain),b.holderURL=b.holderURL.join("/"),c?b:!1}function h(a){var b=a.mode,c=a.el,d=a.flags,e=a.engineSettings,f=d.dimensions,g=d.theme,h=f.width+"x"+f.height;if(b=null==b?d.fluid?"fluid":"image":b,null!=d.text&&(g.text=d.text,"object"===c.nodeName.toLowerCase())){for(var j=g.text.split("\\n"),k=0;k1){var n,o=0,p=0,q=0;j=new e.Group("line"+q),("left"===a.align||"right"===a.align)&&(m=a.width*(1-2*(1-J.setup.lineWrapRatio)));for(var r=0;r=m||t===!0)&&(b(g,j,o,g.properties.leading),g.add(j),o=0,p+=g.properties.leading,q+=1,j=new e.Group("line"+q),j.y=p),t!==!0&&(i.moveTo(o,0),o+=h.spaceWidth+s.width,j.add(i))}if(b(g,j,o,g.properties.leading),g.add(j),"left"===a.align)g.moveTo(a.width-l,null,null);else if("right"===a.align){for(n in g.children)j=g.children[n],j.moveTo(a.width-j.width,null,null);g.moveTo(0-(a.width-l),null,null)}else{for(n in g.children)j=g.children[n],j.moveTo((g.width-j.width)/2,null,null);g.moveTo((a.width-g.width)/2,null,null)}g.moveTo(null,(a.height-g.height)/2,null),(a.height-g.height)/2<0&&g.moveTo(null,0,null)}else i=new e.Text(a.text),j=new e.Group("line0"),j.add(i),g.add(j),"left"===a.align?g.moveTo(a.width-l,null,null):"right"===a.align?g.moveTo(0-(a.width-l),null,null):g.moveTo((a.width-h.boundingBox.width)/2,null,null),g.moveTo(null,(a.height-h.boundingBox.height)/2,null);return d}function k(a,b,c){var d=parseInt(a,10),e=parseInt(b,10),f=Math.max(d,e),g=Math.min(d,e),h=.8*Math.min(g,f*J.defaults.scale);return Math.round(Math.max(c,h))}function l(a){var b;b=null==a||null==a.nodeType?J.vars.resizableImages:[a];for(var c=0,d=b.length;d>c;c++){var e=b[c];if(e.holderData){var f=e.holderData.flags,g=D(e);if(g){if(!e.holderData.resizeUpdate)continue;if(f.fluid&&f.auto){var h=e.holderData.fluidConfig;switch(h.mode){case"width":g.height=g.width/h.ratio;break;case"height":g.width=g.height*h.ratio}}var j={mode:"image",holderSettings:{dimensions:g,theme:f.theme,flags:f},el:e,engineSettings:e.holderData.engineSettings};"exact"==f.textmode&&(f.exactDimensions=g,j.holderSettings.dimensions=f.dimensions),i(j)}else p(e)}}}function m(a){if(a.holderData){var b=D(a);if(b){var c=a.holderData.flags,d={fluidHeight:"%"==c.dimensions.height.slice(-1),fluidWidth:"%"==c.dimensions.width.slice(-1),mode:null,initialDimensions:b};d.fluidWidth&&!d.fluidHeight?(d.mode="width",d.ratio=d.initialDimensions.width/parseFloat(c.dimensions.height)):!d.fluidWidth&&d.fluidHeight&&(d.mode="height",d.ratio=parseFloat(c.dimensions.width)/d.initialDimensions.height),a.holderData.fluidConfig=d}else p(a)}}function n(){for(var a,c=[],d=Object.keys(J.vars.invisibleImages),e=0,f=d.length;f>e;e++)a=J.vars.invisibleImages[d[e]],D(a)&&"img"==a.nodeName.toLowerCase()&&(c.push(a),delete J.vars.invisibleImages[d[e]]);c.length&&I.run({images:c}),b.requestAnimationFrame(n)}function o(){J.vars.visibilityCheckStarted||(b.requestAnimationFrame(n),J.vars.visibilityCheckStarted=!0)}function p(a){a.holderData.invisibleId||(J.vars.invisibleId+=1,J.vars.invisibleImages["i"+J.vars.invisibleId]=a,a.holderData.invisibleId=J.vars.invisibleId)}function q(a,b){return null==b?document.createElement(a):document.createElementNS(b,a)}function r(a,b){for(var c in b)a.setAttribute(c,b[c])}function s(a,b,c){var d,e;null==a?(a=q("svg",E),d=q("defs",E),e=q("style",E),r(e,{type:"text/css"}),d.appendChild(e),a.appendChild(d)):e=a.querySelector("style"),a.webkitMatchesSelector&&a.setAttribute("xmlns",E);for(var f=0;f=0;h--){var i=g.createProcessingInstruction("xml-stylesheet",'href="'+f[h]+'" rel="stylesheet"');g.insertBefore(i,g.firstChild)}g.removeChild(g.documentElement),e=d.serializeToString(g)}var j=d.serializeToString(a);return j=j.replace(/\&(\#[0-9]{2,}\;)/g,"&$1"),e+j}}function u(){return b.DOMParser?(new DOMParser).parseFromString("","application/xml"):void 0}function v(a){J.vars.debounceTimer||a.call(this),J.vars.debounceTimer&&b.clearTimeout(J.vars.debounceTimer),J.vars.debounceTimer=b.setTimeout(function(){J.vars.debounceTimer=null,a.call(this)},J.setup.debounce)}function w(){v(function(){l(null)})}var x=c(1),y=c(2),z=c(3),A=c(4),B=z.extend,C=z.getNodeArray,D=z.dimensionCheck,E="http://www.w3.org/2000/svg",F=8,G="2.7.1",H="\nCreated with Holder.js "+G+".\nLearn more at http://holderjs.com\n(c) 2012-2015 Ivan Malopinsky - http://imsky.co\n",I={version:G,addTheme:function(a,b){return null!=a&&null!=b&&(J.settings.themes[a]=b),delete J.vars.cache.themeKeys,this},addImage:function(a,b){var c=document.querySelectorAll(b);if(c.length)for(var d=0,e=c.length;e>d;d++){var f=q("img"),g={};g[J.vars.dataAttr]=a,r(f,g),c[d].appendChild(f)}return this},setResizeUpdate:function(a,b){a.holderData&&(a.holderData.resizeUpdate=!!b,a.holderData.resizeUpdate&&l(a))},run:function(a){a=a||{};var c={},f=B(J.settings,a);J.vars.preempted=!0,J.vars.dataAttr=f.dataAttr||J.vars.dataAttr,c.renderer=f.renderer?f.renderer:J.setup.renderer,-1===J.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=J.setup.supportsSVG?"svg":J.setup.supportsCanvas?"canvas":"html");var g=C(f.images),i=C(f.bgnodes),j=C(f.stylenodes),k=C(f.objects);c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=f.noFontFallback?f.noFontFallback:!1;for(var l=0;l1){c.nodeValue="";for(var u=0;u=0?b:1)}function f(a){v?e(a):w.push(a)}null==document.readyState&&document.addEventListener&&(document.addEventListener("DOMContentLoaded",function y(){document.removeEventListener("DOMContentLoaded",y,!1),document.readyState="complete"},!1),document.readyState="loading");var g=a.document,h=g.documentElement,i="load",j=!1,k="on"+i,l="complete",m="readyState",n="attachEvent",o="detachEvent",p="addEventListener",q="DOMContentLoaded",r="onreadystatechange",s="removeEventListener",t=p in g,u=j,v=j,w=[];if(g[m]===l)e(b);else if(t)g[p](q,c,j),a[p](i,c,j);else{g[n](r,c),a[n](k,c);try{u=null==a.frameElement&&h}catch(x){}u&&u.doScroll&&!function z(){if(!v){try{u.doScroll("left")}catch(a){return e(z,50)}d(),b()}}()}return f.version="1.4.0",f.isReady=function(){return v},f}a.exports="undefined"!=typeof window&&b(window)},function(a,b,c){var d=c(5),e=function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}var c=1,e=d.defclass({constructor:function(a){c++,this.parent=null,this.children={},this.id=c,this.name="n"+c,null!=a&&(this.name=a),this.x=0,this.y=0,this.z=0,this.width=0,this.height=0},resize:function(a,b){null!=a&&(this.width=a),null!=b&&(this.height=b)},moveTo:function(a,b,c){this.x=null!=a?a:this.x,this.y=null!=b?b:this.y,this.z=null!=c?c:this.z},add:function(a){var b=a.name;if(null!=this.children[b])throw"SceneGraph: child with that name already exists: "+b;this.children[b]=a,a.parent=this}}),f=d(e,function(b){this.constructor=function(){b.constructor.call(this,"root"),this.properties=a}}),g=d(e,function(a){function c(c,d){if(a.constructor.call(this,c),this.properties={fill:"#000"},null!=d)b(this.properties,d);else if(null!=c&&"string"!=typeof c)throw"SceneGraph: invalid node name"}this.Group=d.extend(this,{constructor:c,type:"group"}),this.Rect=d.extend(this,{constructor:c,type:"rect"}),this.Text=d.extend(this,{constructor:function(a){c.call(this),this.properties.text=a},type:"text"})}),h=new f;return this.Shape=g,this.root=h,this};a.exports=e},function(a,b){(function(a){b.extend=function(a,b){var c={};for(var d in a)a.hasOwnProperty(d)&&(c[d]=a[d]);if(null!=b)for(var e in b)b.hasOwnProperty(e)&&(c[e]=b[e]);return c},b.cssProps=function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c+":"+a[c]);return b.join(";")},b.encodeHtmlEntity=function(a){for(var b=[],c=0,d=a.length-1;d>=0;d--)c=a.charCodeAt(d),b.unshift(c>128?["&#",c,";"].join(""):a[d]);return b.join("")},b.getNodeArray=function(b){var c=null;return"string"==typeof b?c=document.querySelectorAll(b):a.NodeList&&b instanceof a.NodeList?c=b:a.Node&&b instanceof a.Node?c=[b]:a.HTMLCollection&&b instanceof a.HTMLCollection?c=b:b instanceof Array?c=b:null===b&&(c=[]),c},b.imageExists=function(a,b){var c=new Image;c.onerror=function(){b.call(this,!1)},c.onload=function(){b.call(this,!0)},c.src=a},b.decodeHtmlEntity=function(a){return a.replace(/&#(\d+);/g,function(a,b){return String.fromCharCode(b)})},b.dimensionCheck=function(a){var b={height:a.clientHeight,width:a.clientWidth};return b.height&&b.width?b:!1},b.truthy=function(a){return"string"==typeof a?"true"===a||"yes"===a||"1"===a||"on"===a||"✓"===a:!!a}}).call(b,function(){return this}())},function(a,b,c){var d=encodeURIComponent,e=decodeURIComponent,f=c(6),g=c(7),h=/(\w+)\[(\d+)\]/,i=/\w+\.\w+/;b.parse=function(a){if("string"!=typeof a)return{};if(a=f(a),""===a)return{};"?"===a.charAt(0)&&(a=a.slice(1));for(var b={},c=a.split("&"),d=0;d",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document); \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.min.js b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.min.js new file mode 100644 index 0000000..0f60b7b --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; + +return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
    a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/\s*$/g,ra={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:k.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?""!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("