From a1789ddde42033f1b05cc4929491214ee6e79383 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Thu, 17 Dec 2015 09:15:42 +0100 Subject: Update to MediaWiki 1.26.0 --- vendor/README.md | 30 + vendor/autoload.php | 2 +- vendor/composer.json | 35 + vendor/composer.lock | 1064 ++++++ vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 509 ++- vendor/composer/autoload_files.php | 10 + vendor/composer/autoload_namespaces.php | 7 +- vendor/composer/autoload_psr4.php | 9 +- vendor/composer/autoload_real.php | 14 +- vendor/composer/installed.json | 987 ++++- vendor/composer/semver/CHANGELOG.md | 28 + vendor/composer/semver/LICENSE | 19 + vendor/composer/semver/README.md | 70 + vendor/composer/semver/composer.json | 57 + vendor/composer/semver/src/Comparator.php | 111 + .../semver/src/Constraint/AbstractConstraint.php | 65 + .../composer/semver/src/Constraint/Constraint.php | 181 + .../semver/src/Constraint/ConstraintInterface.php | 37 + .../semver/src/Constraint/EmptyConstraint.php | 59 + .../semver/src/Constraint/MultiConstraint.php | 96 + vendor/composer/semver/src/Semver.php | 127 + vendor/composer/semver/src/VersionParser.php | 520 +++ vendor/firebase/php-jwt/Authentication/JWT.php | 334 ++ .../php-jwt/Exceptions/BeforeValidException.php | 6 + .../php-jwt/Exceptions/ExpiredException.php | 6 + .../Exceptions/SignatureInvalidException.php | 6 + vendor/firebase/php-jwt/LICENSE | 30 + vendor/firebase/php-jwt/README.md | 93 + vendor/firebase/php-jwt/composer.json | 25 + vendor/firebase/php-jwt/package.xml | 77 + vendor/firebase/php-jwt/phpunit.xml.dist | 19 + vendor/firebase/php-jwt/run-tests.sh | 38 + vendor/firebase/php-jwt/tests/JWTTest.php | 231 ++ vendor/firebase/php-jwt/tests/autoload.php.dist | 17 + vendor/firebase/php-jwt/tests/bootstrap.php | 7 + vendor/kzykhys/pygments/README.md | 99 + vendor/kzykhys/pygments/composer.json | 17 + vendor/kzykhys/pygments/composer.lock | 118 + vendor/kzykhys/pygments/phpunit.xml.dist | 28 + .../pygments/src/KzykHys/Pygments/Pygments.php | 200 ++ .../test/KzykHys/Pygments/PygmentsTest.php | 116 + .../KzykHys/Pygments/Resources/css/default.css | 61 + .../Pygments/Resources/css/default.prefix.css | 62 + .../KzykHys/Pygments/Resources/example/php.php.in | 21 + .../Pygments/Resources/example/php.php.linenos.out | 43 + .../KzykHys/Pygments/Resources/example/php.php.out | 22 + vendor/leafo/lessphp/LICENSE | 660 ---- vendor/leafo/lessphp/Makefile | 7 - vendor/leafo/lessphp/README.md | 96 - vendor/leafo/lessphp/composer.json | 25 - vendor/leafo/lessphp/docs/docs.md | 1400 -------- vendor/leafo/lessphp/lessc.inc.php | 3768 -------------------- vendor/leafo/lessphp/lessify | 23 - vendor/leafo/lessphp/lessify.inc.php | 447 --- vendor/leafo/lessphp/package.sh | 35 - vendor/leafo/lessphp/plessc | 250 -- vendor/leafo/lessphp/tests/ApiTest.php | 196 - vendor/leafo/lessphp/tests/ErrorHandlingTest.php | 81 - vendor/leafo/lessphp/tests/InputTest.php | 89 - vendor/leafo/lessphp/tests/README.md | 24 - vendor/leafo/lessphp/tests/bootstrap.sh | 38 - .../lessphp/tests/inputs/accessors.less.disable | 36 - vendor/leafo/lessphp/tests/inputs/arity.less | 77 - vendor/leafo/lessphp/tests/inputs/attributes.less | 41 - vendor/leafo/lessphp/tests/inputs/builtins.less | 96 - vendor/leafo/lessphp/tests/inputs/colors.less | 154 - .../lessphp/tests/inputs/compile_on_mixin.less | 39 - vendor/leafo/lessphp/tests/inputs/data-uri.less | 7 - vendor/leafo/lessphp/tests/inputs/directives.less | 28 - vendor/leafo/lessphp/tests/inputs/escape.less | 18 - vendor/leafo/lessphp/tests/inputs/font_family.less | 28 - vendor/leafo/lessphp/tests/inputs/guards.less | 74 - vendor/leafo/lessphp/tests/inputs/hacks.less | 6 - vendor/leafo/lessphp/tests/inputs/hi.less | 5 - vendor/leafo/lessphp/tests/inputs/ie.less | 12 - vendor/leafo/lessphp/tests/inputs/import.less | 56 - .../leafo/lessphp/tests/inputs/interpolation.less | 47 - vendor/leafo/lessphp/tests/inputs/keyframes.less | 52 - vendor/leafo/lessphp/tests/inputs/math.less | 122 - vendor/leafo/lessphp/tests/inputs/media.less | 68 - vendor/leafo/lessphp/tests/inputs/misc.less | 100 - .../lessphp/tests/inputs/mixin_functions.less | 33 - .../tests/inputs/mixin_merging.less.disable | 100 - vendor/leafo/lessphp/tests/inputs/mixins.less | 197 - vendor/leafo/lessphp/tests/inputs/nested.less | 60 - .../lessphp/tests/inputs/pattern_matching.less | 157 - vendor/leafo/lessphp/tests/inputs/scopes.less | 40 - .../lessphp/tests/inputs/selector_expressions.less | 29 - vendor/leafo/lessphp/tests/inputs/site_demos.less | 120 - .../leafo/lessphp/tests/inputs/test-imports/a.less | 6 - .../leafo/lessphp/tests/inputs/test-imports/b.less | 12 - .../lessphp/tests/inputs/test-imports/file1.less | 16 - .../lessphp/tests/inputs/test-imports/file2.less | 6 - .../lessphp/tests/inputs/test-imports/file3.less | 7 - .../tests/inputs/test-imports/inner/file1.less | 6 - .../tests/inputs/test-imports/inner/file2.less | 4 - vendor/leafo/lessphp/tests/inputs/variables.less | 44 - .../lessphp/tests/inputs_lessjs/mixins-args.less | 205 -- .../tests/inputs_lessjs/mixins-named-args.less | 36 - .../leafo/lessphp/tests/inputs_lessjs/strings.less | 51 - vendor/leafo/lessphp/tests/outputs/accessors.css | 14 - vendor/leafo/lessphp/tests/outputs/arity.css | 25 - vendor/leafo/lessphp/tests/outputs/attributes.css | 105 - vendor/leafo/lessphp/tests/outputs/builtins.css | 61 - vendor/leafo/lessphp/tests/outputs/colors.css | 103 - .../lessphp/tests/outputs/compile_on_mixin.css | 29 - vendor/leafo/lessphp/tests/outputs/data-uri.css | 6 - vendor/leafo/lessphp/tests/outputs/directives.css | 27 - vendor/leafo/lessphp/tests/outputs/escape.css | 14 - vendor/leafo/lessphp/tests/outputs/font_family.css | 17 - vendor/leafo/lessphp/tests/outputs/guards.css | 27 - vendor/leafo/lessphp/tests/outputs/hacks.css | 4 - vendor/leafo/lessphp/tests/outputs/hi.css | 3 - vendor/leafo/lessphp/tests/outputs/ie.css | 9 - vendor/leafo/lessphp/tests/outputs/import.css | 51 - .../leafo/lessphp/tests/outputs/interpolation.css | 28 - vendor/leafo/lessphp/tests/outputs/keyframes.css | 48 - vendor/leafo/lessphp/tests/outputs/math.css | 69 - vendor/leafo/lessphp/tests/outputs/media.css | 70 - vendor/leafo/lessphp/tests/outputs/misc.css | 68 - .../lessphp/tests/outputs/mixin_functions.css | 7 - .../leafo/lessphp/tests/outputs/mixin_merging.css | 42 - vendor/leafo/lessphp/tests/outputs/mixins.css | 92 - vendor/leafo/lessphp/tests/outputs/nested.css | 51 - vendor/leafo/lessphp/tests/outputs/nesting.css | 6 - .../lessphp/tests/outputs/pattern_matching.css | 72 - vendor/leafo/lessphp/tests/outputs/scopes.css | 11 - .../lessphp/tests/outputs/selector_expressions.css | 25 - vendor/leafo/lessphp/tests/outputs/site_demos.css | 76 - vendor/leafo/lessphp/tests/outputs/variables.css | 19 - .../lessphp/tests/outputs_lessjs/mixins-args.css | 113 - .../tests/outputs_lessjs/mixins-named-args.css | 27 - .../leafo/lessphp/tests/outputs_lessjs/strings.css | 40 - vendor/leafo/lessphp/tests/sort.php | 57 - vendor/liuggio/statsd-php-client/CHANGELOG.md | 17 + vendor/liuggio/statsd-php-client/README.md | 152 + vendor/liuggio/statsd-php-client/Readme.md | 149 - vendor/liuggio/statsd-php-client/composer.json | 2 +- vendor/liuggio/statsd-php-client/phpunit.xml | 15 + vendor/liuggio/statsd-php-client/phpunit.xml.dist | 15 - .../src/Liuggio/StatsdClient/Entity/StatsdData.php | 28 +- .../StatsdClient/Entity/StatsdDataInterface.php | 6 + .../Liuggio/StatsdClient/Service/StatsdService.php | 196 + .../src/Liuggio/StatsdClient/StatsdClient.php | 8 +- .../StatsdClient/Service/StatsdServiceTest.php | 86 + vendor/mediawiki/at-ease/COPYING | 342 ++ vendor/mediawiki/at-ease/README.md | 59 + vendor/mediawiki/at-ease/src/Functions.php | 75 + vendor/monolog/monolog/.php_cs | 15 + vendor/monolog/monolog/CHANGELOG.mdown | 226 ++ vendor/monolog/monolog/LICENSE | 19 + vendor/monolog/monolog/README.mdown | 302 ++ vendor/monolog/monolog/composer.json | 61 + vendor/monolog/monolog/doc/extending.md | 76 + vendor/monolog/monolog/doc/sockets.md | 37 + vendor/monolog/monolog/doc/usage.md | 162 + vendor/monolog/monolog/phpunit.xml.dist | 19 + .../monolog/monolog/src/Monolog/ErrorHandler.php | 208 ++ .../src/Monolog/Formatter/ChromePHPFormatter.php | 79 + .../src/Monolog/Formatter/ElasticaFormatter.php | 87 + .../src/Monolog/Formatter/FlowdockFormatter.php | 104 + .../src/Monolog/Formatter/FormatterInterface.php | 36 + .../src/Monolog/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 + .../src/Monolog/Formatter/LogstashFormatter.php | 165 + .../src/Monolog/Formatter/MongoDBFormatter.php | 105 + .../src/Monolog/Formatter/NormalizerFormatter.php | 158 + .../src/Monolog/Formatter/ScalarFormatter.php | 48 + .../src/Monolog/Formatter/WildfireFormatter.php | 113 + .../src/Monolog/Handler/AbstractHandler.php | 184 + .../Monolog/Handler/AbstractProcessingHandler.php | 66 + .../src/Monolog/Handler/AbstractSyslogHandler.php | 92 + .../monolog/src/Monolog/Handler/AmqpHandler.php | 98 + .../src/Monolog/Handler/BrowserConsoleHandler.php | 184 + .../monolog/src/Monolog/Handler/BufferHandler.php | 117 + .../src/Monolog/Handler/ChromePHPHandler.php | 204 ++ .../monolog/src/Monolog/Handler/CouchDBHandler.php | 72 + .../monolog/src/Monolog/Handler/CubeHandler.php | 151 + .../src/Monolog/Handler/DoctrineCouchDBHandler.php | 45 + .../src/Monolog/Handler/DynamoDbHandler.php | 89 + .../src/Monolog/Handler/ElasticSearchHandler.php | 128 + .../src/Monolog/Handler/ErrorLogHandler.php | 82 + .../monolog/src/Monolog/Handler/FilterHandler.php | 140 + .../FingersCrossed/ActivationStrategyInterface.php | 28 + .../ChannelLevelActivationStrategy.php | 59 + .../ErrorLevelActivationStrategy.php | 34 + .../src/Monolog/Handler/FingersCrossedHandler.php | 153 + .../monolog/src/Monolog/Handler/FirePHPHandler.php | 195 + .../src/Monolog/Handler/FleepHookHandler.php | 126 + .../src/Monolog/Handler/FlowdockHandler.php | 103 + .../monolog/src/Monolog/Handler/GelfHandler.php | 73 + .../monolog/src/Monolog/Handler/GroupHandler.php | 80 + .../src/Monolog/Handler/HandlerInterface.php | 90 + .../monolog/src/Monolog/Handler/HipChatHandler.php | 337 ++ .../src/Monolog/Handler/LogEntriesHandler.php | 55 + .../monolog/src/Monolog/Handler/LogglyHandler.php | 106 + .../monolog/src/Monolog/Handler/MailHandler.php | 55 + .../src/Monolog/Handler/MandrillHandler.php | 71 + .../Monolog/Handler/MissingExtensionException.php | 21 + .../monolog/src/Monolog/Handler/MongoDBHandler.php | 55 + .../src/Monolog/Handler/NativeMailerHandler.php | 176 + .../src/Monolog/Handler/NewRelicHandler.php | 198 + .../monolog/src/Monolog/Handler/NullHandler.php | 45 + .../src/Monolog/Handler/PHPConsoleHandler.php | 243 ++ .../monolog/src/Monolog/Handler/PsrHandler.php | 56 + .../src/Monolog/Handler/PushoverHandler.php | 185 + .../monolog/src/Monolog/Handler/RavenHandler.php | 190 + .../monolog/src/Monolog/Handler/RedisHandler.php | 63 + .../monolog/src/Monolog/Handler/RollbarHandler.php | 73 + .../src/Monolog/Handler/RotatingFileHandler.php | 153 + .../src/Monolog/Handler/SamplingHandler.php | 82 + .../monolog/src/Monolog/Handler/SlackHandler.php | 292 ++ .../monolog/src/Monolog/Handler/SocketHandler.php | 284 ++ .../monolog/src/Monolog/Handler/StreamHandler.php | 104 + .../src/Monolog/Handler/SwiftMailerHandler.php | 87 + .../monolog/src/Monolog/Handler/SyslogHandler.php | 67 + .../src/Monolog/Handler/SyslogUdp/UdpSocket.php | 46 + .../src/Monolog/Handler/SyslogUdpHandler.php | 80 + .../monolog/src/Monolog/Handler/TestHandler.php | 195 + .../Monolog/Handler/WhatFailureGroupHandler.php | 57 + .../src/Monolog/Handler/ZendMonitorHandler.php | 95 + vendor/monolog/monolog/src/Monolog/Logger.php | 629 ++++ .../monolog/src/Monolog/Processor/GitProcessor.php | 64 + .../Monolog/Processor/IntrospectionProcessor.php | 82 + .../Monolog/Processor/MemoryPeakUsageProcessor.php | 40 + .../src/Monolog/Processor/MemoryProcessor.php | 63 + .../src/Monolog/Processor/MemoryUsageProcessor.php | 40 + .../src/Monolog/Processor/ProcessIdProcessor.php | 31 + .../Monolog/Processor/PsrLogMessageProcessor.php | 48 + .../monolog/src/Monolog/Processor/TagProcessor.php | 34 + .../monolog/src/Monolog/Processor/UidProcessor.php | 38 + .../monolog/src/Monolog/Processor/WebProcessor.php | 105 + vendor/monolog/monolog/src/Monolog/Registry.php | 134 + .../monolog/tests/Monolog/ErrorHandlerTest.php | 31 + .../Monolog/Formatter/ChromePHPFormatterTest.php | 158 + .../Monolog/Formatter/ElasticaFormatterTest.php | 79 + .../Monolog/Formatter/FlowdockFormatterTest.php | 55 + .../Monolog/Formatter/GelfMessageFormatterTest.php | 204 ++ .../tests/Monolog/Formatter/JsonFormatterTest.php | 78 + .../tests/Monolog/Formatter/LineFormatterTest.php | 208 ++ .../Monolog/Formatter/LogglyFormatterTest.php | 40 + .../Monolog/Formatter/LogstashFormatterTest.php | 289 ++ .../Monolog/Formatter/MongoDBFormatterTest.php | 253 ++ .../Monolog/Formatter/NormalizerFormatterTest.php | 254 ++ .../Monolog/Formatter/ScalarFormatterTest.php | 98 + .../Monolog/Formatter/WildfireFormatterTest.php | 142 + .../tests/Monolog/Handler/AbstractHandlerTest.php | 115 + .../Handler/AbstractProcessingHandlerTest.php | 80 + .../tests/Monolog/Handler/AmqpHandlerTest.php | 136 + .../Monolog/Handler/BrowserConsoleHandlerTest.php | 130 + .../tests/Monolog/Handler/BufferHandlerTest.php | 158 + .../tests/Monolog/Handler/ChromePHPHandlerTest.php | 141 + .../tests/Monolog/Handler/CouchDBHandlerTest.php | 31 + .../Monolog/Handler/DoctrineCouchDBHandlerTest.php | 52 + .../tests/Monolog/Handler/DynamoDbHandlerTest.php | 73 + .../Monolog/Handler/ElasticSearchHandlerTest.php | 239 ++ .../tests/Monolog/Handler/ErrorLogHandlerTest.php | 66 + .../tests/Monolog/Handler/FilterHandlerTest.php | 170 + .../Monolog/Handler/FingersCrossedHandlerTest.php | 255 ++ .../tests/Monolog/Handler/FirePHPHandlerTest.php | 96 + .../tests/Monolog/Handler/FleepHookHandlerTest.php | 85 + .../tests/Monolog/Handler/FlowdockHandlerTest.php | 88 + .../Monolog/Handler/GelfHandlerLegacyTest.php | 95 + .../tests/Monolog/Handler/GelfHandlerTest.php | 117 + .../Monolog/Handler/GelfMockMessagePublisher.php | 25 + .../tests/Monolog/Handler/GroupHandlerTest.php | 89 + .../tests/Monolog/Handler/HipChatHandlerTest.php | 240 ++ .../Monolog/Handler/LogEntriesHandlerTest.php | 84 + .../tests/Monolog/Handler/MailHandlerTest.php | 75 + .../tests/Monolog/Handler/MockRavenClient.php | 27 + .../tests/Monolog/Handler/MongoDBHandlerTest.php | 65 + .../Monolog/Handler/NativeMailerHandlerTest.php | 61 + .../tests/Monolog/Handler/NewRelicHandlerTest.php | 192 + .../tests/Monolog/Handler/NullHandlerTest.php | 33 + .../Monolog/Handler/PHPConsoleHandlerTest.php | 271 ++ .../tests/Monolog/Handler/PsrHandlerTest.php | 50 + .../tests/Monolog/Handler/PushoverHandlerTest.php | 141 + .../tests/Monolog/Handler/RavenHandlerTest.php | 185 + .../tests/Monolog/Handler/RedisHandlerTest.php | 71 + .../Monolog/Handler/RotatingFileHandlerTest.php | 99 + .../tests/Monolog/Handler/SamplingHandlerTest.php | 33 + .../tests/Monolog/Handler/SlackHandlerTest.php | 133 + .../tests/Monolog/Handler/SocketHandlerTest.php | 282 ++ .../tests/Monolog/Handler/StreamHandlerTest.php | 118 + .../Monolog/Handler/SwiftMailerHandlerTest.php | 65 + .../tests/Monolog/Handler/SyslogHandlerTest.php | 44 + .../tests/Monolog/Handler/SyslogUdpHandlerTest.php | 49 + .../tests/Monolog/Handler/TestHandlerTest.php | 58 + .../tests/Monolog/Handler/UdpSocketTest.php | 46 + .../Handler/WhatFailureGroupHandlerTest.php | 121 + .../Monolog/Handler/ZendMonitorHandlerTest.php | 69 + .../monolog/monolog/tests/Monolog/LoggerTest.php | 447 +++ .../tests/Monolog/Processor/GitProcessorTest.php | 29 + .../Processor/IntrospectionProcessorTest.php | 123 + .../Processor/MemoryPeakUsageProcessorTest.php | 42 + .../Monolog/Processor/MemoryUsageProcessorTest.php | 42 + .../Monolog/Processor/ProcessIdProcessorTest.php | 30 + .../Processor/PsrLogMessageProcessorTest.php | 43 + .../tests/Monolog/Processor/TagProcessorTest.php | 29 + .../tests/Monolog/Processor/UidProcessorTest.php | 27 + .../tests/Monolog/Processor/WebProcessorTest.php | 98 + .../monolog/tests/Monolog/PsrLogCompatTest.php | 47 + .../monolog/monolog/tests/Monolog/RegistryTest.php | 63 + vendor/monolog/monolog/tests/Monolog/TestCase.php | 58 + vendor/nmred/kafka-php/LICENSE | 27 + vendor/nmred/kafka-php/README.md | 496 +++ vendor/nmred/kafka-php/src/Kafka/Client.php | 290 ++ .../nmred/kafka-php/src/Kafka/ClusterMetaData.php | 53 + vendor/nmred/kafka-php/src/Kafka/Consumer.php | 378 ++ vendor/nmred/kafka-php/src/Kafka/Exception.php | 31 + .../kafka-php/src/Kafka/Exception/NotSupported.php | 33 + .../kafka-php/src/Kafka/Exception/OutOfRange.php | 33 + .../kafka-php/src/Kafka/Exception/Protocol.php | 33 + .../nmred/kafka-php/src/Kafka/Exception/Socket.php | 33 + .../src/Kafka/Exception/SocketConnect.php | 33 + .../kafka-php/src/Kafka/Exception/SocketEOF.php | 33 + .../src/Kafka/Exception/SocketTimeout.php | 33 + vendor/nmred/kafka-php/src/Kafka/Log.php | 78 + .../kafka-php/src/Kafka/MetaDataFromKafka.php | 200 ++ vendor/nmred/kafka-php/src/Kafka/Offset.php | 305 ++ vendor/nmred/kafka-php/src/Kafka/Produce.php | 337 ++ .../nmred/kafka-php/src/Kafka/Protocol/Decoder.php | 430 +++ .../nmred/kafka-php/src/Kafka/Protocol/Encoder.php | 652 ++++ .../Kafka/Protocol/Fetch/Helper/CommitOffset.php | 119 + .../src/Kafka/Protocol/Fetch/Helper/Consumer.php | 39 + .../src/Kafka/Protocol/Fetch/Helper/FreeStream.php | 117 + .../src/Kafka/Protocol/Fetch/Helper/Helper.php | 160 + .../Kafka/Protocol/Fetch/Helper/HelperAbstract.php | 71 + .../kafka-php/src/Kafka/Protocol/Fetch/Message.php | 175 + .../src/Kafka/Protocol/Fetch/MessageSet.php | 269 ++ .../src/Kafka/Protocol/Fetch/Partition.php | 375 ++ .../kafka-php/src/Kafka/Protocol/Fetch/Topic.php | 345 ++ .../kafka-php/src/Kafka/Protocol/Protocol.php | 230 ++ vendor/nmred/kafka-php/src/Kafka/Socket.php | 365 ++ vendor/nmred/kafka-php/src/Kafka/ZooKeeper.php | 364 ++ vendor/oojs/oojs-ui/.csscomb.json | 24 - vendor/oojs/oojs-ui/.csslintrc | 11 - vendor/oojs/oojs-ui/.npmignore | 2 - vendor/oojs/oojs-ui/AUTHORS.txt | 3 +- vendor/oojs/oojs-ui/Doxyfile | 33 - vendor/oojs/oojs-ui/Gruntfile.js | 401 --- vendor/oojs/oojs-ui/History.md | 1242 +++++-- vendor/oojs/oojs-ui/LICENSE-MIT | 2 +- vendor/oojs/oojs-ui/README.md | 12 +- vendor/oojs/oojs-ui/bin/docparser.rb | 70 +- .../oojs/oojs-ui/bin/generate-JSPHP-for-karma.php | 20 +- vendor/oojs/oojs-ui/bin/testsuitegenerator.rb | 12 +- vendor/oojs/oojs-ui/build/banner.txt | 10 - vendor/oojs/oojs-ui/build/modules.json | 240 -- vendor/oojs/oojs-ui/build/tasks/colorize-svg.js | 538 --- vendor/oojs/oojs-ui/build/tasks/typos.js | 89 - vendor/oojs/oojs-ui/build/typos.json | 17 - vendor/oojs/oojs-ui/composer.json | 24 - vendor/oojs/oojs-ui/demos/demo.js | 55 +- vendor/oojs/oojs-ui/demos/index.html | 11 +- vendor/oojs/oojs-ui/demos/infusion.js | 58 +- vendor/oojs/oojs-ui/demos/pages/dialogs.js | 318 +- vendor/oojs/oojs-ui/demos/pages/icons.js | 16 +- vendor/oojs/oojs-ui/demos/pages/toolbars.js | 27 +- vendor/oojs/oojs-ui/demos/pages/widgets.js | 470 ++- vendor/oojs/oojs-ui/demos/styles/demo.css | 12 +- vendor/oojs/oojs-ui/demos/widgets.php | 309 +- vendor/oojs/oojs-ui/i18n/af.json | 8 +- vendor/oojs/oojs-ui/i18n/ar.json | 10 +- vendor/oojs/oojs-ui/i18n/arq.json | 7 +- vendor/oojs/oojs-ui/i18n/as.json | 25 + vendor/oojs/oojs-ui/i18n/ast.json | 9 +- vendor/oojs/oojs-ui/i18n/be-tarask.json | 21 +- vendor/oojs/oojs-ui/i18n/be.json | 17 +- vendor/oojs/oojs-ui/i18n/bg.json | 13 +- vendor/oojs/oojs-ui/i18n/bn.json | 9 +- vendor/oojs/oojs-ui/i18n/bs.json | 5 +- vendor/oojs/oojs-ui/i18n/ca.json | 11 +- vendor/oojs/oojs-ui/i18n/ckb.json | 13 +- vendor/oojs/oojs-ui/i18n/cs.json | 4 +- vendor/oojs/oojs-ui/i18n/cu.json | 3 +- vendor/oojs/oojs-ui/i18n/da.json | 7 +- vendor/oojs/oojs-ui/i18n/de.json | 6 +- vendor/oojs/oojs-ui/i18n/dty.json | 18 + vendor/oojs/oojs-ui/i18n/el.json | 8 +- vendor/oojs/oojs-ui/i18n/en-ca.json | 22 + vendor/oojs/oojs-ui/i18n/en.json | 6 +- vendor/oojs/oojs-ui/i18n/eo.json | 17 +- vendor/oojs/oojs-ui/i18n/es.json | 6 +- vendor/oojs/oojs-ui/i18n/et.json | 9 +- vendor/oojs/oojs-ui/i18n/eu.json | 10 +- vendor/oojs/oojs-ui/i18n/fa.json | 15 +- vendor/oojs/oojs-ui/i18n/fi.json | 14 +- vendor/oojs/oojs-ui/i18n/fr.json | 18 +- vendor/oojs/oojs-ui/i18n/gl.json | 6 +- vendor/oojs/oojs-ui/i18n/glk.json | 23 + vendor/oojs/oojs-ui/i18n/gu.json | 12 +- vendor/oojs/oojs-ui/i18n/he.json | 6 +- vendor/oojs/oojs-ui/i18n/hi.json | 7 +- vendor/oojs/oojs-ui/i18n/hrx.json | 12 + vendor/oojs/oojs-ui/i18n/hu-formal.json | 21 + vendor/oojs/oojs-ui/i18n/hu.json | 10 +- vendor/oojs/oojs-ui/i18n/hy.json | 7 +- vendor/oojs/oojs-ui/i18n/ia.json | 9 +- vendor/oojs/oojs-ui/i18n/id.json | 4 +- vendor/oojs/oojs-ui/i18n/ilo.json | 4 +- vendor/oojs/oojs-ui/i18n/is.json | 6 +- vendor/oojs/oojs-ui/i18n/it.json | 13 +- vendor/oojs/oojs-ui/i18n/ja.json | 9 +- vendor/oojs/oojs-ui/i18n/jv.json | 18 +- vendor/oojs/oojs-ui/i18n/ka.json | 4 +- vendor/oojs/oojs-ui/i18n/km.json | 23 +- vendor/oojs/oojs-ui/i18n/ko.json | 13 +- vendor/oojs/oojs-ui/i18n/krc.json | 4 +- vendor/oojs/oojs-ui/i18n/krl.json | 10 + vendor/oojs/oojs-ui/i18n/ksh.json | 5 +- vendor/oojs/oojs-ui/i18n/ku-latn.json | 7 +- vendor/oojs/oojs-ui/i18n/la.json | 15 + vendor/oojs/oojs-ui/i18n/lb.json | 5 +- vendor/oojs/oojs-ui/i18n/li.json | 21 + vendor/oojs/oojs-ui/i18n/lt.json | 20 +- vendor/oojs/oojs-ui/i18n/luz.json | 21 + vendor/oojs/oojs-ui/i18n/mk.json | 6 +- vendor/oojs/oojs-ui/i18n/ml.json | 18 +- vendor/oojs/oojs-ui/i18n/mr.json | 11 +- vendor/oojs/oojs-ui/i18n/ms.json | 11 +- vendor/oojs/oojs-ui/i18n/nap.json | 21 +- vendor/oojs/oojs-ui/i18n/nb.json | 6 +- vendor/oojs/oojs-ui/i18n/nl.json | 4 +- vendor/oojs/oojs-ui/i18n/oc.json | 9 +- vendor/oojs/oojs-ui/i18n/olo.json | 23 + vendor/oojs/oojs-ui/i18n/om.json | 4 +- vendor/oojs/oojs-ui/i18n/or.json | 7 +- vendor/oojs/oojs-ui/i18n/pa.json | 9 +- vendor/oojs/oojs-ui/i18n/pl.json | 11 +- vendor/oojs/oojs-ui/i18n/pms.json | 13 +- vendor/oojs/oojs-ui/i18n/ps.json | 6 +- vendor/oojs/oojs-ui/i18n/pt-br.json | 17 +- vendor/oojs/oojs-ui/i18n/pt.json | 8 +- vendor/oojs/oojs-ui/i18n/qqq.json | 6 +- vendor/oojs/oojs-ui/i18n/ro.json | 6 +- vendor/oojs/oojs-ui/i18n/roa-tara.json | 6 +- vendor/oojs/oojs-ui/i18n/ru.json | 9 +- vendor/oojs/oojs-ui/i18n/sa.json | 14 + vendor/oojs/oojs-ui/i18n/sah.json | 16 +- vendor/oojs/oojs-ui/i18n/sco.json | 15 +- vendor/oojs/oojs-ui/i18n/sh.json | 14 +- vendor/oojs/oojs-ui/i18n/sk.json | 14 +- vendor/oojs/oojs-ui/i18n/sl.json | 4 +- vendor/oojs/oojs-ui/i18n/sq.json | 11 +- vendor/oojs/oojs-ui/i18n/sr-ec.json | 4 +- vendor/oojs/oojs-ui/i18n/su.json | 21 + vendor/oojs/oojs-ui/i18n/sv.json | 9 +- vendor/oojs/oojs-ui/i18n/ta.json | 17 +- vendor/oojs/oojs-ui/i18n/te.json | 11 +- vendor/oojs/oojs-ui/i18n/tl.json | 13 +- vendor/oojs/oojs-ui/i18n/uk.json | 10 +- vendor/oojs/oojs-ui/i18n/vec.json | 11 +- vendor/oojs/oojs-ui/i18n/vi.json | 13 +- vendor/oojs/oojs-ui/i18n/xmf.json | 19 + vendor/oojs/oojs-ui/i18n/yi.json | 7 +- vendor/oojs/oojs-ui/i18n/yue.json | 16 +- vendor/oojs/oojs-ui/i18n/zh-hans.json | 17 +- vendor/oojs/oojs-ui/i18n/zh-hant.json | 9 +- vendor/oojs/oojs-ui/jsduck.categories.json | 80 - vendor/oojs/oojs-ui/jsduck.eg-iframe.html | 33 - vendor/oojs/oojs-ui/jsduck.external.js | 26 - vendor/oojs/oojs-ui/jsduck.json | 16 - vendor/oojs/oojs-ui/php/Element.php | 48 +- vendor/oojs/oojs-ui/php/HtmlSnippet.php | 2 +- vendor/oojs/oojs-ui/php/Tag.php | 20 +- vendor/oojs/oojs-ui/php/Theme.php | 26 +- vendor/oojs/oojs-ui/php/Widget.php | 10 + vendor/oojs/oojs-ui/php/elements/ButtonElement.php | 102 - .../oojs/oojs-ui/php/elements/FlaggedElement.php | 133 - vendor/oojs/oojs-ui/php/elements/GroupElement.php | 129 - vendor/oojs/oojs-ui/php/elements/IconElement.php | 76 - .../oojs/oojs-ui/php/elements/IndicatorElement.php | 78 - vendor/oojs/oojs-ui/php/elements/LabelElement.php | 77 - .../oojs-ui/php/elements/TabIndexedElement.php | 88 - vendor/oojs/oojs-ui/php/elements/TitledElement.php | 74 - .../oojs/oojs-ui/php/layouts/ActionFieldLayout.php | 55 + vendor/oojs/oojs-ui/php/layouts/FieldLayout.php | 73 +- vendor/oojs/oojs-ui/php/layouts/FormLayout.php | 2 +- .../oojs/oojs-ui/php/layouts/HorizontalLayout.php | 27 + .../oojs/oojs-ui/php/mixins/AccessKeyedElement.php | 76 + vendor/oojs/oojs-ui/php/mixins/ButtonElement.php | 69 + vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php | 133 + vendor/oojs/oojs-ui/php/mixins/GroupElement.php | 129 + vendor/oojs/oojs-ui/php/mixins/IconElement.php | 76 + .../oojs/oojs-ui/php/mixins/IndicatorElement.php | 78 + vendor/oojs/oojs-ui/php/mixins/LabelElement.php | 77 + .../oojs/oojs-ui/php/mixins/TabIndexedElement.php | 88 + vendor/oojs/oojs-ui/php/mixins/TitledElement.php | 74 + .../oojs/oojs-ui/php/widgets/ButtonInputWidget.php | 14 +- vendor/oojs/oojs-ui/php/widgets/ButtonWidget.php | 2 + .../oojs-ui/php/widgets/CheckboxInputWidget.php | 2 + .../oojs-ui/php/widgets/DropdownInputWidget.php | 11 +- vendor/oojs/oojs-ui/php/widgets/IconWidget.php | 2 +- .../oojs/oojs-ui/php/widgets/IndicatorWidget.php | 2 +- vendor/oojs/oojs-ui/php/widgets/InputWidget.php | 10 +- vendor/oojs/oojs-ui/php/widgets/LabelWidget.php | 2 +- .../oojs/oojs-ui/php/widgets/RadioInputWidget.php | 2 + .../oojs-ui/php/widgets/RadioSelectInputWidget.php | 127 + .../oojs/oojs-ui/php/widgets/TextInputWidget.php | 63 +- vendor/oojs/oojs-ui/src/ActionSet.js | 504 --- vendor/oojs/oojs-ui/src/Dialog.js | 323 -- vendor/oojs/oojs-ui/src/Element.js | 748 ---- vendor/oojs/oojs-ui/src/Error.js | 91 - vendor/oojs/oojs-ui/src/HtmlSnippet.js | 29 - vendor/oojs/oojs-ui/src/Layout.js | 33 - vendor/oojs/oojs-ui/src/Process.js | 166 - vendor/oojs/oojs-ui/src/Theme.js | 48 - vendor/oojs/oojs-ui/src/Tool.js | 279 -- vendor/oojs/oojs-ui/src/ToolFactory.js | 120 - vendor/oojs/oojs-ui/src/ToolGroup.js | 338 -- vendor/oojs/oojs-ui/src/ToolGroupFactory.js | 38 - vendor/oojs/oojs-ui/src/Toolbar.js | 481 --- vendor/oojs/oojs-ui/src/Widget.js | 102 - vendor/oojs/oojs-ui/src/Window.js | 628 ---- vendor/oojs/oojs-ui/src/WindowManager.js | 675 ---- vendor/oojs/oojs-ui/src/core.js | 286 -- vendor/oojs/oojs-ui/src/dialogs/MessageDialog.js | 325 -- vendor/oojs/oojs-ui/src/dialogs/ProcessDialog.js | 296 -- vendor/oojs/oojs-ui/src/elements/ButtonElement.js | 263 -- .../oojs/oojs-ui/src/elements/ClippableElement.js | 205 -- .../oojs/oojs-ui/src/elements/DraggableElement.js | 142 - .../oojs-ui/src/elements/DraggableGroupElement.js | 261 -- vendor/oojs/oojs-ui/src/elements/FlaggedElement.js | 209 -- vendor/oojs/oojs-ui/src/elements/GroupElement.js | 290 -- vendor/oojs/oojs-ui/src/elements/IconElement.js | 187 - .../oojs/oojs-ui/src/elements/IndicatorElement.js | 168 - vendor/oojs/oojs-ui/src/elements/LabelElement.js | 152 - vendor/oojs/oojs-ui/src/elements/LookupElement.js | 352 -- vendor/oojs/oojs-ui/src/elements/PendingElement.js | 84 - vendor/oojs/oojs-ui/src/elements/PopupElement.js | 36 - .../oojs/oojs-ui/src/elements/TabIndexedElement.js | 138 - vendor/oojs/oojs-ui/src/elements/TitledElement.js | 106 - vendor/oojs/oojs-ui/src/intro.js.txt | 3 - .../oojs/oojs-ui/src/layouts/ActionFieldLayout.js | 81 - vendor/oojs/oojs-ui/src/layouts/BookletLayout.js | 542 --- vendor/oojs/oojs-ui/src/layouts/CardLayout.js | 138 - vendor/oojs/oojs-ui/src/layouts/FieldLayout.js | 160 - vendor/oojs/oojs-ui/src/layouts/FieldsetLayout.js | 86 - vendor/oojs/oojs-ui/src/layouts/FormLayout.js | 119 - vendor/oojs/oojs-ui/src/layouts/IndexLayout.js | 452 --- vendor/oojs/oojs-ui/src/layouts/MenuLayout.js | 156 - vendor/oojs/oojs-ui/src/layouts/PageLayout.js | 138 - vendor/oojs/oojs-ui/src/layouts/PanelLayout.js | 55 - vendor/oojs/oojs-ui/src/layouts/StackLayout.js | 214 -- vendor/oojs/oojs-ui/src/outro.js.txt | 1 - vendor/oojs/oojs-ui/src/styles/Dialog.less | 35 - vendor/oojs/oojs-ui/src/styles/Element.less | 9 - vendor/oojs/oojs-ui/src/styles/Layout.less | 5 - vendor/oojs/oojs-ui/src/styles/Tool.less | 5 - vendor/oojs/oojs-ui/src/styles/ToolGroup.less | 21 - vendor/oojs/oojs-ui/src/styles/Toolbar.less | 52 - vendor/oojs/oojs-ui/src/styles/Widget.less | 5 - vendor/oojs/oojs-ui/src/styles/Window.less | 32 - vendor/oojs/oojs-ui/src/styles/WindowManager.less | 39 - vendor/oojs/oojs-ui/src/styles/common.less | 102 - vendor/oojs/oojs-ui/src/styles/core.less | 114 - .../oojs-ui/src/styles/dialogs/MessageDialog.less | 45 - .../oojs-ui/src/styles/dialogs/ProcessDialog.less | 52 - .../oojs-ui/src/styles/elements/ButtonElement.less | 62 - .../src/styles/elements/ClippableElement.less | 7 - .../src/styles/elements/DraggableElement.less | 22 - .../src/styles/elements/DraggableGroupElement.less | 11 - .../src/styles/elements/FlaggedElement.less | 5 - .../oojs-ui/src/styles/elements/GroupElement.less | 5 - .../oojs-ui/src/styles/elements/IconElement.less | 5 - .../src/styles/elements/IndicatorElement.less | 5 - .../oojs-ui/src/styles/elements/LabelElement.less | 5 - .../oojs-ui/src/styles/elements/LookupElement.less | 10 - .../oojs-ui/src/styles/elements/PopupElement.less | 5 - .../src/styles/elements/TabIndexedElement.less | 5 - .../oojs-ui/src/styles/elements/TitledElement.less | 5 - vendor/oojs/oojs-ui/src/styles/images/grab.cur | Bin 326 -> 0 bytes vendor/oojs/oojs-ui/src/styles/images/grabbing.cur | Bin 326 -> 0 bytes .../src/styles/layouts/ActionFieldLayout.less | 26 - .../oojs-ui/src/styles/layouts/BookletLayout.less | 43 - .../oojs-ui/src/styles/layouts/CardLayout.less | 5 - .../oojs-ui/src/styles/layouts/FieldLayout.less | 59 - .../oojs-ui/src/styles/layouts/FieldsetLayout.less | 31 - .../oojs-ui/src/styles/layouts/FormLayout.less | 5 - .../oojs-ui/src/styles/layouts/IndexLayout.less | 13 - .../oojs-ui/src/styles/layouts/MenuLayout.less | 108 - .../oojs-ui/src/styles/layouts/PageLayout.less | 5 - .../oojs-ui/src/styles/layouts/PanelLayout.less | 19 - .../oojs-ui/src/styles/layouts/StackLayout.less | 10 - vendor/oojs/oojs-ui/src/styles/theme.less | 91 - .../src/styles/toolgroups/BarToolGroup.less | 51 - .../src/styles/toolgroups/ListToolGroup.less | 21 - .../src/styles/toolgroups/MenuToolGroup.less | 19 - .../src/styles/toolgroups/PopupToolGroup.less | 73 - .../oojs/oojs-ui/src/styles/tools/PopupTool.less | 12 - .../oojs-ui/src/styles/tools/ToolGroupTool.less | 5 - .../oojs-ui/src/styles/widgets/ActionWidget.less | 5 - .../src/styles/widgets/ButtonGroupWidget.less | 5 - .../src/styles/widgets/ButtonInputWidget.less | 8 - .../src/styles/widgets/ButtonOptionWidget.less | 18 - .../src/styles/widgets/ButtonSelectWidget.less | 8 - .../oojs-ui/src/styles/widgets/ButtonWidget.less | 8 - .../src/styles/widgets/CheckboxInputWidget.less | 5 - .../oojs-ui/src/styles/widgets/ComboBoxWidget.less | 13 - .../src/styles/widgets/DecoratedOptionWidget.less | 12 - .../src/styles/widgets/DropdownInputWidget.less | 17 - .../oojs-ui/src/styles/widgets/DropdownWidget.less | 33 - .../oojs-ui/src/styles/widgets/IconWidget.less | 10 - .../src/styles/widgets/IndicatorWidget.less | 10 - .../oojs-ui/src/styles/widgets/InputWidget.less | 5 - .../oojs-ui/src/styles/widgets/LabelWidget.less | 7 - .../src/styles/widgets/MenuOptionWidget.less | 21 - .../styles/widgets/MenuSectionOptionWidget.less | 8 - .../src/styles/widgets/MenuSelectWidget.less | 15 - .../oojs-ui/src/styles/widgets/OptionWidget.less | 20 - .../src/styles/widgets/OutlineControlsWidget.less | 32 - .../src/styles/widgets/OutlineOptionWidget.less | 9 - .../src/styles/widgets/OutlineSelectWidget.less | 5 - .../src/styles/widgets/PopupButtonWidget.less | 12 - .../oojs-ui/src/styles/widgets/PopupWidget.less | 49 - .../src/styles/widgets/ProgressBarWidget.less | 5 - .../src/styles/widgets/RadioInputWidget.less | 5 - .../src/styles/widgets/RadioOptionWidget.less | 13 - .../src/styles/widgets/RadioSelectWidget.less | 5 - .../oojs-ui/src/styles/widgets/SearchWidget.less | 25 - .../oojs-ui/src/styles/widgets/SelectWidget.less | 5 - .../src/styles/widgets/TabOptionWidget.less | 8 - .../src/styles/widgets/TabSelectWidget.less | 9 - .../styles/widgets/TextInputMenuSelectWidget.less | 5 - .../src/styles/widgets/TextInputWidget.less | 71 - .../src/styles/widgets/ToggleButtonWidget.less | 8 - .../src/styles/widgets/ToggleSwitchWidget.less | 41 - .../oojs-ui/src/styles/widgets/ToggleWidget.less | 5 - vendor/oojs/oojs-ui/src/themes/apex/ApexTheme.js | 18 - vendor/oojs/oojs-ui/src/themes/apex/common.less | 27 - vendor/oojs/oojs-ui/src/themes/apex/core.less | 12 - vendor/oojs/oojs-ui/src/themes/apex/elements.less | 247 -- .../src/themes/apex/icons-editing-advanced.json | 75 - .../src/themes/apex/icons-editing-core.json | 24 - .../src/themes/apex/icons-editing-list.json | 22 - .../src/themes/apex/icons-editing-styling.json | 72 - .../oojs-ui/src/themes/apex/icons-moderation.json | 33 - .../oojs-ui/src/themes/apex/icons-movement.json | 27 - vendor/oojs/oojs-ui/src/themes/apex/icons.json | 50 - .../oojs-ui/src/themes/apex/images/icons/add.svg | 6 - .../src/themes/apex/images/icons/advanced.svg | 6 - .../oojs-ui/src/themes/apex/images/icons/alert.svg | 8 - .../src/themes/apex/images/icons/align-center.svg | 6 - .../themes/apex/images/icons/align-float-left.svg | 6 - .../themes/apex/images/icons/align-float-right.svg | 6 - .../themes/apex/images/icons/arched-arrow-ltr.svg | 6 - .../themes/apex/images/icons/arched-arrow-rtl.svg | 6 - .../src/themes/apex/images/icons/arrow-ltr.svg | 6 - .../src/themes/apex/images/icons/arrow-rtl.svg | 6 - .../src/themes/apex/images/icons/bigger-ltr.svg | 7 - .../src/themes/apex/images/icons/bigger-rtl.svg | 7 - .../oojs-ui/src/themes/apex/images/icons/block.svg | 4 - .../src/themes/apex/images/icons/blockUndo-ltr.svg | 6 - .../src/themes/apex/images/icons/blockUndo-rtl.svg | 6 - .../src/themes/apex/images/icons/bold-a.svg | 6 - .../src/themes/apex/images/icons/bold-arab-ain.svg | 6 - .../src/themes/apex/images/icons/bold-arab-dad.svg | 6 - .../src/themes/apex/images/icons/bold-armn-to.svg | 6 - .../src/themes/apex/images/icons/bold-b.svg | 6 - .../src/themes/apex/images/icons/bold-cyrl-be.svg | 6 - .../src/themes/apex/images/icons/bold-cyrl-te.svg | 6 - .../src/themes/apex/images/icons/bold-cyrl-zhe.svg | 6 - .../src/themes/apex/images/icons/bold-f.svg | 6 - .../src/themes/apex/images/icons/bold-g.svg | 6 - .../src/themes/apex/images/icons/bold-geor-man.svg | 6 - .../src/themes/apex/images/icons/bold-l.svg | 6 - .../src/themes/apex/images/icons/bold-n.svg | 6 - .../src/themes/apex/images/icons/bold-v.svg | 6 - .../src/themes/apex/images/icons/cancel.svg | 6 - .../src/themes/apex/images/icons/caret-ltr.svg | 4 - .../src/themes/apex/images/icons/caret-rtl.svg | 4 - .../src/themes/apex/images/icons/caretDown.svg | 4 - .../src/themes/apex/images/icons/caretUp.svg | 4 - .../themes/apex/images/icons/case-sensitive.svg | 7 - .../oojs-ui/src/themes/apex/images/icons/check.svg | 6 - .../src/themes/apex/images/icons/circle.svg | 2 - .../oojs-ui/src/themes/apex/images/icons/close.svg | 6 - .../oojs-ui/src/themes/apex/images/icons/code.svg | 7 - .../src/themes/apex/images/icons/collapse.svg | 6 - .../src/themes/apex/images/icons/comment.svg | 6 - .../src/themes/apex/images/icons/downTriangle.svg | 4 - .../src/themes/apex/images/icons/edit-ltr.svg | 6 - .../src/themes/apex/images/icons/edit-rtl.svg | 6 - .../src/themes/apex/images/icons/editLock-ltr.svg | 8 - .../src/themes/apex/images/icons/editLock-rtl.svg | 8 - .../src/themes/apex/images/icons/editUndo-ltr.svg | 11 - .../src/themes/apex/images/icons/editUndo-rtl.svg | 11 - .../src/themes/apex/images/icons/ellipsis.svg | 14 - .../src/themes/apex/images/icons/expand.svg | 6 - .../themes/apex/images/icons/external-link-ltr.svg | 7 - .../themes/apex/images/icons/external-link-rtl.svg | 7 - .../src/themes/apex/images/icons/find-ltr.svg | 7 - .../src/themes/apex/images/icons/find-rtl.svg | 7 - .../src/themes/apex/images/icons/flag-ltr.svg | 4 - .../src/themes/apex/images/icons/flag-rtl.svg | 4 - .../src/themes/apex/images/icons/flagUndo-ltr.svg | 16 - .../src/themes/apex/images/icons/flagUndo-rtl.svg | 16 - .../src/themes/apex/images/icons/help-ltr.svg | 10 - .../src/themes/apex/images/icons/help-rtl.svg | 10 - .../src/themes/apex/images/icons/history.svg | 7 - .../src/themes/apex/images/icons/indent-ltr.svg | 9 - .../src/themes/apex/images/icons/indent-rtl.svg | 9 - .../oojs-ui/src/themes/apex/images/icons/info.svg | 6 - .../src/themes/apex/images/icons/insert.svg | 6 - .../src/themes/apex/images/icons/italic-a.svg | 6 - .../apex/images/icons/italic-arab-keheh-jeem.svg | 6 - .../themes/apex/images/icons/italic-arab-meem.svg | 6 - .../themes/apex/images/icons/italic-armn-sha.svg | 6 - .../src/themes/apex/images/icons/italic-c.svg | 6 - .../src/themes/apex/images/icons/italic-d.svg | 6 - .../src/themes/apex/images/icons/italic-e.svg | 6 - .../themes/apex/images/icons/italic-geor-kan.svg | 6 - .../src/themes/apex/images/icons/italic-i.svg | 6 - .../src/themes/apex/images/icons/italic-k.svg | 6 - .../src/themes/apex/images/icons/italic-s.svg | 6 - .../src/themes/apex/images/icons/language.svg | 7 - .../src/themes/apex/images/icons/layout-ltr.svg | 7 - .../src/themes/apex/images/icons/layout-rtl.svg | 7 - .../oojs-ui/src/themes/apex/images/icons/link.svg | 8 - .../themes/apex/images/icons/listBullet-ltr.svg | 11 - .../themes/apex/images/icons/listBullet-rtl.svg | 11 - .../themes/apex/images/icons/listNumbered-ltr.svg | 11 - .../themes/apex/images/icons/listNumbered-rtl.svg | 11 - .../oojs-ui/src/themes/apex/images/icons/lock.svg | 6 - .../oojs-ui/src/themes/apex/images/icons/menu.svg | 6 - .../src/themes/apex/images/icons/move-ltr.svg | 6 - .../src/themes/apex/images/icons/move-rtl.svg | 6 - .../oojs-ui/src/themes/apex/images/icons/move.svg | 4 - .../src/themes/apex/images/icons/newline-ltr.svg | 6 - .../src/themes/apex/images/icons/newline-rtl.svg | 6 - .../themes/apex/images/icons/noWikiText-ltr.svg | 6 - .../themes/apex/images/icons/noWikiText-rtl.svg | 6 - .../src/themes/apex/images/icons/outdent-ltr.svg | 9 - .../src/themes/apex/images/icons/outdent-rtl.svg | 9 - .../src/themes/apex/images/icons/outline-ltr.svg | 7 - .../src/themes/apex/images/icons/outline-rtl.svg | 7 - .../src/themes/apex/images/icons/picture.svg | 8 - .../src/themes/apex/images/icons/puzzle-ltr.svg | 4 - .../src/themes/apex/images/icons/puzzle-rtl.svg | 4 - .../src/themes/apex/images/icons/quotes-ltr.svg | 6 - .../src/themes/apex/images/icons/quotes-rtl.svg | 6 - .../src/themes/apex/images/icons/quotesAdd-ltr.svg | 6 - .../src/themes/apex/images/icons/quotesAdd-rtl.svg | 6 - .../src/themes/apex/images/icons/redirect-ltr.svg | 8 - .../src/themes/apex/images/icons/redirect-rtl.svg | 9 - .../apex/images/icons/regular-expression.svg | 9 - .../src/themes/apex/images/icons/remove.svg | 6 - .../src/themes/apex/images/icons/search.svg | 6 - .../src/themes/apex/images/icons/secure-link.svg | 6 - .../src/themes/apex/images/icons/settings.svg | 6 - .../src/themes/apex/images/icons/smaller-ltr.svg | 7 - .../src/themes/apex/images/icons/smaller-rtl.svg | 7 - .../themes/apex/images/icons/specialCharacter.svg | 6 - .../oojs-ui/src/themes/apex/images/icons/star.svg | 4 - .../themes/apex/images/icons/strikethrough-a.svg | 7 - .../themes/apex/images/icons/strikethrough-s.svg | 7 - .../themes/apex/images/icons/strikethrough-y.svg | 7 - .../src/themes/apex/images/icons/subscript-ltr.svg | 5 - .../src/themes/apex/images/icons/subscript-rtl.svg | 5 - .../themes/apex/images/icons/superscript-ltr.svg | 5 - .../themes/apex/images/icons/superscript-rtl.svg | 5 - .../src/themes/apex/images/icons/table-caption.svg | 7 - .../apex/images/icons/table-insert-column-ltr.svg | 11 - .../apex/images/icons/table-insert-column-rtl.svg | 11 - .../apex/images/icons/table-insert-row-after.svg | 11 - .../apex/images/icons/table-insert-row-before.svg | 11 - .../themes/apex/images/icons/table-merge-cells.svg | 10 - .../oojs-ui/src/themes/apex/images/icons/table.svg | 7 - .../oojs-ui/src/themes/apex/images/icons/tag.svg | 6 - .../themes/apex/images/icons/templateAdd-ltr.svg | 7 - .../themes/apex/images/icons/templateAdd-rtl.svg | 7 - .../apex/images/icons/text-dir-lefttoright.svg | 6 - .../apex/images/icons/text-dir-righttoleft.svg | 6 - .../src/themes/apex/images/icons/text-style.svg | 7 - .../themes/apex/images/icons/translation-ltr.svg | 4 - .../themes/apex/images/icons/translation-rtl.svg | 4 - .../oojs-ui/src/themes/apex/images/icons/trash.svg | 4 - .../src/themes/apex/images/icons/trashUndo-ltr.svg | 6 - .../src/themes/apex/images/icons/trashUndo-rtl.svg | 6 - .../src/themes/apex/images/icons/unLock-ltr.svg | 4 - .../src/themes/apex/images/icons/unLock-rtl.svg | 4 - .../src/themes/apex/images/icons/unStar.svg | 4 - .../src/themes/apex/images/icons/underline-a.svg | 7 - .../src/themes/apex/images/icons/underline-u.svg | 7 - .../src/themes/apex/images/icons/upTriangle.svg | 4 - .../src/themes/apex/images/icons/wikiText.svg | 15 - .../src/themes/apex/images/icons/window.svg | 7 - .../src/themes/apex/images/indicators/alert.svg | 6 - .../themes/apex/images/indicators/arrow-down.svg | 6 - .../themes/apex/images/indicators/arrow-ltr.svg | 6 - .../themes/apex/images/indicators/arrow-rtl.svg | 6 - .../src/themes/apex/images/indicators/arrow-up.svg | 6 - .../src/themes/apex/images/indicators/required.svg | 6 - .../themes/apex/images/indicators/search-ltr.svg | 6 - .../themes/apex/images/indicators/search-rtl.svg | 6 - .../src/themes/apex/images/textures/pending.gif | Bin 2032 -> 0 bytes .../themes/apex/images/textures/transparency.svg | 10 - .../src/themes/apex/images/toolbar-shadow.png | Bin 131 -> 0 bytes .../oojs/oojs-ui/src/themes/apex/indicators.json | 22 - vendor/oojs/oojs-ui/src/themes/apex/layouts.less | 135 - vendor/oojs/oojs-ui/src/themes/apex/textures.json | 8 - vendor/oojs/oojs-ui/src/themes/apex/tools.less | 422 --- vendor/oojs/oojs-ui/src/themes/apex/widgets.less | 797 ----- vendor/oojs/oojs-ui/src/themes/apex/windows.less | 307 -- vendor/oojs/oojs-ui/src/themes/blank/BlankTheme.js | 32 - vendor/oojs/oojs-ui/src/themes/blank/common.less | 10 - vendor/oojs/oojs-ui/src/themes/blank/core.less | 12 - vendor/oojs/oojs-ui/src/themes/blank/elements.less | 29 - .../src/themes/blank/images/icons/README.txt | 1 - .../src/themes/blank/images/indicators/README.txt | 1 - .../src/themes/blank/images/textures/README.txt | 1 - vendor/oojs/oojs-ui/src/themes/blank/layouts.less | 26 - vendor/oojs/oojs-ui/src/themes/blank/tools.less | 20 - vendor/oojs/oojs-ui/src/themes/blank/widgets.less | 77 - vendor/oojs/oojs-ui/src/themes/blank/windows.less | 11 - .../oojs-ui/src/themes/mediawiki/MediaWikiTheme.js | 56 - .../oojs/oojs-ui/src/themes/mediawiki/common.less | 69 - vendor/oojs/oojs-ui/src/themes/mediawiki/core.less | 12 - .../oojs-ui/src/themes/mediawiki/elements.less | 319 -- .../oojs-ui/src/themes/mediawiki/icons-alerts.json | 33 - .../src/themes/mediawiki/icons-content.json | 50 - .../themes/mediawiki/icons-editing-advanced.json | 75 - .../src/themes/mediawiki/icons-editing-core.json | 45 - .../src/themes/mediawiki/icons-editing-list.json | 22 - .../themes/mediawiki/icons-editing-styling.json | 72 - .../src/themes/mediawiki/icons-interactions.json | 52 - .../oojs-ui/src/themes/mediawiki/icons-layout.json | 43 - .../src/themes/mediawiki/icons-location.json | 19 - .../oojs-ui/src/themes/mediawiki/icons-media.json | 27 - .../src/themes/mediawiki/icons-moderation.json | 52 - .../src/themes/mediawiki/icons-movement.json | 27 - .../oojs-ui/src/themes/mediawiki/icons-user.json | 19 - .../src/themes/mediawiki/icons-wikimedia.json | 9 - .../oojs/oojs-ui/src/themes/mediawiki/icons.json | 75 - .../src/themes/mediawiki/images/icons/add.svg | 6 - .../src/themes/mediawiki/images/icons/advanced.svg | 4 - .../src/themes/mediawiki/images/icons/alert.svg | 8 - .../themes/mediawiki/images/icons/align-center.svg | 6 - .../mediawiki/images/icons/align-float-left.svg | 6 - .../mediawiki/images/icons/align-float-right.svg | 6 - .../mediawiki/images/icons/arched-arrow-ltr.svg | 6 - .../mediawiki/images/icons/arched-arrow-rtl.svg | 6 - .../themes/mediawiki/images/icons/arrow-ltr.svg | 6 - .../themes/mediawiki/images/icons/arrow-rtl.svg | 6 - .../themes/mediawiki/images/icons/article-ltr.svg | 6 - .../themes/mediawiki/images/icons/article-rtl.svg | 6 - .../mediawiki/images/icons/articleCheck-ltr.svg | 9 - .../mediawiki/images/icons/articleCheck-rtl.svg | 9 - .../mediawiki/images/icons/articleSearch-ltr.svg | 6 - .../mediawiki/images/icons/articleSearch-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/bell.svg | 4 - .../themes/mediawiki/images/icons/bellOn-ltr.svg | 4 - .../themes/mediawiki/images/icons/bellOn-rtl.svg | 4 - .../src/themes/mediawiki/images/icons/beta.svg | 4 - .../themes/mediawiki/images/icons/betaLaunch.svg | 4 - .../themes/mediawiki/images/icons/bigger-ltr.svg | 7 - .../themes/mediawiki/images/icons/bigger-rtl.svg | 7 - .../src/themes/mediawiki/images/icons/block.svg | 4 - .../mediawiki/images/icons/blockUndo-ltr.svg | 6 - .../mediawiki/images/icons/blockUndo-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/bold-a.svg | 6 - .../mediawiki/images/icons/bold-arab-ain.svg | 6 - .../mediawiki/images/icons/bold-arab-dad.svg | 6 - .../themes/mediawiki/images/icons/bold-armn-to.svg | 6 - .../src/themes/mediawiki/images/icons/bold-b.svg | 6 - .../themes/mediawiki/images/icons/bold-cyrl-be.svg | 6 - .../themes/mediawiki/images/icons/bold-cyrl-te.svg | 6 - .../mediawiki/images/icons/bold-cyrl-zhe.svg | 6 - .../src/themes/mediawiki/images/icons/bold-f.svg | 6 - .../src/themes/mediawiki/images/icons/bold-g.svg | 6 - .../mediawiki/images/icons/bold-geor-man.svg | 6 - .../src/themes/mediawiki/images/icons/bold-l.svg | 6 - .../src/themes/mediawiki/images/icons/bold-n.svg | 6 - .../src/themes/mediawiki/images/icons/bold-v.svg | 6 - .../src/themes/mediawiki/images/icons/book-ltr.svg | 4 - .../src/themes/mediawiki/images/icons/book-rtl.svg | 4 - .../themes/mediawiki/images/icons/bookmark-ltr.svg | 4 - .../themes/mediawiki/images/icons/bookmark-rtl.svg | 4 - .../themes/mediawiki/images/icons/browser-ltr.svg | 4 - .../themes/mediawiki/images/icons/browser-rtl.svg | 4 - .../src/themes/mediawiki/images/icons/cancel.svg | 6 - .../themes/mediawiki/images/icons/caret-ltr.svg | 4 - .../themes/mediawiki/images/icons/caret-rtl.svg | 4 - .../themes/mediawiki/images/icons/caretDown.svg | 4 - .../src/themes/mediawiki/images/icons/caretUp.svg | 4 - .../mediawiki/images/icons/case-sensitive.svg | 7 - .../src/themes/mediawiki/images/icons/check.svg | 6 - .../src/themes/mediawiki/images/icons/circle.svg | 2 - .../mediawiki/images/icons/citeArticle-ltr.svg | 6 - .../mediawiki/images/icons/citeArticle-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/clear.svg | 6 - .../src/themes/mediawiki/images/icons/clock.svg | 6 - .../themes/mediawiki/images/icons/close-ltr.svg | 4 - .../themes/mediawiki/images/icons/close-rtl.svg | 4 - .../src/themes/mediawiki/images/icons/code.svg | 7 - .../src/themes/mediawiki/images/icons/collapse.svg | 6 - .../src/themes/mediawiki/images/icons/comment.svg | 6 - .../src/themes/mediawiki/images/icons/die-ltr.svg | 4 - .../src/themes/mediawiki/images/icons/die-rtl.svg | 4 - .../themes/mediawiki/images/icons/downTriangle.svg | 4 - .../themes/mediawiki/images/icons/download-ltr.svg | 6 - .../themes/mediawiki/images/icons/download-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/edit-ltr.svg | 6 - .../src/themes/mediawiki/images/icons/edit-rtl.svg | 6 - .../themes/mediawiki/images/icons/editLock-ltr.svg | 8 - .../themes/mediawiki/images/icons/editLock-rtl.svg | 8 - .../themes/mediawiki/images/icons/editUndo-ltr.svg | 11 - .../themes/mediawiki/images/icons/editUndo-rtl.svg | 11 - .../src/themes/mediawiki/images/icons/ellipsis.svg | 14 - .../src/themes/mediawiki/images/icons/expand.svg | 6 - .../mediawiki/images/icons/external-link-ltr.svg | 7 - .../mediawiki/images/icons/external-link-rtl.svg | 7 - .../src/themes/mediawiki/images/icons/eye.svg | 7 - .../themes/mediawiki/images/icons/eyeClosed.svg | 4 - .../src/themes/mediawiki/images/icons/find-ltr.svg | 7 - .../src/themes/mediawiki/images/icons/find-rtl.svg | 7 - .../src/themes/mediawiki/images/icons/flag-ltr.svg | 4 - .../src/themes/mediawiki/images/icons/flag-rtl.svg | 4 - .../themes/mediawiki/images/icons/flagUndo-ltr.svg | 16 - .../themes/mediawiki/images/icons/flagUndo-rtl.svg | 16 - .../images/icons/folderPlaceholder-ltr.svg | 4 - .../images/icons/folderPlaceholder-rtl.svg | 4 - .../themes/mediawiki/images/icons/funnel-ltr.svg | 6 - .../themes/mediawiki/images/icons/funnel-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/heart.svg | 4 - .../src/themes/mediawiki/images/icons/help-ltr.svg | 10 - .../src/themes/mediawiki/images/icons/help-rtl.svg | 10 - .../src/themes/mediawiki/images/icons/history.svg | 7 - .../themes/mediawiki/images/icons/image-ltr.svg | 6 - .../themes/mediawiki/images/icons/image-rtl.svg | 6 - .../themes/mediawiki/images/icons/imageAdd-ltr.svg | 7 - .../themes/mediawiki/images/icons/imageAdd-rtl.svg | 7 - .../mediawiki/images/icons/imageLock-ltr.svg | 4 - .../mediawiki/images/icons/imageLock-rtl.svg | 4 - .../themes/mediawiki/images/icons/indent-ltr.svg | 6 - .../themes/mediawiki/images/icons/indent-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/info.svg | 6 - .../src/themes/mediawiki/images/icons/insert.svg | 6 - .../src/themes/mediawiki/images/icons/italic-a.svg | 6 - .../images/icons/italic-arab-keheh-jeem.svg | 6 - .../mediawiki/images/icons/italic-arab-meem.svg | 6 - .../mediawiki/images/icons/italic-armn-sha.svg | 6 - .../src/themes/mediawiki/images/icons/italic-c.svg | 6 - .../src/themes/mediawiki/images/icons/italic-d.svg | 6 - .../src/themes/mediawiki/images/icons/italic-e.svg | 6 - .../mediawiki/images/icons/italic-geor-kan.svg | 6 - .../src/themes/mediawiki/images/icons/italic-i.svg | 6 - .../src/themes/mediawiki/images/icons/italic-k.svg | 6 - .../src/themes/mediawiki/images/icons/italic-s.svg | 6 - .../themes/mediawiki/images/icons/journal-ltr.svg | 4 - .../themes/mediawiki/images/icons/journal-rtl.svg | 4 - .../src/themes/mediawiki/images/icons/key-ltr.svg | 4 - .../src/themes/mediawiki/images/icons/key-rtl.svg | 4 - .../themes/mediawiki/images/icons/keyboard-ltr.svg | 6 - .../themes/mediawiki/images/icons/keyboard-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/language.svg | 7 - .../themes/mediawiki/images/icons/layout-ltr.svg | 7 - .../themes/mediawiki/images/icons/layout-rtl.svg | 7 - .../src/themes/mediawiki/images/icons/link-ltr.svg | 13 - .../src/themes/mediawiki/images/icons/link-rtl.svg | 6 - .../mediawiki/images/icons/listBullet-ltr.svg | 4 - .../mediawiki/images/icons/listBullet-rtl.svg | 4 - .../mediawiki/images/icons/listNumbered-ltr.svg | 4 - .../mediawiki/images/icons/listNumbered-rtl.svg | 4 - .../src/themes/mediawiki/images/icons/lock-ltr.svg | 6 - .../src/themes/mediawiki/images/icons/lock-rtl.svg | 6 - .../themes/mediawiki/images/icons/logOut-ltr.svg | 6 - .../themes/mediawiki/images/icons/logOut-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/logo-cc.svg | 6 - .../images/icons/logo-wikimediaCommons.svg | 7 - .../mediawiki/images/icons/logo-wikipedia.svg | 6 - .../src/themes/mediawiki/images/icons/map-ltr.svg | 4 - .../src/themes/mediawiki/images/icons/map-rtl.svg | 4 - .../src/themes/mediawiki/images/icons/mapPin.svg | 4 - .../mediawiki/images/icons/mapPinAdd-ltr.svg | 9 - .../mediawiki/images/icons/mapPinAdd-rtl.svg | 9 - .../src/themes/mediawiki/images/icons/menu.svg | 10 - .../themes/mediawiki/images/icons/message-ltr.svg | 6 - .../themes/mediawiki/images/icons/message-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/move-ltr.svg | 6 - .../src/themes/mediawiki/images/icons/move-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/move.svg | 4 - .../mediawiki/images/icons/newWindow-ltr.svg | 6 - .../mediawiki/images/icons/newWindow-rtl.svg | 6 - .../themes/mediawiki/images/icons/newline-ltr.svg | 6 - .../themes/mediawiki/images/icons/newline-rtl.svg | 6 - .../mediawiki/images/icons/newspaper-ltr.svg | 4 - .../mediawiki/images/icons/newspaper-rtl.svg | 4 - .../mediawiki/images/icons/noWikiText-ltr.svg | 6 - .../mediawiki/images/icons/noWikiText-rtl.svg | 6 - .../themes/mediawiki/images/icons/outdent-ltr.svg | 6 - .../themes/mediawiki/images/icons/outdent-rtl.svg | 6 - .../themes/mediawiki/images/icons/outline-ltr.svg | 7 - .../themes/mediawiki/images/icons/outline-rtl.svg | 7 - .../mediawiki/images/icons/photoGallery-ltr.svg | 6 - .../mediawiki/images/icons/photoGallery-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/picture.svg | 8 - .../src/themes/mediawiki/images/icons/play-ltr.svg | 6 - .../src/themes/mediawiki/images/icons/play-rtl.svg | 6 - .../themes/mediawiki/images/icons/printer-ltr.svg | 4 - .../themes/mediawiki/images/icons/printer-rtl.svg | 4 - .../themes/mediawiki/images/icons/puzzle-ltr.svg | 4 - .../themes/mediawiki/images/icons/puzzle-rtl.svg | 4 - .../themes/mediawiki/images/icons/quotes-ltr.svg | 11 - .../themes/mediawiki/images/icons/quotes-rtl.svg | 11 - .../mediawiki/images/icons/quotesAdd-ltr.svg | 6 - .../mediawiki/images/icons/quotesAdd-rtl.svg | 6 - .../themes/mediawiki/images/icons/redirect-ltr.svg | 8 - .../themes/mediawiki/images/icons/redirect-rtl.svg | 9 - .../mediawiki/images/icons/regular-expression.svg | 9 - .../src/themes/mediawiki/images/icons/remove.svg | 6 - .../themes/mediawiki/images/icons/ribbonPrize.svg | 9 - .../themes/mediawiki/images/icons/search-ltr.svg | 6 - .../themes/mediawiki/images/icons/search-rtl.svg | 6 - .../themes/mediawiki/images/icons/secure-link.svg | 6 - .../src/themes/mediawiki/images/icons/settings.svg | 6 - .../mediawiki/images/icons/signature-ltr.svg | 4 - .../mediawiki/images/icons/signature-rtl.svg | 4 - .../themes/mediawiki/images/icons/smaller-ltr.svg | 7 - .../themes/mediawiki/images/icons/smaller-rtl.svg | 7 - .../mediawiki/images/icons/specialCharacter.svg | 6 - .../mediawiki/images/icons/speechBubble-ltr.svg | 6 - .../mediawiki/images/icons/speechBubble-rtl.svg | 6 - .../mediawiki/images/icons/speechBubbleAdd-ltr.svg | 7 - .../mediawiki/images/icons/speechBubbleAdd-rtl.svg | 7 - .../mediawiki/images/icons/speechBubbles-ltr.svg | 6 - .../mediawiki/images/icons/speechBubbles-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/star.svg | 4 - .../src/themes/mediawiki/images/icons/stop.svg | 4 - .../mediawiki/images/icons/strikethrough-a.svg | 7 - .../mediawiki/images/icons/strikethrough-s.svg | 7 - .../mediawiki/images/icons/strikethrough-y.svg | 7 - .../mediawiki/images/icons/stripeFlow-ltr.svg | 4 - .../mediawiki/images/icons/stripeFlow-rtl.svg | 4 - .../mediawiki/images/icons/stripeSideMenu.svg | 12 - .../mediawiki/images/icons/stripeSummary-ltr.svg | 6 - .../mediawiki/images/icons/stripeSummary-rtl.svg | 6 - .../mediawiki/images/icons/stripeToC-ltr.svg | 6 - .../mediawiki/images/icons/stripeToC-rtl.svg | 6 - .../mediawiki/images/icons/subscript-ltr.svg | 5 - .../mediawiki/images/icons/subscript-rtl.svg | 5 - .../src/themes/mediawiki/images/icons/sun-ltr.svg | 5 - .../src/themes/mediawiki/images/icons/sun-rtl.svg | 5 - .../mediawiki/images/icons/superscript-ltr.svg | 5 - .../mediawiki/images/icons/superscript-rtl.svg | 5 - .../mediawiki/images/icons/table-caption.svg | 7 - .../images/icons/table-insert-column-ltr.svg | 11 - .../images/icons/table-insert-column-rtl.svg | 11 - .../images/icons/table-insert-row-after.svg | 11 - .../images/icons/table-insert-row-before.svg | 11 - .../mediawiki/images/icons/table-merge-cells.svg | 10 - .../src/themes/mediawiki/images/icons/table.svg | 7 - .../src/themes/mediawiki/images/icons/tag.svg | 6 - .../mediawiki/images/icons/templateAdd-ltr.svg | 7 - .../mediawiki/images/icons/templateAdd-rtl.svg | 7 - .../images/icons/text-dir-lefttoright.svg | 6 - .../images/icons/text-dir-righttoleft.svg | 6 - .../themes/mediawiki/images/icons/text-style.svg | 7 - .../mediawiki/images/icons/translation-ltr.svg | 4 - .../mediawiki/images/icons/translation-rtl.svg | 4 - .../src/themes/mediawiki/images/icons/trash.svg | 4 - .../mediawiki/images/icons/trashUndo-ltr.svg | 6 - .../mediawiki/images/icons/trashUndo-rtl.svg | 6 - .../themes/mediawiki/images/icons/unLock-ltr.svg | 4 - .../themes/mediawiki/images/icons/unLock-rtl.svg | 4 - .../src/themes/mediawiki/images/icons/unStar.svg | 4 - .../themes/mediawiki/images/icons/underline-a.svg | 7 - .../themes/mediawiki/images/icons/underline-u.svg | 7 - .../themes/mediawiki/images/icons/upTriangle.svg | 4 - .../themes/mediawiki/images/icons/upload-ltr.svg | 6 - .../themes/mediawiki/images/icons/upload-rtl.svg | 6 - .../mediawiki/images/icons/userActive-ltr.svg | 4 - .../mediawiki/images/icons/userActive-rtl.svg | 4 - .../themes/mediawiki/images/icons/userAvatar.svg | 8 - .../mediawiki/images/icons/userInactive-ltr.svg | 4 - .../mediawiki/images/icons/userInactive-rtl.svg | 4 - .../themes/mediawiki/images/icons/userTalk-ltr.svg | 4 - .../themes/mediawiki/images/icons/userTalk-rtl.svg | 4 - .../themes/mediawiki/images/icons/viewCompact.svg | 14 - .../mediawiki/images/icons/viewDetails-ltr.svg | 9 - .../mediawiki/images/icons/viewDetails-rtl.svg | 9 - .../mediawiki/images/icons/visionSimulator.svg | 4 - .../mediawiki/images/icons/watchlist-ltr.svg | 6 - .../mediawiki/images/icons/watchlist-rtl.svg | 6 - .../src/themes/mediawiki/images/icons/wikiText.svg | 15 - .../mediawiki/images/icons/wikitrail-ltr.svg | 8 - .../mediawiki/images/icons/wikitrail-rtl.svg | 8 - .../src/themes/mediawiki/images/icons/window.svg | 7 - .../themes/mediawiki/images/indicators/alert.svg | 6 - .../mediawiki/images/indicators/arrow-down.svg | 8 - .../mediawiki/images/indicators/arrow-ltr.svg | 8 - .../mediawiki/images/indicators/arrow-rtl.svg | 8 - .../mediawiki/images/indicators/arrow-up.svg | 8 - .../mediawiki/images/indicators/required.svg | 6 - .../mediawiki/images/indicators/search-ltr.svg | 6 - .../mediawiki/images/indicators/search-rtl.svg | 6 - .../themes/mediawiki/images/textures/pending.gif | Bin 2032 -> 0 bytes .../mediawiki/images/textures/transparency.svg | 10 - .../oojs-ui/src/themes/mediawiki/indicators.json | 29 - .../oojs/oojs-ui/src/themes/mediawiki/layouts.less | 135 - .../oojs-ui/src/themes/mediawiki/textures.json | 8 - .../oojs/oojs-ui/src/themes/mediawiki/tools.less | 422 --- .../oojs/oojs-ui/src/themes/mediawiki/widgets.less | 978 ----- .../oojs/oojs-ui/src/themes/mediawiki/windows.less | 300 -- vendor/oojs/oojs-ui/src/toolgroups/BarToolGroup.js | 35 - .../oojs/oojs-ui/src/toolgroups/ListToolGroup.js | 133 - .../oojs/oojs-ui/src/toolgroups/MenuToolGroup.js | 58 - .../oojs/oojs-ui/src/toolgroups/PopupToolGroup.js | 187 - vendor/oojs/oojs-ui/src/tools/PopupTool.js | 59 - vendor/oojs/oojs-ui/src/tools/ToolGroupTool.js | 96 - vendor/oojs/oojs-ui/src/widgets/ActionWidget.js | 170 - .../oojs/oojs-ui/src/widgets/ButtonGroupWidget.js | 53 - .../oojs/oojs-ui/src/widgets/ButtonInputWidget.js | 121 - .../oojs/oojs-ui/src/widgets/ButtonOptionWidget.js | 60 - .../oojs/oojs-ui/src/widgets/ButtonSelectWidget.js | 62 - vendor/oojs/oojs-ui/src/widgets/ButtonWidget.js | 215 -- .../oojs-ui/src/widgets/CheckboxInputWidget.js | 110 - vendor/oojs/oojs-ui/src/widgets/ComboBoxWidget.js | 230 -- .../oojs-ui/src/widgets/DecoratedOptionWidget.js | 55 - .../oojs-ui/src/widgets/DropdownInputWidget.js | 137 - vendor/oojs/oojs-ui/src/widgets/DropdownWidget.js | 149 - vendor/oojs/oojs-ui/src/widgets/GroupWidget.js | 48 - vendor/oojs/oojs-ui/src/widgets/IconWidget.js | 54 - vendor/oojs/oojs-ui/src/widgets/IndicatorWidget.js | 52 - vendor/oojs/oojs-ui/src/widgets/InputWidget.js | 207 -- vendor/oojs/oojs-ui/src/widgets/ItemWidget.js | 48 - vendor/oojs/oojs-ui/src/widgets/LabelWidget.js | 84 - .../oojs/oojs-ui/src/widgets/MenuOptionWidget.js | 33 - .../oojs-ui/src/widgets/MenuSectionOptionWidget.js | 55 - .../oojs/oojs-ui/src/widgets/MenuSelectWidget.js | 254 -- vendor/oojs/oojs-ui/src/widgets/OptionWidget.js | 177 - .../oojs-ui/src/widgets/OutlineControlsWidget.js | 145 - .../oojs-ui/src/widgets/OutlineOptionWidget.js | 130 - .../oojs-ui/src/widgets/OutlineSelectWidget.js | 34 - .../oojs/oojs-ui/src/widgets/PopupButtonWidget.js | 57 - vendor/oojs/oojs-ui/src/widgets/PopupWidget.js | 395 -- .../oojs/oojs-ui/src/widgets/ProgressBarWidget.js | 96 - .../oojs/oojs-ui/src/widgets/RadioInputWidget.js | 94 - .../oojs/oojs-ui/src/widgets/RadioOptionWidget.js | 66 - .../oojs/oojs-ui/src/widgets/RadioSelectWidget.js | 58 - vendor/oojs/oojs-ui/src/widgets/SearchWidget.js | 176 - vendor/oojs/oojs-ui/src/widgets/SelectWidget.js | 630 ---- vendor/oojs/oojs-ui/src/widgets/TabOptionWidget.js | 31 - vendor/oojs/oojs-ui/src/widgets/TabSelectWidget.js | 33 - .../src/widgets/TextInputMenuSelectWidget.js | 103 - vendor/oojs/oojs-ui/src/widgets/TextInputWidget.js | 535 --- .../oojs/oojs-ui/src/widgets/ToggleButtonWidget.js | 114 - .../oojs/oojs-ui/src/widgets/ToggleSwitchWidget.js | 92 - vendor/oojs/oojs-ui/src/widgets/ToggleWidget.js | 71 - vendor/oojs/oojs-ui/tests/Element.test.js | 52 - vendor/oojs/oojs-ui/tests/JSPHP.test.karma.js | 61 - vendor/oojs/oojs-ui/tests/JSPHP.test.standalone.js | 55 - vendor/oojs/oojs-ui/tests/Process.test.js | 179 - .../oojs-ui/tests/QUnit.assert.equalDomElement.js | 113 - .../oojs-ui/tests/elements/FlaggedElement.test.js | 64 - vendor/oojs/oojs-ui/tests/index.php | 77 - vendor/oyejorge/less.php/CHANGES.md | 6 + vendor/oyejorge/less.php/LICENSE | 178 + vendor/oyejorge/less.php/README.md | 322 ++ vendor/oyejorge/less.php/bin/lessc | 191 + vendor/oyejorge/less.php/composer.json | 31 + vendor/oyejorge/less.php/lessc.inc.php | 268 ++ .../less.php/lib/Less/.easymin/ignore_prefixes | 2 + vendor/oyejorge/less.php/lib/Less/Autoloader.php | 79 + vendor/oyejorge/less.php/lib/Less/Cache.php | 316 ++ vendor/oyejorge/less.php/lib/Less/Colors.php | 170 + vendor/oyejorge/less.php/lib/Less/Configurable.php | 69 + vendor/oyejorge/less.php/lib/Less/Environment.php | 166 + .../oyejorge/less.php/lib/Less/Exception/Chunk.php | 203 ++ .../less.php/lib/Less/Exception/Compiler.php | 11 + .../less.php/lib/Less/Exception/Parser.php | 125 + vendor/oyejorge/less.php/lib/Less/Functions.php | 1183 ++++++ vendor/oyejorge/less.php/lib/Less/Less.php.combine | 17 + vendor/oyejorge/less.php/lib/Less/Mime.php | 41 + vendor/oyejorge/less.php/lib/Less/Output.php | 49 + .../oyejorge/less.php/lib/Less/Output/Mapped.php | 122 + vendor/oyejorge/less.php/lib/Less/Parser.php | 2627 ++++++++++++++ .../less.php/lib/Less/SourceMap/Base64VLQ.php | 187 + .../less.php/lib/Less/SourceMap/Generator.php | 365 ++ vendor/oyejorge/less.php/lib/Less/Tree.php | 90 + vendor/oyejorge/less.php/lib/Less/Tree/Alpha.php | 51 + .../oyejorge/less.php/lib/Less/Tree/Anonymous.php | 58 + .../oyejorge/less.php/lib/Less/Tree/Assignment.php | 39 + .../oyejorge/less.php/lib/Less/Tree/Attribute.php | 54 + vendor/oyejorge/less.php/lib/Less/Tree/Call.php | 121 + vendor/oyejorge/less.php/lib/Less/Tree/Color.php | 230 ++ vendor/oyejorge/less.php/lib/Less/Tree/Comment.php | 51 + .../oyejorge/less.php/lib/Less/Tree/Condition.php | 72 + .../less.php/lib/Less/Tree/DefaultFunc.php | 34 + .../less.php/lib/Less/Tree/DetachedRuleset.php | 40 + .../oyejorge/less.php/lib/Less/Tree/Dimension.php | 201 ++ .../oyejorge/less.php/lib/Less/Tree/Directive.php | 100 + vendor/oyejorge/less.php/lib/Less/Tree/Element.php | 75 + .../oyejorge/less.php/lib/Less/Tree/Expression.php | 97 + vendor/oyejorge/less.php/lib/Less/Tree/Extend.php | 77 + vendor/oyejorge/less.php/lib/Less/Tree/Import.php | 307 ++ .../oyejorge/less.php/lib/Less/Tree/Javascript.php | 30 + vendor/oyejorge/less.php/lib/Less/Tree/Keyword.php | 44 + vendor/oyejorge/less.php/lib/Less/Tree/Media.php | 179 + .../oyejorge/less.php/lib/Less/Tree/Mixin/Call.php | 202 ++ .../less.php/lib/Less/Tree/Mixin/Definition.php | 241 ++ .../oyejorge/less.php/lib/Less/Tree/NameValue.php | 41 + .../oyejorge/less.php/lib/Less/Tree/Negative.php | 37 + .../oyejorge/less.php/lib/Less/Tree/Operation.php | 70 + vendor/oyejorge/less.php/lib/Less/Tree/Paren.php | 35 + vendor/oyejorge/less.php/lib/Less/Tree/Quoted.php | 81 + vendor/oyejorge/less.php/lib/Less/Tree/Rule.php | 115 + vendor/oyejorge/less.php/lib/Less/Tree/Ruleset.php | 643 ++++ .../less.php/lib/Less/Tree/RulesetCall.php | 26 + .../oyejorge/less.php/lib/Less/Tree/Selector.php | 168 + .../less.php/lib/Less/Tree/UnicodeDescriptor.php | 29 + vendor/oyejorge/less.php/lib/Less/Tree/Unit.php | 147 + .../less.php/lib/Less/Tree/UnitConversions.php | 35 + vendor/oyejorge/less.php/lib/Less/Tree/Url.php | 76 + vendor/oyejorge/less.php/lib/Less/Tree/Value.php | 48 + .../oyejorge/less.php/lib/Less/Tree/Variable.php | 52 + vendor/oyejorge/less.php/lib/Less/Version.php | 15 + vendor/oyejorge/less.php/lib/Less/Visitor.php | 49 + .../less.php/lib/Less/Visitor/extendFinder.php | 114 + .../oyejorge/less.php/lib/Less/Visitor/import.php | 139 + .../less.php/lib/Less/Visitor/joinSelector.php | 70 + .../less.php/lib/Less/Visitor/processExtends.php | 469 +++ .../oyejorge/less.php/lib/Less/Visitor/toCSS.php | 292 ++ .../less.php/lib/Less/VisitorReplacing.php | 75 + vendor/psr/log/Psr/Log/LoggerAwareTrait.php | 22 - vendor/psr/log/Psr/Log/LoggerTrait.php | 131 - vendor/ruflin/elastica/CHANGELOG.md | 1038 ++++++ vendor/ruflin/elastica/CONTRIBUTING.md | 75 + vendor/ruflin/elastica/Dockerfile | 58 + vendor/ruflin/elastica/LICENSE.txt | 21 + vendor/ruflin/elastica/Makefile | 108 + vendor/ruflin/elastica/README.md | 31 + vendor/ruflin/elastica/Vagrantfile | 18 + vendor/ruflin/elastica/ansible/es-playbook.yml | 20 + vendor/ruflin/elastica/ansible/provision.sh | 63 + .../elastica/ansible/roles/base/tasks/main.yml | 13 + .../ansible/roles/elasticsearch/handlers/main.yml | 6 + .../ansible/roles/elasticsearch/tasks/main.yml | 101 + .../roles/elasticsearch/templates/config-0.yml | 10 + .../roles/elasticsearch/templates/config-1.yml | 10 + .../elasticsearch/templates/config-default.yml | 40 + .../elasticsearch/templates/elasticsearch.service | 229 ++ .../roles/elasticsearch/templates/logging.yml | 56 + .../elastica/ansible/roles/nginx/handlers/main.yml | 6 + .../elastica/ansible/roles/nginx/tasks/main.yml | 26 + .../ansible/roles/nginx/templates/mime.types.j2 | 109 + .../ansible/roles/nginx/templates/nginx.conf.j2 | 35 + .../elastica/ansible/roles/php/tasks/main.yml | 43 + vendor/ruflin/elastica/composer.json | 43 + vendor/ruflin/elastica/docker-compose.yml | 27 + .../ruflin/elastica/env/elasticsearch/Dockerfile | 26 + .../elastica/env/elasticsearch/elasticsearch.yml | 39 + .../ruflin/elastica/env/elasticsearch/logging.yml | 56 + vendor/ruflin/elastica/env/nginx/mime.types | 109 + vendor/ruflin/elastica/env/nginx/nginx.conf | 38 + .../elastica/lib/Elastica/AbstractUpdateAction.php | 568 +++ .../Elastica/Aggregation/AbstractAggregation.php | 97 + .../Aggregation/AbstractSimpleAggregation.php | 37 + .../Aggregation/AbstractTermsAggregation.php | 97 + .../elastica/lib/Elastica/Aggregation/Avg.php | 11 + .../lib/Elastica/Aggregation/Cardinality.php | 38 + .../lib/Elastica/Aggregation/DateHistogram.php | 130 + .../lib/Elastica/Aggregation/DateRange.php | 22 + .../lib/Elastica/Aggregation/ExtendedStats.php | 11 + .../elastica/lib/Elastica/Aggregation/Filter.php | 53 + .../elastica/lib/Elastica/Aggregation/Filters.php | 59 + .../lib/Elastica/Aggregation/GeoDistance.php | 104 + .../lib/Elastica/Aggregation/GeohashGrid.php | 68 + .../lib/Elastica/Aggregation/GlobalAggregation.php | 11 + .../lib/Elastica/Aggregation/Histogram.php | 59 + .../elastica/lib/Elastica/Aggregation/IpRange.php | 72 + .../elastica/lib/Elastica/Aggregation/Max.php | 11 + .../elastica/lib/Elastica/Aggregation/Min.php | 11 + .../elastica/lib/Elastica/Aggregation/Missing.php | 32 + .../elastica/lib/Elastica/Aggregation/Nested.php | 32 + .../lib/Elastica/Aggregation/Percentiles.php | 59 + .../elastica/lib/Elastica/Aggregation/Range.php | 58 + .../lib/Elastica/Aggregation/ReverseNested.php | 49 + .../lib/Elastica/Aggregation/ScriptedMetric.php | 82 + .../lib/Elastica/Aggregation/SignificantTerms.php | 27 + .../elastica/lib/Elastica/Aggregation/Stats.php | 11 + .../elastica/lib/Elastica/Aggregation/Sum.php | 11 + .../elastica/lib/Elastica/Aggregation/Terms.php | 23 + .../elastica/lib/Elastica/Aggregation/TopHits.php | 156 + .../lib/Elastica/Aggregation/ValueCount.php | 32 + vendor/ruflin/elastica/lib/Elastica/Bulk.php | 442 +++ .../ruflin/elastica/lib/Elastica/Bulk/Action.php | 228 ++ .../lib/Elastica/Bulk/Action/AbstractDocument.php | 166 + .../lib/Elastica/Bulk/Action/CreateDocument.php | 10 + .../lib/Elastica/Bulk/Action/DeleteDocument.php | 33 + .../lib/Elastica/Bulk/Action/IndexDocument.php | 53 + .../lib/Elastica/Bulk/Action/UpdateDocument.php | 65 + .../ruflin/elastica/lib/Elastica/Bulk/Response.php | 46 + .../elastica/lib/Elastica/Bulk/ResponseSet.php | 141 + vendor/ruflin/elastica/lib/Elastica/Client.php | 719 ++++ vendor/ruflin/elastica/lib/Elastica/Cluster.php | 192 + .../elastica/lib/Elastica/Cluster/Health.php | 185 + .../elastica/lib/Elastica/Cluster/Health/Index.php | 137 + .../elastica/lib/Elastica/Cluster/Health/Shard.php | 102 + .../elastica/lib/Elastica/Cluster/Settings.php | 202 ++ vendor/ruflin/elastica/lib/Elastica/Connection.php | 320 ++ .../lib/Elastica/Connection/ConnectionPool.php | 122 + .../Connection/Strategy/CallbackStrategy.php | 51 + .../Elastica/Connection/Strategy/RoundRobin.php | 24 + .../lib/Elastica/Connection/Strategy/Simple.php | 30 + .../Connection/Strategy/StrategyFactory.php | 45 + .../Connection/Strategy/StrategyInterface.php | 17 + vendor/ruflin/elastica/lib/Elastica/Document.php | 356 ++ .../Exception/Bulk/Response/ActionException.php | 65 + .../Elastica/Exception/Bulk/ResponseException.php | 98 + .../lib/Elastica/Exception/Bulk/UdpException.php | 8 + .../lib/Elastica/Exception/BulkException.php | 6 + .../lib/Elastica/Exception/ClientException.php | 11 + .../Exception/Connection/GuzzleException.php | 50 + .../Exception/Connection/HttpException.php | 86 + .../Exception/Connection/MemcacheException.php | 13 + .../Exception/Connection/ThriftException.php | 49 + .../lib/Elastica/Exception/ConnectionException.php | 58 + .../Elastica/Exception/ElasticsearchException.php | 91 + .../lib/Elastica/Exception/ExceptionInterface.php | 11 + .../lib/Elastica/Exception/InvalidException.php | 11 + .../lib/Elastica/Exception/JSONParseException.php | 9 + .../lib/Elastica/Exception/NotFoundException.php | 11 + .../Elastica/Exception/NotImplementedException.php | 13 + .../Exception/PartialShardFailureException.php | 28 + .../Elastica/Exception/QueryBuilderException.php | 11 + .../lib/Elastica/Exception/ResponseException.php | 70 + .../lib/Elastica/Exception/RuntimeException.php | 11 + .../elastica/lib/Elastica/Facet/AbstractFacet.php | 145 + .../elastica/lib/Elastica/Facet/DateHistogram.php | 58 + .../ruflin/elastica/lib/Elastica/Facet/Filter.php | 27 + .../elastica/lib/Elastica/Facet/GeoCluster.php | 66 + .../elastica/lib/Elastica/Facet/GeoDistance.php | 69 + .../elastica/lib/Elastica/Facet/Histogram.php | 96 + .../ruflin/elastica/lib/Elastica/Facet/Query.php | 27 + .../ruflin/elastica/lib/Elastica/Facet/Range.php | 143 + .../elastica/lib/Elastica/Facet/Statistical.php | 64 + .../ruflin/elastica/lib/Elastica/Facet/Terms.php | 137 + .../elastica/lib/Elastica/Facet/TermsStats.php | 107 + .../lib/Elastica/Filter/AbstractFilter.php | 59 + .../lib/Elastica/Filter/AbstractGeoDistance.php | 198 + .../lib/Elastica/Filter/AbstractGeoShape.php | 52 + .../elastica/lib/Elastica/Filter/AbstractMulti.php | 89 + .../ruflin/elastica/lib/Elastica/Filter/Bool.php | 15 + .../elastica/lib/Elastica/Filter/BoolAnd.php | 20 + .../elastica/lib/Elastica/Filter/BoolFilter.php | 133 + .../elastica/lib/Elastica/Filter/BoolNot.php | 42 + .../ruflin/elastica/lib/Elastica/Filter/BoolOr.php | 20 + .../ruflin/elastica/lib/Elastica/Filter/Exists.php | 34 + .../lib/Elastica/Filter/GeoBoundingBox.php | 49 + .../elastica/lib/Elastica/Filter/GeoDistance.php | 76 + .../lib/Elastica/Filter/GeoDistanceRange.php | 103 + .../elastica/lib/Elastica/Filter/GeoPolygon.php | 56 + .../lib/Elastica/Filter/GeoShapePreIndexed.php | 84 + .../lib/Elastica/Filter/GeoShapeProvided.php | 73 + .../elastica/lib/Elastica/Filter/GeohashCell.php | 47 + .../elastica/lib/Elastica/Filter/HasChild.php | 95 + .../elastica/lib/Elastica/Filter/HasParent.php | 69 + vendor/ruflin/elastica/lib/Elastica/Filter/Ids.php | 94 + .../elastica/lib/Elastica/Filter/Indices.php | 78 + .../ruflin/elastica/lib/Elastica/Filter/Limit.php | 34 + .../elastica/lib/Elastica/Filter/MatchAll.php | 20 + .../elastica/lib/Elastica/Filter/Missing.php | 60 + .../ruflin/elastica/lib/Elastica/Filter/Nested.php | 62 + .../elastica/lib/Elastica/Filter/NumericRange.php | 13 + .../ruflin/elastica/lib/Elastica/Filter/Prefix.php | 80 + .../ruflin/elastica/lib/Elastica/Filter/Query.php | 91 + .../ruflin/elastica/lib/Elastica/Filter/Range.php | 73 + .../ruflin/elastica/lib/Elastica/Filter/Regexp.php | 112 + .../ruflin/elastica/lib/Elastica/Filter/Script.php | 47 + .../ruflin/elastica/lib/Elastica/Filter/Term.php | 47 + .../ruflin/elastica/lib/Elastica/Filter/Terms.php | 149 + .../ruflin/elastica/lib/Elastica/Filter/Type.php | 59 + vendor/ruflin/elastica/lib/Elastica/Index.php | 515 +++ .../elastica/lib/Elastica/Index/Settings.php | 366 ++ .../ruflin/elastica/lib/Elastica/Index/Stats.php | 108 + .../ruflin/elastica/lib/Elastica/Index/Status.php | 150 + vendor/ruflin/elastica/lib/Elastica/JSON.php | 67 + vendor/ruflin/elastica/lib/Elastica/Log.php | 81 + .../elastica/lib/Elastica/Multi/ResultSet.php | 205 ++ .../ruflin/elastica/lib/Elastica/Multi/Search.php | 203 ++ vendor/ruflin/elastica/lib/Elastica/Node.php | 161 + vendor/ruflin/elastica/lib/Elastica/Node/Info.php | 220 ++ vendor/ruflin/elastica/lib/Elastica/Node/Stats.php | 113 + vendor/ruflin/elastica/lib/Elastica/Param.php | 167 + vendor/ruflin/elastica/lib/Elastica/Percolator.php | 194 + vendor/ruflin/elastica/lib/Elastica/Query.php | 488 +++ .../elastica/lib/Elastica/Query/AbstractQuery.php | 13 + vendor/ruflin/elastica/lib/Elastica/Query/Bool.php | 15 + .../elastica/lib/Elastica/Query/BoolQuery.php | 111 + .../elastica/lib/Elastica/Query/Boosting.php | 50 + .../ruflin/elastica/lib/Elastica/Query/Builder.php | 935 +++++ .../ruflin/elastica/lib/Elastica/Query/Common.php | 172 + .../elastica/lib/Elastica/Query/ConstantScore.php | 70 + .../ruflin/elastica/lib/Elastica/Query/DisMax.php | 62 + .../elastica/lib/Elastica/Query/Filtered.php | 97 + .../elastica/lib/Elastica/Query/FunctionScore.php | 260 ++ .../ruflin/elastica/lib/Elastica/Query/Fuzzy.php | 87 + .../elastica/lib/Elastica/Query/FuzzyLikeThis.php | 217 ++ .../elastica/lib/Elastica/Query/HasChild.php | 65 + .../elastica/lib/Elastica/Query/HasParent.php | 63 + vendor/ruflin/elastica/lib/Elastica/Query/Ids.php | 121 + .../ruflin/elastica/lib/Elastica/Query/Image.php | 187 + .../ruflin/elastica/lib/Elastica/Query/Match.php | 222 ++ .../elastica/lib/Elastica/Query/MatchAll.php | 20 + .../elastica/lib/Elastica/Query/MatchPhrase.php | 13 + .../lib/Elastica/Query/MatchPhrasePrefix.php | 13 + .../elastica/lib/Elastica/Query/MoreLikeThis.php | 198 + .../elastica/lib/Elastica/Query/MultiMatch.php | 191 + .../ruflin/elastica/lib/Elastica/Query/Nested.php | 48 + .../ruflin/elastica/lib/Elastica/Query/Prefix.php | 47 + .../elastica/lib/Elastica/Query/QueryString.php | 282 ++ .../ruflin/elastica/lib/Elastica/Query/Range.php | 38 + .../ruflin/elastica/lib/Elastica/Query/Regexp.php | 40 + .../ruflin/elastica/lib/Elastica/Query/Simple.php | 54 + .../lib/Elastica/Query/SimpleQueryString.php | 83 + vendor/ruflin/elastica/lib/Elastica/Query/Term.php | 49 + .../ruflin/elastica/lib/Elastica/Query/Terms.php | 107 + .../elastica/lib/Elastica/Query/TopChildren.php | 53 + .../elastica/lib/Elastica/Query/Wildcard.php | 40 + .../ruflin/elastica/lib/Elastica/QueryBuilder.php | 114 + .../elastica/lib/Elastica/QueryBuilder/DSL.php | 22 + .../lib/Elastica/QueryBuilder/DSL/Aggregation.php | 470 +++ .../lib/Elastica/QueryBuilder/DSL/Filter.php | 480 +++ .../lib/Elastica/QueryBuilder/DSL/Query.php | 586 +++ .../lib/Elastica/QueryBuilder/DSL/Suggest.php | 83 + .../elastica/lib/Elastica/QueryBuilder/Facade.php | 64 + .../elastica/lib/Elastica/QueryBuilder/Version.php | 101 + .../Elastica/QueryBuilder/Version/Version090.php | 97 + .../Elastica/QueryBuilder/Version/Version100.php | 123 + .../Elastica/QueryBuilder/Version/Version110.php | 131 + .../Elastica/QueryBuilder/Version/Version120.php | 137 + .../Elastica/QueryBuilder/Version/Version130.php | 142 + .../Elastica/QueryBuilder/Version/Version140.php | 145 + .../Elastica/QueryBuilder/Version/Version150.php | 14 + vendor/ruflin/elastica/lib/Elastica/Request.php | 204 ++ .../lib/Elastica/Rescore/AbstractRescore.php | 36 + .../ruflin/elastica/lib/Elastica/Rescore/Query.php | 91 + vendor/ruflin/elastica/lib/Elastica/Response.php | 308 ++ vendor/ruflin/elastica/lib/Elastica/Result.php | 217 ++ vendor/ruflin/elastica/lib/Elastica/ResultSet.php | 433 +++ .../ruflin/elastica/lib/Elastica/ScanAndScroll.php | 80 + vendor/ruflin/elastica/lib/Elastica/Script.php | 163 + .../ruflin/elastica/lib/Elastica/ScriptFields.php | 65 + vendor/ruflin/elastica/lib/Elastica/Scroll.php | 174 + vendor/ruflin/elastica/lib/Elastica/Search.php | 553 +++ .../elastica/lib/Elastica/SearchableInterface.php | 52 + vendor/ruflin/elastica/lib/Elastica/Snapshot.php | 176 + vendor/ruflin/elastica/lib/Elastica/Status.php | 177 + vendor/ruflin/elastica/lib/Elastica/Suggest.php | 65 + .../lib/Elastica/Suggest/AbstractSuggest.php | 97 + .../AbstractCandidateGenerator.php | 8 + .../Suggest/CandidateGenerator/DirectGenerator.php | 140 + .../elastica/lib/Elastica/Suggest/Completion.php | 26 + .../elastica/lib/Elastica/Suggest/Phrase.php | 164 + .../ruflin/elastica/lib/Elastica/Suggest/Term.php | 129 + .../elastica/lib/Elastica/Tool/CrossIndex.php | 160 + .../lib/Elastica/Transport/AbstractTransport.php | 113 + .../elastica/lib/Elastica/Transport/Guzzle.php | 179 + .../elastica/lib/Elastica/Transport/Http.php | 190 + .../lib/Elastica/Transport/HttpAdapter.php | 156 + .../elastica/lib/Elastica/Transport/Https.php | 27 + .../elastica/lib/Elastica/Transport/Memcache.php | 109 + .../elastica/lib/Elastica/Transport/Null.php | 13 + .../lib/Elastica/Transport/NullTransport.php | 46 + .../elastica/lib/Elastica/Transport/Thrift.php | 176 + vendor/ruflin/elastica/lib/Elastica/Type.php | 572 +++ .../elastica/lib/Elastica/Type/AbstractType.php | 205 ++ .../ruflin/elastica/lib/Elastica/Type/Mapping.php | 297 ++ vendor/ruflin/elastica/lib/Elastica/Util.php | 194 + vendor/ruflin/elastica/phpdoc.dist.xml | 13 + vendor/ruflin/elastica/test/bootstrap.php | 5 + vendor/ruflin/elastica/test/data/test.doc | Bin 0 -> 22016 bytes vendor/ruflin/elastica/test/data/test.docx | Bin 0 -> 25890 bytes vendor/ruflin/elastica/test/data/test.jpg | Bin 0 -> 4459 bytes vendor/ruflin/elastica/test/data/test.pdf | Bin 0 -> 16107 bytes vendor/ruflin/elastica/test/data/test.txt | 1 + .../test/lib/Elastica/Test/Aggregation/AvgTest.php | 39 + .../Test/Aggregation/BaseAggregationTest.php | 8 + .../Elastica/Test/Aggregation/CardinalityTest.php | 132 + .../Test/Aggregation/DateHistogramTest.php | 103 + .../Elastica/Test/Aggregation/DateRangeTest.php | 52 + .../Test/Aggregation/ExtendedStatsTest.php | 45 + .../lib/Elastica/Test/Aggregation/FilterTest.php | 113 + .../lib/Elastica/Test/Aggregation/FiltersTest.php | 120 + .../Elastica/Test/Aggregation/GeoDistanceTest.php | 46 + .../Elastica/Test/Aggregation/GeohashGridTest.php | 46 + .../Test/Aggregation/GlobalAggregationTest.php | 27 + .../Elastica/Test/Aggregation/HistogramTest.php | 47 + .../lib/Elastica/Test/Aggregation/IpRangeTest.php | 57 + .../test/lib/Elastica/Test/Aggregation/MaxTest.php | 79 + .../test/lib/Elastica/Test/Aggregation/MinTest.php | 40 + .../lib/Elastica/Test/Aggregation/MissingTest.php | 39 + .../lib/Elastica/Test/Aggregation/NestedTest.php | 63 + .../Elastica/Test/Aggregation/PercentilesTest.php | 125 + .../lib/Elastica/Test/Aggregation/RangeTest.php | 78 + .../Test/Aggregation/ReverseNestedTest.php | 134 + .../lib/Elastica/Test/Aggregation/ScriptTest.php | 87 + .../Test/Aggregation/ScriptedMetricTest.php | 50 + .../Test/Aggregation/SignificantTermsTest.php | 72 + .../lib/Elastica/Test/Aggregation/StatsTest.php | 44 + .../test/lib/Elastica/Test/Aggregation/SumTest.php | 40 + .../lib/Elastica/Test/Aggregation/TermsTest.php | 41 + .../lib/Elastica/Test/Aggregation/TopHitsTest.php | 385 ++ .../Elastica/Test/Aggregation/ValueCountTest.php | 40 + .../elastica/test/lib/Elastica/Test/Base.php | 142 + .../test/lib/Elastica/Test/Bulk/ActionTest.php | 66 + .../lib/Elastica/Test/Bulk/ResponseSetTest.php | 200 ++ .../elastica/test/lib/Elastica/Test/BulkTest.php | 792 ++++ .../elastica/test/lib/Elastica/Test/ClientTest.php | 1160 ++++++ .../lib/Elastica/Test/Cluster/Health/IndexTest.php | 144 + .../lib/Elastica/Test/Cluster/Health/ShardTest.php | 85 + .../test/lib/Elastica/Test/Cluster/HealthTest.php | 147 + .../lib/Elastica/Test/Cluster/SettingsTest.php | 117 + .../test/lib/Elastica/Test/ClusterTest.php | 83 + .../Test/Connection/ConnectionPoolTest.php | 112 + .../Connection/Strategy/CallbackStrategyTest.php | 97 + .../Strategy/CallbackStrategyTestHelper.php | 20 + .../Test/Connection/Strategy/EmptyStrategy.php | 17 + .../Test/Connection/Strategy/RoundRobinTest.php | 128 + .../Test/Connection/Strategy/SimpleTest.php | 113 + .../Connection/Strategy/StrategyFactoryTest.php | 84 + .../test/lib/Elastica/Test/ConnectionTest.php | 121 + .../test/lib/Elastica/Test/DocumentTest.php | 349 ++ .../test/lib/Elastica/Test/ExampleTest.php | 61 + .../Test/Exception/AbstractExceptionTest.php | 31 + .../Bulk/Response/ActionExceptionTest.php | 8 + .../Test/Exception/Bulk/ResponseExceptionTest.php | 8 + .../Test/Exception/Bulk/UdpExceptionTest.php | 8 + .../Elastica/Test/Exception/BulkExceptionTest.php | 6 + .../Test/Exception/ClientExceptionTest.php | 6 + .../Exception/Connection/GuzzleExceptionTest.php | 14 + .../Exception/Connection/HttpExceptionTest.php | 8 + .../Exception/Connection/MemcacheExceptionTest.php | 8 + .../Exception/Connection/ThriftExceptionTest.php | 14 + .../Test/Exception/ConnectionExceptionTest.php | 6 + .../Test/Exception/ElasticsearchExceptionTest.php | 6 + .../Test/Exception/InvalidExceptionTest.php | 6 + .../Test/Exception/JSONParseExceptionTest.php | 6 + .../Test/Exception/NotFoundExceptionTest.php | 6 + .../Test/Exception/NotImplementedExceptionTest.php | 19 + .../Exception/PartialShardFailureExceptionTest.php | 54 + .../Test/Exception/QueryBuilderExceptionTest.php | 6 + .../Test/Exception/ResponseExceptionTest.php | 65 + .../Test/Exception/RuntimeExceptionTest.php | 6 + .../lib/Elastica/Test/Facet/DateHistogramTest.php | 106 + .../test/lib/Elastica/Test/Facet/FilterTest.php | 42 + .../lib/Elastica/Test/Facet/GeoClusterTest.php | 57 + .../test/lib/Elastica/Test/Facet/QueryTest.php | 42 + .../lib/Elastica/Test/Facet/StatisticalTest.php | 82 + .../lib/Elastica/Test/Facet/TermsStatsTest.php | 113 + .../test/lib/Elastica/Test/Facet/TermsTest.php | 74 + .../test/lib/Elastica/Test/Filter/AbstractTest.php | 81 + .../test/lib/Elastica/Test/Filter/BoolAndTest.php | 86 + .../lib/Elastica/Test/Filter/BoolFilterTest.php | 200 ++ .../test/lib/Elastica/Test/Filter/BoolNotTest.php | 27 + .../test/lib/Elastica/Test/Filter/BoolOrTest.php | 90 + .../test/lib/Elastica/Test/Filter/ExistsTest.php | 36 + .../Elastica/Test/Filter/GeoBoundingBoxTest.php | 55 + .../Elastica/Test/Filter/GeoDistanceRangeTest.php | 220 ++ .../lib/Elastica/Test/Filter/GeoDistanceTest.php | 141 + .../lib/Elastica/Test/Filter/GeoPolygonTest.php | 65 + .../Test/Filter/GeoShapePreIndexedTest.php | 102 + .../Elastica/Test/Filter/GeoShapeProvidedTest.php | 103 + .../lib/Elastica/Test/Filter/GeohashCellTest.php | 68 + .../test/lib/Elastica/Test/Filter/HasChildTest.php | 213 ++ .../lib/Elastica/Test/Filter/HasParentTest.php | 153 + .../test/lib/Elastica/Test/Filter/IdsTest.php | 244 ++ .../test/lib/Elastica/Test/Filter/IndicesTest.php | 125 + .../test/lib/Elastica/Test/Filter/LimitTest.php | 34 + .../test/lib/Elastica/Test/Filter/MatchAllTest.php | 20 + .../test/lib/Elastica/Test/Filter/MissingTest.php | 78 + .../test/lib/Elastica/Test/Filter/MultiTest.php | 109 + .../Test/Filter/NestedFilterWithSetFilterTest.php | 110 + .../test/lib/Elastica/Test/Filter/NestedTest.php | 127 + .../lib/Elastica/Test/Filter/NumericRangeTest.php | 37 + .../test/lib/Elastica/Test/Filter/PrefixTest.php | 138 + .../test/lib/Elastica/Test/Filter/QueryTest.php | 51 + .../test/lib/Elastica/Test/Filter/RangeTest.php | 61 + .../test/lib/Elastica/Test/Filter/RegexpTest.php | 162 + .../test/lib/Elastica/Test/Filter/ScriptTest.php | 57 + .../test/lib/Elastica/Test/Filter/TermTest.php | 24 + .../test/lib/Elastica/Test/Filter/TermsTest.php | 129 + .../test/lib/Elastica/Test/Filter/TypeTest.php | 32 + .../test/lib/Elastica/Test/Index/SettingsTest.php | 338 ++ .../test/lib/Elastica/Test/Index/StatsTest.php | 24 + .../test/lib/Elastica/Test/Index/StatusTest.php | 74 + .../elastica/test/lib/Elastica/Test/IndexTest.php | 901 +++++ .../elastica/test/lib/Elastica/Test/LogTest.php | 196 + .../test/lib/Elastica/Test/Multi/SearchTest.php | 575 +++ .../test/lib/Elastica/Test/Node/InfoTest.php | 79 + .../elastica/test/lib/Elastica/Test/NodeTest.php | 75 + .../elastica/test/lib/Elastica/Test/ParamTest.php | 115 + .../test/lib/Elastica/Test/PercolatorTest.php | 328 ++ .../test/lib/Elastica/Test/Query/BoolQueryTest.php | 171 + .../test/lib/Elastica/Test/Query/BoostingTest.php | 89 + .../test/lib/Elastica/Test/Query/BuilderTest.php | 273 ++ .../test/lib/Elastica/Test/Query/CommonTest.php | 63 + .../lib/Elastica/Test/Query/ConstantScoreTest.php | 162 + .../test/lib/Elastica/Test/Query/DisMaxTest.php | 84 + .../lib/Elastica/Test/Query/EscapeStringTest.php | 36 + .../test/lib/Elastica/Test/Query/FilteredTest.php | 124 + .../lib/Elastica/Test/Query/FunctionScoreTest.php | 324 ++ .../lib/Elastica/Test/Query/FuzzyLikeThisTest.php | 300 ++ .../test/lib/Elastica/Test/Query/FuzzyTest.php | 136 + .../test/lib/Elastica/Test/Query/HasChildTest.php | 117 + .../test/lib/Elastica/Test/Query/HasParentTest.php | 108 + .../test/lib/Elastica/Test/Query/HighlightTest.php | 48 + .../test/lib/Elastica/Test/Query/IdsTest.php | 187 + .../test/lib/Elastica/Test/Query/ImageTest.php | 159 + .../test/lib/Elastica/Test/Query/MatchAllTest.php | 49 + .../test/lib/Elastica/Test/Query/MatchTest.php | 339 ++ .../lib/Elastica/Test/Query/MoreLikeThisTest.php | 240 ++ .../lib/Elastica/Test/Query/MultiMatchTest.php | 214 ++ .../test/lib/Elastica/Test/Query/NestedTest.php | 30 + .../lib/Elastica/Test/Query/PostFilterTest.php | 64 + .../test/lib/Elastica/Test/Query/PrefixTest.php | 27 + .../lib/Elastica/Test/Query/QueryStringTest.php | 189 + .../test/lib/Elastica/Test/Query/RangeTest.php | 79 + .../test/lib/Elastica/Test/Query/RegexpTest.php | 31 + .../test/lib/Elastica/Test/Query/RescoreTest.php | 236 ++ .../Elastica/Test/Query/SimpleQueryStringTest.php | 103 + .../test/lib/Elastica/Test/Query/SimpleTest.php | 19 + .../test/lib/Elastica/Test/Query/TermTest.php | 27 + .../test/lib/Elastica/Test/Query/TermsTest.php | 65 + .../test/lib/Elastica/Test/Query/WildcardTest.php | 106 + .../Test/QueryBuilder/DSL/AbstractDSLTest.php | 97 + .../Test/QueryBuilder/DSL/AggregationTest.php | 58 + .../Elastica/Test/QueryBuilder/DSL/FilterTest.php | 58 + .../Elastica/Test/QueryBuilder/DSL/QueryTest.php | 85 + .../Elastica/Test/QueryBuilder/DSL/SuggestTest.php | 32 + .../lib/Elastica/Test/QueryBuilder/VersionTest.php | 67 + .../test/lib/Elastica/Test/QueryBuilderTest.php | 88 + .../elastica/test/lib/Elastica/Test/QueryTest.php | 458 +++ .../test/lib/Elastica/Test/RequestTest.php | 95 + .../test/lib/Elastica/Test/ResponseTest.php | 205 ++ .../test/lib/Elastica/Test/ResultSetTest.php | 95 + .../elastica/test/lib/Elastica/Test/ResultTest.php | 131 + .../test/lib/Elastica/Test/ScanAndScrollTest.php | 78 + .../test/lib/Elastica/Test/ScriptFieldsTest.php | 93 + .../elastica/test/lib/Elastica/Test/ScriptTest.php | 169 + .../elastica/test/lib/Elastica/Test/ScrollTest.php | 105 + .../elastica/test/lib/Elastica/Test/SearchTest.php | 647 ++++ .../test/lib/Elastica/Test/ShutdownTest.php | 74 + .../test/lib/Elastica/Test/SnapshotTest.php | 109 + .../elastica/test/lib/Elastica/Test/StatusTest.php | 133 + .../lib/Elastica/Test/Suggest/CompletionTest.php | 140 + .../test/lib/Elastica/Test/Suggest/PhraseTest.php | 82 + .../test/lib/Elastica/Test/Suggest/TermTest.php | 105 + .../test/lib/Elastica/Test/Tool/CrossIndexTest.php | 135 + .../Test/Transport/AbstractTransportTest.php | 80 + .../lib/Elastica/Test/Transport/GuzzleTest.php | 180 + .../test/lib/Elastica/Test/Transport/HttpTest.php | 246 ++ .../lib/Elastica/Test/Transport/MemcacheTest.php | 176 + .../Elastica/Test/Transport/NullTransportTest.php | 96 + .../lib/Elastica/Test/Transport/ThriftTest.php | 135 + .../Test/Transport/TransportBenchmarkTest.php | 261 ++ .../test/lib/Elastica/Test/Type/MappingTest.php | 331 ++ .../elastica/test/lib/Elastica/Test/TypeTest.php | 968 +++++ .../elastica/test/lib/Elastica/Test/UtilTest.php | 139 + vendor/ruflin/elastica/test/phpunit.xhprof.xml | 39 + vendor/ruflin/elastica/test/phpunit.xml.dist | 27 + vendor/symfony/process/CHANGELOG.md | 40 + .../process/Exception/ExceptionInterface.php | 21 + .../process/Exception/InvalidArgumentException.php | 21 + .../symfony/process/Exception/LogicException.php | 21 + .../process/Exception/ProcessFailedException.php | 53 + .../process/Exception/ProcessTimedOutException.php | 69 + .../symfony/process/Exception/RuntimeException.php | 21 + vendor/symfony/process/ExecutableFinder.php | 89 + vendor/symfony/process/LICENSE | 19 + vendor/symfony/process/PhpExecutableFinder.php | 86 + vendor/symfony/process/PhpProcess.php | 71 + vendor/symfony/process/Pipes/AbstractPipes.php | 74 + vendor/symfony/process/Pipes/PipesInterface.php | 60 + vendor/symfony/process/Pipes/UnixPipes.php | 214 ++ vendor/symfony/process/Pipes/WindowsPipes.php | 254 ++ vendor/symfony/process/Process.php | 1526 ++++++++ vendor/symfony/process/ProcessBuilder.php | 287 ++ vendor/symfony/process/ProcessUtils.php | 115 + vendor/symfony/process/README.md | 51 + .../symfony/process/Tests/AbstractProcessTest.php | 1205 +++++++ .../symfony/process/Tests/ExecutableFinderTest.php | 149 + .../symfony/process/Tests/NonStopableProcess.php | 36 + .../process/Tests/PhpExecutableFinderTest.php | 97 + vendor/symfony/process/Tests/PhpProcessTest.php | 49 + .../Tests/PipeStdinInStdoutStdErrStreamSelect.php | 63 + .../symfony/process/Tests/ProcessBuilderTest.php | 225 ++ .../process/Tests/ProcessFailedExceptionTest.php | 136 + .../process/Tests/ProcessInSigchildEnvironment.php | 22 + vendor/symfony/process/Tests/ProcessUtilsTest.php | 48 + .../process/Tests/SigchildDisabledProcessTest.php | 263 ++ .../process/Tests/SigchildEnabledProcessTest.php | 148 + vendor/symfony/process/Tests/SignalListener.php | 16 + vendor/symfony/process/Tests/SimpleProcessTest.php | 222 ++ vendor/symfony/process/composer.json | 33 + vendor/symfony/process/phpunit.xml.dist | 27 + vendor/wikimedia/assert/COPYING | 21 + vendor/wikimedia/assert/README.md | 43 + vendor/wikimedia/assert/composer.json | 24 + vendor/wikimedia/assert/phpunit.xml.dist | 27 + vendor/wikimedia/assert/src/Assert.php | 204 ++ vendor/wikimedia/assert/src/AssertionException.php | 16 + vendor/wikimedia/assert/src/InvariantException.php | 18 + .../assert/src/ParameterAssertionException.php | 49 + .../assert/src/ParameterElementTypeException.php | 43 + .../assert/src/ParameterTypeException.php | 43 + .../assert/src/PostconditionException.php | 18 + .../wikimedia/assert/src/PreconditionException.php | 17 + .../wikimedia/assert/tests/phpunit/AssertTest.php | 156 + vendor/wikimedia/avro/LICENSE.txt | 308 ++ vendor/wikimedia/avro/NOTICE.txt | 9 + vendor/wikimedia/avro/README.md | 23 + vendor/wikimedia/avro/lib/avro.php | 195 + vendor/wikimedia/avro/lib/avro/data_file.php | 535 +++ vendor/wikimedia/avro/lib/avro/datum.php | 984 +++++ vendor/wikimedia/avro/lib/avro/debug.php | 194 + vendor/wikimedia/avro/lib/avro/gmp.php | 222 ++ vendor/wikimedia/avro/lib/avro/io.php | 494 +++ vendor/wikimedia/avro/lib/avro/protocol.php | 86 + vendor/wikimedia/avro/lib/avro/schema.php | 1457 ++++++++ vendor/wikimedia/avro/lib/avro/util.php | 67 + vendor/wikimedia/cdb/COPYING | 183 +- vendor/wikimedia/cdb/Doxyfile | 32 - vendor/wikimedia/cdb/README.md | 31 +- vendor/wikimedia/cdb/composer.json | 26 - vendor/wikimedia/cdb/doc/README | 1 - vendor/wikimedia/cdb/src/Reader.php | 17 + vendor/wikimedia/cdb/src/Reader/DBA.php | 13 + vendor/wikimedia/cdb/src/Reader/PHP.php | 286 +- vendor/wikimedia/cdb/src/Writer.php | 2 +- vendor/wikimedia/cdb/src/Writer/DBA.php | 1 + vendor/wikimedia/cdb/src/Writer/PHP.php | 1 + vendor/wikimedia/cdb/test/CdbTest.php | 95 - vendor/wikimedia/composer-merge-plugin/.arcconfig | 6 + vendor/wikimedia/composer-merge-plugin/.arclint | 13 + vendor/wikimedia/composer-merge-plugin/LICENSE | 2 +- vendor/wikimedia/composer-merge-plugin/README.md | 133 +- .../wikimedia/composer-merge-plugin/composer.json | 18 +- .../wikimedia/composer-merge-plugin/src/Logger.php | 102 + .../src/Merge/ExtraPackage.php | 487 +++ .../src/Merge/MissingFileException.php | 18 + .../src/Merge/PluginState.php | 327 ++ .../src/Merge/StabilityFlags.php | 181 + .../composer-merge-plugin/src/MergePlugin.php | 427 +-- vendor/wikimedia/ip-set/COPYING | 339 ++ vendor/wikimedia/ip-set/README.md | 83 + vendor/wikimedia/ip-set/src/IPSet.php | 284 ++ vendor/wikimedia/utfnormal/COPYING | 342 ++ vendor/wikimedia/utfnormal/Doxyfile | 32 + vendor/wikimedia/wrappedstring/LICENSE | 19 + vendor/wikimedia/wrappedstring/README.md | 24 + .../wikimedia/wrappedstring/src/WrappedString.php | 110 + vendor/zordius/lightncandy/HISTORY.md | 180 +- vendor/zordius/lightncandy/LICENSE.txt | 2 +- vendor/zordius/lightncandy/README.md | 91 +- vendor/zordius/lightncandy/UPGRADE.md | 4 + vendor/zordius/lightncandy/build/gen_doc | 2 +- vendor/zordius/lightncandy/src/lightncandy.php | 540 +-- vendor/zordius/lightncandy/tests/LCRun3Test.php | 18 +- .../zordius/lightncandy/tests/LightnCandyTest.php | 159 +- vendor/zordius/lightncandy/tests/contextTest.php | 300 ++ vendor/zordius/lightncandy/tests/errorTest.php | 23 +- .../zordius/lightncandy/tests/helpers_for_test.php | 12 +- .../zordius/lightncandy/tests/regressionTest.php | 609 ++++ 1770 files changed, 113092 insertions(+), 42007 deletions(-) create mode 100644 vendor/README.md create mode 100644 vendor/composer.json create mode 100644 vendor/composer.lock create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_files.php create mode 100644 vendor/composer/semver/CHANGELOG.md create mode 100644 vendor/composer/semver/LICENSE create mode 100644 vendor/composer/semver/README.md create mode 100644 vendor/composer/semver/composer.json create mode 100644 vendor/composer/semver/src/Comparator.php create mode 100644 vendor/composer/semver/src/Constraint/AbstractConstraint.php create mode 100644 vendor/composer/semver/src/Constraint/Constraint.php create mode 100644 vendor/composer/semver/src/Constraint/ConstraintInterface.php create mode 100644 vendor/composer/semver/src/Constraint/EmptyConstraint.php create mode 100644 vendor/composer/semver/src/Constraint/MultiConstraint.php create mode 100644 vendor/composer/semver/src/Semver.php create mode 100644 vendor/composer/semver/src/VersionParser.php create mode 100644 vendor/firebase/php-jwt/Authentication/JWT.php create mode 100644 vendor/firebase/php-jwt/Exceptions/BeforeValidException.php create mode 100644 vendor/firebase/php-jwt/Exceptions/ExpiredException.php create mode 100644 vendor/firebase/php-jwt/Exceptions/SignatureInvalidException.php create mode 100644 vendor/firebase/php-jwt/LICENSE create mode 100644 vendor/firebase/php-jwt/README.md create mode 100644 vendor/firebase/php-jwt/composer.json create mode 100644 vendor/firebase/php-jwt/package.xml create mode 100644 vendor/firebase/php-jwt/phpunit.xml.dist create mode 100644 vendor/firebase/php-jwt/run-tests.sh create mode 100644 vendor/firebase/php-jwt/tests/JWTTest.php create mode 100644 vendor/firebase/php-jwt/tests/autoload.php.dist create mode 100644 vendor/firebase/php-jwt/tests/bootstrap.php create mode 100644 vendor/kzykhys/pygments/README.md create mode 100644 vendor/kzykhys/pygments/composer.json create mode 100644 vendor/kzykhys/pygments/composer.lock create mode 100644 vendor/kzykhys/pygments/phpunit.xml.dist create mode 100644 vendor/kzykhys/pygments/src/KzykHys/Pygments/Pygments.php create mode 100644 vendor/kzykhys/pygments/test/KzykHys/Pygments/PygmentsTest.php create mode 100644 vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/css/default.css create mode 100644 vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/css/default.prefix.css create mode 100644 vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.in create mode 100644 vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.linenos.out create mode 100644 vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.out delete mode 100644 vendor/leafo/lessphp/LICENSE delete mode 100644 vendor/leafo/lessphp/Makefile delete mode 100644 vendor/leafo/lessphp/README.md delete mode 100644 vendor/leafo/lessphp/composer.json delete mode 100644 vendor/leafo/lessphp/docs/docs.md delete mode 100644 vendor/leafo/lessphp/lessc.inc.php delete mode 100644 vendor/leafo/lessphp/lessify delete mode 100644 vendor/leafo/lessphp/lessify.inc.php delete mode 100644 vendor/leafo/lessphp/package.sh delete mode 100644 vendor/leafo/lessphp/plessc delete mode 100644 vendor/leafo/lessphp/tests/ApiTest.php delete mode 100644 vendor/leafo/lessphp/tests/ErrorHandlingTest.php delete mode 100644 vendor/leafo/lessphp/tests/InputTest.php delete mode 100644 vendor/leafo/lessphp/tests/README.md delete mode 100644 vendor/leafo/lessphp/tests/bootstrap.sh delete mode 100644 vendor/leafo/lessphp/tests/inputs/accessors.less.disable delete mode 100644 vendor/leafo/lessphp/tests/inputs/arity.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/attributes.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/builtins.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/colors.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/compile_on_mixin.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/data-uri.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/directives.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/escape.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/font_family.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/guards.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/hacks.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/hi.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/ie.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/import.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/interpolation.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/keyframes.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/math.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/media.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/misc.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/mixin_functions.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/mixin_merging.less.disable delete mode 100644 vendor/leafo/lessphp/tests/inputs/mixins.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/nested.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/pattern_matching.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/scopes.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/selector_expressions.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/site_demos.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/test-imports/a.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/test-imports/b.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/test-imports/file1.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/test-imports/file2.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/test-imports/file3.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/test-imports/inner/file1.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/test-imports/inner/file2.less delete mode 100644 vendor/leafo/lessphp/tests/inputs/variables.less delete mode 100644 vendor/leafo/lessphp/tests/inputs_lessjs/mixins-args.less delete mode 100644 vendor/leafo/lessphp/tests/inputs_lessjs/mixins-named-args.less delete mode 100644 vendor/leafo/lessphp/tests/inputs_lessjs/strings.less delete mode 100644 vendor/leafo/lessphp/tests/outputs/accessors.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/arity.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/attributes.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/builtins.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/colors.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/compile_on_mixin.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/data-uri.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/directives.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/escape.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/font_family.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/guards.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/hacks.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/hi.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/ie.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/import.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/interpolation.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/keyframes.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/math.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/media.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/misc.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/mixin_functions.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/mixin_merging.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/mixins.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/nested.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/nesting.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/pattern_matching.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/scopes.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/selector_expressions.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/site_demos.css delete mode 100644 vendor/leafo/lessphp/tests/outputs/variables.css delete mode 100644 vendor/leafo/lessphp/tests/outputs_lessjs/mixins-args.css delete mode 100644 vendor/leafo/lessphp/tests/outputs_lessjs/mixins-named-args.css delete mode 100644 vendor/leafo/lessphp/tests/outputs_lessjs/strings.css delete mode 100644 vendor/leafo/lessphp/tests/sort.php create mode 100644 vendor/liuggio/statsd-php-client/CHANGELOG.md create mode 100644 vendor/liuggio/statsd-php-client/README.md delete mode 100644 vendor/liuggio/statsd-php-client/Readme.md create mode 100644 vendor/liuggio/statsd-php-client/phpunit.xml delete mode 100644 vendor/liuggio/statsd-php-client/phpunit.xml.dist create mode 100644 vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php create mode 100644 vendor/liuggio/statsd-php-client/tests/Liuggio/StatsdClient/Service/StatsdServiceTest.php create mode 100644 vendor/mediawiki/at-ease/COPYING create mode 100644 vendor/mediawiki/at-ease/README.md create mode 100644 vendor/mediawiki/at-ease/src/Functions.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/extending.md create mode 100644 vendor/monolog/monolog/doc/sockets.md create mode 100644 vendor/monolog/monolog/doc/usage.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/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/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/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/nmred/kafka-php/LICENSE create mode 100644 vendor/nmred/kafka-php/README.md create mode 100644 vendor/nmred/kafka-php/src/Kafka/Client.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/ClusterMetaData.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Consumer.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Exception.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Exception/NotSupported.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Exception/OutOfRange.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Exception/Protocol.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Exception/Socket.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Exception/SocketConnect.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Exception/SocketEOF.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Exception/SocketTimeout.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Log.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/MetaDataFromKafka.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Offset.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Produce.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Decoder.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Encoder.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/CommitOffset.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Consumer.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/FreeStream.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Helper.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/HelperAbstract.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Message.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/MessageSet.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Partition.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Topic.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Protocol/Protocol.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/Socket.php create mode 100644 vendor/nmred/kafka-php/src/Kafka/ZooKeeper.php delete mode 100644 vendor/oojs/oojs-ui/.csscomb.json delete mode 100644 vendor/oojs/oojs-ui/.csslintrc delete mode 100644 vendor/oojs/oojs-ui/.npmignore delete mode 100644 vendor/oojs/oojs-ui/Doxyfile delete mode 100644 vendor/oojs/oojs-ui/Gruntfile.js delete mode 100644 vendor/oojs/oojs-ui/build/banner.txt delete mode 100644 vendor/oojs/oojs-ui/build/modules.json delete mode 100644 vendor/oojs/oojs-ui/build/tasks/colorize-svg.js delete mode 100644 vendor/oojs/oojs-ui/build/tasks/typos.js delete mode 100644 vendor/oojs/oojs-ui/build/typos.json delete mode 100644 vendor/oojs/oojs-ui/composer.json create mode 100644 vendor/oojs/oojs-ui/i18n/as.json create mode 100644 vendor/oojs/oojs-ui/i18n/dty.json create mode 100644 vendor/oojs/oojs-ui/i18n/en-ca.json create mode 100644 vendor/oojs/oojs-ui/i18n/glk.json create mode 100644 vendor/oojs/oojs-ui/i18n/hrx.json create mode 100644 vendor/oojs/oojs-ui/i18n/hu-formal.json create mode 100644 vendor/oojs/oojs-ui/i18n/krl.json create mode 100644 vendor/oojs/oojs-ui/i18n/la.json create mode 100644 vendor/oojs/oojs-ui/i18n/li.json create mode 100644 vendor/oojs/oojs-ui/i18n/luz.json create mode 100644 vendor/oojs/oojs-ui/i18n/olo.json create mode 100644 vendor/oojs/oojs-ui/i18n/sa.json create mode 100644 vendor/oojs/oojs-ui/i18n/su.json create mode 100644 vendor/oojs/oojs-ui/i18n/xmf.json delete mode 100644 vendor/oojs/oojs-ui/jsduck.categories.json delete mode 100644 vendor/oojs/oojs-ui/jsduck.eg-iframe.html delete mode 100644 vendor/oojs/oojs-ui/jsduck.external.js delete mode 100644 vendor/oojs/oojs-ui/jsduck.json delete mode 100644 vendor/oojs/oojs-ui/php/elements/ButtonElement.php delete mode 100644 vendor/oojs/oojs-ui/php/elements/FlaggedElement.php delete mode 100644 vendor/oojs/oojs-ui/php/elements/GroupElement.php delete mode 100644 vendor/oojs/oojs-ui/php/elements/IconElement.php delete mode 100644 vendor/oojs/oojs-ui/php/elements/IndicatorElement.php delete mode 100644 vendor/oojs/oojs-ui/php/elements/LabelElement.php delete mode 100644 vendor/oojs/oojs-ui/php/elements/TabIndexedElement.php delete mode 100644 vendor/oojs/oojs-ui/php/elements/TitledElement.php create mode 100644 vendor/oojs/oojs-ui/php/layouts/ActionFieldLayout.php create mode 100644 vendor/oojs/oojs-ui/php/layouts/HorizontalLayout.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/AccessKeyedElement.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/ButtonElement.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/GroupElement.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/IconElement.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/IndicatorElement.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/LabelElement.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/TabIndexedElement.php create mode 100644 vendor/oojs/oojs-ui/php/mixins/TitledElement.php create mode 100644 vendor/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php delete mode 100644 vendor/oojs/oojs-ui/src/ActionSet.js delete mode 100644 vendor/oojs/oojs-ui/src/Dialog.js delete mode 100644 vendor/oojs/oojs-ui/src/Element.js delete mode 100644 vendor/oojs/oojs-ui/src/Error.js delete mode 100644 vendor/oojs/oojs-ui/src/HtmlSnippet.js delete mode 100644 vendor/oojs/oojs-ui/src/Layout.js delete mode 100644 vendor/oojs/oojs-ui/src/Process.js delete mode 100644 vendor/oojs/oojs-ui/src/Theme.js delete mode 100644 vendor/oojs/oojs-ui/src/Tool.js delete mode 100644 vendor/oojs/oojs-ui/src/ToolFactory.js delete mode 100644 vendor/oojs/oojs-ui/src/ToolGroup.js delete mode 100644 vendor/oojs/oojs-ui/src/ToolGroupFactory.js delete mode 100644 vendor/oojs/oojs-ui/src/Toolbar.js delete mode 100644 vendor/oojs/oojs-ui/src/Widget.js delete mode 100644 vendor/oojs/oojs-ui/src/Window.js delete mode 100644 vendor/oojs/oojs-ui/src/WindowManager.js delete mode 100644 vendor/oojs/oojs-ui/src/core.js delete mode 100644 vendor/oojs/oojs-ui/src/dialogs/MessageDialog.js delete mode 100644 vendor/oojs/oojs-ui/src/dialogs/ProcessDialog.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/ButtonElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/ClippableElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/DraggableElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/DraggableGroupElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/FlaggedElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/GroupElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/IconElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/IndicatorElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/LabelElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/LookupElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/PendingElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/PopupElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/TabIndexedElement.js delete mode 100644 vendor/oojs/oojs-ui/src/elements/TitledElement.js delete mode 100644 vendor/oojs/oojs-ui/src/intro.js.txt delete mode 100644 vendor/oojs/oojs-ui/src/layouts/ActionFieldLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/BookletLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/CardLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/FieldLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/FieldsetLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/FormLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/IndexLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/MenuLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/PageLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/PanelLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/layouts/StackLayout.js delete mode 100644 vendor/oojs/oojs-ui/src/outro.js.txt delete mode 100644 vendor/oojs/oojs-ui/src/styles/Dialog.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/Element.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/Layout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/Tool.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/ToolGroup.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/Toolbar.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/Widget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/Window.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/WindowManager.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/common.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/core.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/dialogs/MessageDialog.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/dialogs/ProcessDialog.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/ButtonElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/ClippableElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/DraggableElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/DraggableGroupElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/FlaggedElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/GroupElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/IconElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/IndicatorElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/LabelElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/LookupElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/PopupElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/TabIndexedElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/elements/TitledElement.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/images/grab.cur delete mode 100644 vendor/oojs/oojs-ui/src/styles/images/grabbing.cur delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/ActionFieldLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/BookletLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/CardLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/FieldLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/FieldsetLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/FormLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/IndexLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/MenuLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/PageLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/PanelLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/layouts/StackLayout.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/theme.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/toolgroups/BarToolGroup.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/toolgroups/ListToolGroup.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/toolgroups/MenuToolGroup.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/toolgroups/PopupToolGroup.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/tools/PopupTool.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/tools/ToolGroupTool.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ActionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ButtonGroupWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ButtonInputWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ButtonOptionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ButtonSelectWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ButtonWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/CheckboxInputWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ComboBoxWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/DecoratedOptionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/DropdownInputWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/DropdownWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/IconWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/IndicatorWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/InputWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/LabelWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/MenuOptionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/MenuSectionOptionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/MenuSelectWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/OptionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/OutlineControlsWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/OutlineOptionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/OutlineSelectWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/PopupButtonWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/PopupWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ProgressBarWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/RadioInputWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/RadioOptionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/RadioSelectWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/SearchWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/SelectWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/TabOptionWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/TabSelectWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/TextInputMenuSelectWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/TextInputWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ToggleButtonWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ToggleSwitchWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/styles/widgets/ToggleWidget.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/ApexTheme.js delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/common.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/core.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/elements.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/icons-editing-advanced.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/icons-editing-core.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/icons-editing-list.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/icons-editing-styling.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/icons-moderation.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/icons-movement.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/icons.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/add.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/advanced.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/alert.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/align-center.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/align-float-left.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/align-float-right.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/arched-arrow-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/arched-arrow-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/arrow-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/arrow-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bigger-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bigger-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/block.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/blockUndo-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/blockUndo-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-a.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-arab-ain.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-arab-dad.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-armn-to.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-b.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-cyrl-be.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-cyrl-te.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-cyrl-zhe.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-f.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-g.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-geor-man.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-l.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-n.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/bold-v.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/cancel.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/caret-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/caret-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/caretDown.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/caretUp.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/case-sensitive.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/check.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/circle.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/close.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/code.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/collapse.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/comment.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/downTriangle.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/edit-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/edit-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/editLock-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/editLock-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/editUndo-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/editUndo-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/ellipsis.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/expand.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/external-link-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/external-link-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/find-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/find-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/flag-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/flag-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/flagUndo-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/flagUndo-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/help-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/help-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/history.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/indent-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/indent-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/info.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/insert.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-a.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-arab-keheh-jeem.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-arab-meem.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-armn-sha.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-c.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-d.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-e.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-geor-kan.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-i.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-k.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/italic-s.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/language.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/layout-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/layout-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/link.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/listBullet-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/listBullet-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/listNumbered-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/listNumbered-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/lock.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/menu.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/move-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/move-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/move.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/newline-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/newline-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/noWikiText-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/noWikiText-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/outdent-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/outdent-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/outline-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/outline-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/picture.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/puzzle-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/puzzle-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/quotes-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/quotes-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/quotesAdd-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/quotesAdd-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/redirect-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/redirect-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/regular-expression.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/remove.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/search.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/secure-link.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/settings.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/smaller-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/smaller-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/specialCharacter.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/star.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/strikethrough-a.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/strikethrough-s.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/strikethrough-y.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/subscript-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/subscript-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/superscript-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/superscript-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/table-caption.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/table-insert-column-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/table-insert-column-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/table-insert-row-after.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/table-insert-row-before.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/table-merge-cells.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/table.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/tag.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/templateAdd-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/templateAdd-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/text-dir-lefttoright.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/text-dir-righttoleft.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/text-style.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/translation-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/translation-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/trash.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/trashUndo-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/trashUndo-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/unLock-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/unLock-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/unStar.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/underline-a.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/underline-u.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/upTriangle.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/wikiText.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/icons/window.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/indicators/alert.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/indicators/arrow-down.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/indicators/arrow-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/indicators/arrow-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/indicators/arrow-up.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/indicators/required.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/indicators/search-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/indicators/search-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/textures/pending.gif delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/textures/transparency.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/images/toolbar-shadow.png delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/indicators.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/layouts.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/textures.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/tools.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/widgets.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/apex/windows.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/BlankTheme.js delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/common.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/core.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/elements.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/images/icons/README.txt delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/images/indicators/README.txt delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/images/textures/README.txt delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/layouts.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/tools.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/widgets.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/blank/windows.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/MediaWikiTheme.js delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/common.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/core.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/elements.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-alerts.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-content.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-editing-advanced.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-editing-core.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-editing-list.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-editing-styling.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-interactions.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-layout.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-location.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-media.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-moderation.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-movement.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-user.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons-wikimedia.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/icons.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/add.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/advanced.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/alert.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/align-center.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/align-float-left.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/align-float-right.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/arched-arrow-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/arched-arrow-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/arrow-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/arrow-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/article-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/article-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/articleCheck-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/articleCheck-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/articleSearch-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/articleSearch-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bell.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bellOn-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bellOn-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/beta.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/betaLaunch.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bigger-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bigger-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/block.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/blockUndo-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/blockUndo-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-a.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-arab-ain.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-arab-dad.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-armn-to.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-b.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-cyrl-be.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-cyrl-te.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-cyrl-zhe.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-f.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-g.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-geor-man.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-l.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-n.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bold-v.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/book-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/book-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bookmark-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/bookmark-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/browser-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/browser-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/cancel.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/caret-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/caret-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/caretDown.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/caretUp.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/case-sensitive.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/check.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/circle.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/citeArticle-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/citeArticle-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/clear.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/clock.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/close-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/close-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/code.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/collapse.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/comment.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/die-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/die-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/downTriangle.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/download-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/download-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/edit-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/edit-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/editLock-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/editLock-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/editUndo-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/editUndo-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/ellipsis.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/expand.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/external-link-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/external-link-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/eye.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/eyeClosed.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/find-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/find-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/flag-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/flag-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/flagUndo-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/flagUndo-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/folderPlaceholder-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/folderPlaceholder-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/funnel-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/funnel-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/heart.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/help-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/help-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/history.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/image-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/image-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/imageAdd-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/imageAdd-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/imageLock-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/imageLock-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/indent-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/indent-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/info.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/insert.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-a.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-arab-keheh-jeem.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-arab-meem.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-armn-sha.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-c.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-d.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-e.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-geor-kan.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-i.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-k.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/italic-s.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/journal-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/journal-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/key-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/key-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/keyboard-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/keyboard-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/language.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/layout-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/layout-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/link-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/link-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/listBullet-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/listBullet-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/listNumbered-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/listNumbered-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/lock-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/lock-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/logOut-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/logOut-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/logo-cc.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/logo-wikimediaCommons.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/logo-wikipedia.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/map-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/map-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/mapPin.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/mapPinAdd-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/mapPinAdd-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/menu.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/message-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/message-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/move-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/move-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/move.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/newWindow-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/newWindow-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/newline-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/newline-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/newspaper-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/newspaper-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/noWikiText-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/noWikiText-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/outdent-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/outdent-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/outline-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/outline-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/photoGallery-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/photoGallery-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/picture.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/play-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/play-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/printer-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/printer-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/puzzle-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/puzzle-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/quotes-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/quotes-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/quotesAdd-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/quotesAdd-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/redirect-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/redirect-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/regular-expression.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/remove.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/ribbonPrize.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/search-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/search-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/secure-link.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/settings.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/signature-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/signature-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/smaller-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/smaller-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/specialCharacter.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/speechBubble-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/speechBubble-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/speechBubbleAdd-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/speechBubbleAdd-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/speechBubbles-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/speechBubbles-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/star.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/stop.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/strikethrough-a.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/strikethrough-s.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/strikethrough-y.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/stripeFlow-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/stripeFlow-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/stripeSideMenu.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/stripeSummary-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/stripeSummary-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/stripeToC-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/stripeToC-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/subscript-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/subscript-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/sun-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/sun-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/superscript-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/superscript-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/table-caption.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/table-insert-column-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/table-insert-column-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/table-insert-row-after.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/table-insert-row-before.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/table-merge-cells.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/table.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/tag.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/templateAdd-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/templateAdd-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/text-dir-lefttoright.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/text-dir-righttoleft.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/text-style.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/translation-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/translation-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/trash.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/trashUndo-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/trashUndo-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/unLock-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/unLock-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/unStar.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/underline-a.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/underline-u.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/upTriangle.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/upload-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/upload-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/userActive-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/userActive-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/userAvatar.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/userInactive-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/userInactive-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/userTalk-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/userTalk-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/viewCompact.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/viewDetails-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/viewDetails-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/visionSimulator.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/watchlist-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/watchlist-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/wikiText.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/wikitrail-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/wikitrail-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/icons/window.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/indicators/alert.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/indicators/arrow-down.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/indicators/arrow-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/indicators/arrow-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/indicators/arrow-up.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/indicators/required.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/indicators/search-ltr.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/indicators/search-rtl.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/textures/pending.gif delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/images/textures/transparency.svg delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/indicators.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/layouts.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/textures.json delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/tools.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/widgets.less delete mode 100644 vendor/oojs/oojs-ui/src/themes/mediawiki/windows.less delete mode 100644 vendor/oojs/oojs-ui/src/toolgroups/BarToolGroup.js delete mode 100644 vendor/oojs/oojs-ui/src/toolgroups/ListToolGroup.js delete mode 100644 vendor/oojs/oojs-ui/src/toolgroups/MenuToolGroup.js delete mode 100644 vendor/oojs/oojs-ui/src/toolgroups/PopupToolGroup.js delete mode 100644 vendor/oojs/oojs-ui/src/tools/PopupTool.js delete mode 100644 vendor/oojs/oojs-ui/src/tools/ToolGroupTool.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ActionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ButtonGroupWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ButtonInputWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ButtonOptionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ButtonSelectWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ButtonWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/CheckboxInputWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ComboBoxWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/DecoratedOptionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/DropdownInputWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/DropdownWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/GroupWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/IconWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/IndicatorWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/InputWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ItemWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/LabelWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/MenuOptionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/MenuSectionOptionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/MenuSelectWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/OptionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/OutlineControlsWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/OutlineOptionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/OutlineSelectWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/PopupButtonWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/PopupWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ProgressBarWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/RadioInputWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/RadioOptionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/RadioSelectWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/SearchWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/SelectWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/TabOptionWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/TabSelectWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/TextInputMenuSelectWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/TextInputWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ToggleButtonWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ToggleSwitchWidget.js delete mode 100644 vendor/oojs/oojs-ui/src/widgets/ToggleWidget.js delete mode 100644 vendor/oojs/oojs-ui/tests/Element.test.js delete mode 100644 vendor/oojs/oojs-ui/tests/JSPHP.test.karma.js delete mode 100644 vendor/oojs/oojs-ui/tests/JSPHP.test.standalone.js delete mode 100644 vendor/oojs/oojs-ui/tests/Process.test.js delete mode 100644 vendor/oojs/oojs-ui/tests/QUnit.assert.equalDomElement.js delete mode 100644 vendor/oojs/oojs-ui/tests/elements/FlaggedElement.test.js delete mode 100644 vendor/oojs/oojs-ui/tests/index.php create mode 100644 vendor/oyejorge/less.php/CHANGES.md create mode 100644 vendor/oyejorge/less.php/LICENSE create mode 100644 vendor/oyejorge/less.php/README.md create mode 100644 vendor/oyejorge/less.php/bin/lessc create mode 100644 vendor/oyejorge/less.php/composer.json create mode 100644 vendor/oyejorge/less.php/lessc.inc.php create mode 100644 vendor/oyejorge/less.php/lib/Less/.easymin/ignore_prefixes create mode 100644 vendor/oyejorge/less.php/lib/Less/Autoloader.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Cache.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Colors.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Configurable.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Environment.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Exception/Chunk.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Exception/Compiler.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Exception/Parser.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Functions.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Less.php.combine create mode 100644 vendor/oyejorge/less.php/lib/Less/Mime.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Output.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Output/Mapped.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Parser.php create mode 100644 vendor/oyejorge/less.php/lib/Less/SourceMap/Base64VLQ.php create mode 100644 vendor/oyejorge/less.php/lib/Less/SourceMap/Generator.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Alpha.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Anonymous.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Assignment.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Attribute.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Call.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Color.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Comment.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Condition.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/DefaultFunc.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/DetachedRuleset.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Dimension.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Directive.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Element.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Expression.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Extend.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Import.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Javascript.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Keyword.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Media.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Mixin/Call.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Mixin/Definition.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/NameValue.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Negative.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Operation.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Paren.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Quoted.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Rule.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Ruleset.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/RulesetCall.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Selector.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/UnicodeDescriptor.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Unit.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/UnitConversions.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Url.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Value.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Tree/Variable.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Version.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Visitor.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Visitor/extendFinder.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Visitor/import.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Visitor/joinSelector.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Visitor/processExtends.php create mode 100644 vendor/oyejorge/less.php/lib/Less/Visitor/toCSS.php create mode 100644 vendor/oyejorge/less.php/lib/Less/VisitorReplacing.php delete mode 100644 vendor/psr/log/Psr/Log/LoggerAwareTrait.php delete mode 100644 vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 vendor/ruflin/elastica/CHANGELOG.md create mode 100644 vendor/ruflin/elastica/CONTRIBUTING.md create mode 100644 vendor/ruflin/elastica/Dockerfile create mode 100644 vendor/ruflin/elastica/LICENSE.txt create mode 100644 vendor/ruflin/elastica/Makefile create mode 100644 vendor/ruflin/elastica/README.md create mode 100644 vendor/ruflin/elastica/Vagrantfile create mode 100644 vendor/ruflin/elastica/ansible/es-playbook.yml create mode 100644 vendor/ruflin/elastica/ansible/provision.sh create mode 100644 vendor/ruflin/elastica/ansible/roles/base/tasks/main.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/elasticsearch/handlers/main.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/elasticsearch/tasks/main.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-0.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-1.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-default.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/elasticsearch.service create mode 100644 vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/logging.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/nginx/handlers/main.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/nginx/tasks/main.yml create mode 100644 vendor/ruflin/elastica/ansible/roles/nginx/templates/mime.types.j2 create mode 100644 vendor/ruflin/elastica/ansible/roles/nginx/templates/nginx.conf.j2 create mode 100644 vendor/ruflin/elastica/ansible/roles/php/tasks/main.yml create mode 100644 vendor/ruflin/elastica/composer.json create mode 100644 vendor/ruflin/elastica/docker-compose.yml create mode 100644 vendor/ruflin/elastica/env/elasticsearch/Dockerfile create mode 100644 vendor/ruflin/elastica/env/elasticsearch/elasticsearch.yml create mode 100644 vendor/ruflin/elastica/env/elasticsearch/logging.yml create mode 100644 vendor/ruflin/elastica/env/nginx/mime.types create mode 100644 vendor/ruflin/elastica/env/nginx/nginx.conf create mode 100644 vendor/ruflin/elastica/lib/Elastica/AbstractUpdateAction.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractAggregation.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractSimpleAggregation.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractTermsAggregation.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Avg.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Cardinality.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/DateHistogram.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/DateRange.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/ExtendedStats.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Filter.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Filters.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/GeoDistance.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/GeohashGrid.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/GlobalAggregation.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Histogram.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/IpRange.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Max.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Min.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Missing.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Nested.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Percentiles.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Range.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/ReverseNested.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/ScriptedMetric.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/SignificantTerms.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Stats.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Sum.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/Terms.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/TopHits.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Aggregation/ValueCount.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk/Action.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk/Action/AbstractDocument.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk/Action/CreateDocument.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk/Action/DeleteDocument.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk/Action/IndexDocument.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk/Action/UpdateDocument.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk/Response.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Bulk/ResponseSet.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Client.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Cluster.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Cluster/Health.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Index.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Shard.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Cluster/Settings.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Connection.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Connection/ConnectionPool.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/CallbackStrategy.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/RoundRobin.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/Simple.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyFactory.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyInterface.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Document.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/Response/ActionException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/ResponseException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/UdpException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/BulkException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/ClientException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/Connection/GuzzleException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/Connection/HttpException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/Connection/MemcacheException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/Connection/ThriftException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/ConnectionException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/ElasticsearchException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/ExceptionInterface.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/InvalidException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/JSONParseException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/NotFoundException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/NotImplementedException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/PartialShardFailureException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/QueryBuilderException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/ResponseException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Exception/RuntimeException.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/AbstractFacet.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/DateHistogram.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/Filter.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/GeoCluster.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/GeoDistance.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/Histogram.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/Query.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/Range.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/Statistical.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/Terms.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Facet/TermsStats.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/AbstractFilter.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoDistance.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoShape.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/AbstractMulti.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Bool.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/BoolAnd.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/BoolFilter.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/BoolNot.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/BoolOr.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Exists.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/GeoBoundingBox.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistance.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistanceRange.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/GeoPolygon.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapePreIndexed.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapeProvided.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/GeohashCell.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/HasChild.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/HasParent.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Ids.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Indices.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Limit.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/MatchAll.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Missing.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Nested.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/NumericRange.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Prefix.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Query.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Range.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Regexp.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Script.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Term.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Terms.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Filter/Type.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Index.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Index/Settings.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Index/Stats.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Index/Status.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/JSON.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Log.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Multi/ResultSet.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Multi/Search.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Node.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Node/Info.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Node/Stats.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Param.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Percolator.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/AbstractQuery.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Bool.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/BoolQuery.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Boosting.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Builder.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Common.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/ConstantScore.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/DisMax.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Filtered.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/FunctionScore.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Fuzzy.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/FuzzyLikeThis.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/HasChild.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/HasParent.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Ids.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Image.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Match.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/MatchAll.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrase.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrasePrefix.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/MoreLikeThis.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/MultiMatch.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Nested.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Prefix.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/QueryString.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Range.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Regexp.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Simple.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/SimpleQueryString.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Term.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Terms.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/TopChildren.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Query/Wildcard.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Aggregation.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Filter.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Query.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Suggest.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Facade.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version090.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version100.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version110.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version120.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version130.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version140.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version150.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Request.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Rescore/AbstractRescore.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Rescore/Query.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Response.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Result.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/ResultSet.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/ScanAndScroll.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Script.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/ScriptFields.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Scroll.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Search.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/SearchableInterface.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Snapshot.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Status.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Suggest.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Suggest/AbstractSuggest.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/AbstractCandidateGenerator.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/DirectGenerator.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Suggest/Completion.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Suggest/Phrase.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Suggest/Term.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Tool/CrossIndex.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/AbstractTransport.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/Guzzle.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/Http.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/HttpAdapter.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/Https.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/Memcache.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/Null.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/NullTransport.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Transport/Thrift.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Type.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Type/AbstractType.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Type/Mapping.php create mode 100644 vendor/ruflin/elastica/lib/Elastica/Util.php create mode 100644 vendor/ruflin/elastica/phpdoc.dist.xml create mode 100644 vendor/ruflin/elastica/test/bootstrap.php create mode 100644 vendor/ruflin/elastica/test/data/test.doc create mode 100644 vendor/ruflin/elastica/test/data/test.docx create mode 100644 vendor/ruflin/elastica/test/data/test.jpg create mode 100644 vendor/ruflin/elastica/test/data/test.pdf create mode 100644 vendor/ruflin/elastica/test/data/test.txt create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/AvgTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/BaseAggregationTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/CardinalityTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateHistogramTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateRangeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ExtendedStatsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FilterTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FiltersTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeoDistanceTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeohashGridTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GlobalAggregationTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/HistogramTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/IpRangeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MaxTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MinTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MissingTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/NestedTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/PercentilesTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/RangeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ReverseNestedTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptedMetricTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SignificantTermsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/StatsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SumTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TermsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TopHitsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ValueCountTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Base.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ActionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ResponseSetTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/BulkTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ClientTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/IndexTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/ShardTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/HealthTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/SettingsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ClusterTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/ConnectionPoolTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTestHelper.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/EmptyStrategy.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/RoundRobinTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/SimpleTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/StrategyFactoryTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ConnectionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/DocumentTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ExampleTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/AbstractExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/Response/ActionExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/ResponseExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/UdpExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/BulkExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ClientExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/GuzzleExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/HttpExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/MemcacheExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/ThriftExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ConnectionExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ElasticsearchExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/InvalidExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/JSONParseExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotFoundExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotImplementedExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/PartialShardFailureExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/QueryBuilderExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ResponseExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/RuntimeExceptionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/DateHistogramTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/FilterTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/GeoClusterTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/QueryTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/StatisticalTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsStatsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/AbstractTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolAndTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolFilterTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolNotTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolOrTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ExistsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoBoundingBoxTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceRangeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoPolygonTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapePreIndexedTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapeProvidedTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeohashCellTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasChildTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasParentTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IdsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IndicesTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/LimitTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MatchAllTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MissingTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MultiTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedFilterWithSetFilterTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NumericRangeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/PrefixTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/QueryTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RangeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RegexpTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ScriptTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TypeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Index/SettingsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatusTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/IndexTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/LogTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Multi/SearchTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Node/InfoTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/NodeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ParamTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/PercolatorTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoolQueryTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoostingTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BuilderTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/CommonTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ConstantScoreTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/DisMaxTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/EscapeStringTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FilteredTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FunctionScoreTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyLikeThisTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasChildTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasParentTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HighlightTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/IdsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ImageTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchAllTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MoreLikeThisTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MultiMatchTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/NestedTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PostFilterTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PrefixTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/QueryStringTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RangeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RegexpTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RescoreTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleQueryStringTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Query/WildcardTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AbstractDSLTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AggregationTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/FilterTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/QueryTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/SuggestTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/VersionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilderTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/QueryTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/RequestTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ResponseTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ResultSetTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ResultTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ScanAndScrollTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptFieldsTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ScrollTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/SearchTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/ShutdownTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/SnapshotTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/StatusTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/CompletionTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/PhraseTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/TermTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Tool/CrossIndexTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/AbstractTransportTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/GuzzleTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/HttpTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/MemcacheTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/NullTransportTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/ThriftTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/TransportBenchmarkTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/Type/MappingTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/TypeTest.php create mode 100644 vendor/ruflin/elastica/test/lib/Elastica/Test/UtilTest.php create mode 100644 vendor/ruflin/elastica/test/phpunit.xhprof.xml create mode 100644 vendor/ruflin/elastica/test/phpunit.xml.dist 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/wikimedia/assert/COPYING create mode 100644 vendor/wikimedia/assert/README.md create mode 100644 vendor/wikimedia/assert/composer.json create mode 100644 vendor/wikimedia/assert/phpunit.xml.dist create mode 100644 vendor/wikimedia/assert/src/Assert.php create mode 100644 vendor/wikimedia/assert/src/AssertionException.php create mode 100644 vendor/wikimedia/assert/src/InvariantException.php create mode 100644 vendor/wikimedia/assert/src/ParameterAssertionException.php create mode 100644 vendor/wikimedia/assert/src/ParameterElementTypeException.php create mode 100644 vendor/wikimedia/assert/src/ParameterTypeException.php create mode 100644 vendor/wikimedia/assert/src/PostconditionException.php create mode 100644 vendor/wikimedia/assert/src/PreconditionException.php create mode 100644 vendor/wikimedia/assert/tests/phpunit/AssertTest.php create mode 100644 vendor/wikimedia/avro/LICENSE.txt create mode 100644 vendor/wikimedia/avro/NOTICE.txt create mode 100644 vendor/wikimedia/avro/README.md create mode 100644 vendor/wikimedia/avro/lib/avro.php create mode 100644 vendor/wikimedia/avro/lib/avro/data_file.php create mode 100644 vendor/wikimedia/avro/lib/avro/datum.php create mode 100644 vendor/wikimedia/avro/lib/avro/debug.php create mode 100644 vendor/wikimedia/avro/lib/avro/gmp.php create mode 100644 vendor/wikimedia/avro/lib/avro/io.php create mode 100644 vendor/wikimedia/avro/lib/avro/protocol.php create mode 100644 vendor/wikimedia/avro/lib/avro/schema.php create mode 100644 vendor/wikimedia/avro/lib/avro/util.php delete mode 100644 vendor/wikimedia/cdb/Doxyfile delete mode 100644 vendor/wikimedia/cdb/composer.json delete mode 100644 vendor/wikimedia/cdb/doc/README delete mode 100644 vendor/wikimedia/cdb/test/CdbTest.php create mode 100644 vendor/wikimedia/composer-merge-plugin/.arcconfig create mode 100644 vendor/wikimedia/composer-merge-plugin/.arclint create mode 100644 vendor/wikimedia/composer-merge-plugin/src/Logger.php create mode 100644 vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php create mode 100644 vendor/wikimedia/composer-merge-plugin/src/Merge/MissingFileException.php create mode 100644 vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php create mode 100644 vendor/wikimedia/composer-merge-plugin/src/Merge/StabilityFlags.php create mode 100644 vendor/wikimedia/ip-set/COPYING create mode 100644 vendor/wikimedia/ip-set/README.md create mode 100644 vendor/wikimedia/ip-set/src/IPSet.php create mode 100644 vendor/wikimedia/utfnormal/COPYING create mode 100644 vendor/wikimedia/utfnormal/Doxyfile create mode 100644 vendor/wikimedia/wrappedstring/LICENSE create mode 100644 vendor/wikimedia/wrappedstring/README.md create mode 100644 vendor/wikimedia/wrappedstring/src/WrappedString.php create mode 100644 vendor/zordius/lightncandy/tests/contextTest.php (limited to 'vendor') diff --git a/vendor/README.md b/vendor/README.md new file mode 100644 index 00000000..71959751 --- /dev/null +++ b/vendor/README.md @@ -0,0 +1,30 @@ +MediaWiki-Vendor +================ + +[Composer] managed libraries required or recommended for use with [MediaWiki]. +This repository is maintained for use on the Wikimedia Foundation production +and testing clusters, but may be useful for anyone wishing to avoid directly +managing MediaWiki dependencies with Composer. + + +Usage +----- + +Checkout this library into $IP/vendor using `git clone ` or add the +repository as a git submodule using `git submodule add vendor` followed +by `git submodule update --init`. + + +Adding or updating libraries +---------------------------- + +0. Read the [documentation] on the process for adding new libraries. +1. Edit the composer.json file +2. Run `composer update` to download files and update the autoloader files. +3. Add and commit changes as a gerrit patch. +4. Review and merge changes. + + +[Composer]: https://getcomposer.org/ +[MediaWiki]: https://www.mediawiki.org/wiki/MediaWiki +[documentation]: https://www.mediawiki.org/wiki/Manual:External_libraries diff --git a/vendor/autoload.php b/vendor/autoload.php index eea313e2..9bcfa9fe 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInite2ef576e4023c6f0949f5e8e1cdf8649::getLoader(); +return ComposerAutoloaderInit_mediawiki_vendor::getLoader(); diff --git a/vendor/composer.json b/vendor/composer.json new file mode 100644 index 00000000..f3a5ba0f --- /dev/null +++ b/vendor/composer.json @@ -0,0 +1,35 @@ +{ + "config": { + "autoloader-suffix": "_mediawiki_vendor", + "classmap-authoritative": true, + "optimize-autoloader": true, + "preferred-install": "dist", + "prepend-autoloader": false, + "vendor-dir": "." + }, + "prefer-stable": true, + "require": { + "composer/semver": "1.0.0", + "cssjanus/cssjanus": "1.1.1", + "firebase/php-jwt": "2.1.0", + "kzykhys/pygments": "1.0", + "liuggio/statsd-php-client": "1.0.16", + "mediawiki/at-ease": "1.1.0", + "monolog/monolog": "1.14.0", + "oojs/oojs-ui": "0.12.12", + "oyejorge/less.php": "1.7.0.9", + "nmred/kafka-php": "0.1.4", + "php": ">=5.3.3", + "psr/log": "1.0.0", + "ruflin/elastica": "2.2.0", + "symfony/process": "2.7.3", + "wikimedia/assert": "0.2.2", + "wikimedia/avro": "1.7.7", + "wikimedia/cdb": "1.3.0", + "wikimedia/composer-merge-plugin": "1.3.0", + "wikimedia/ip-set": "1.0.1", + "wikimedia/utfnormal": "1.0.3", + "wikimedia/wrappedstring": "2.0.0", + "zordius/lightncandy": "0.21" + } +} diff --git a/vendor/composer.lock b/vendor/composer.lock new file mode 100644 index 00000000..cd4210d1 --- /dev/null +++ b/vendor/composer.lock @@ -0,0 +1,1064 @@ +{ + "_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": "a8e4bd12c298a91fbc07f1175b5ae66c", + "content-hash": "9662af67b5bbd488991d27c0f11a617b", + "packages": [ + { + "name": "composer/semver", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com" + }, + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2015-09-21 09:42:36" + }, + { + "name": "cssjanus/cssjanus", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/cssjanus/php-cssjanus.git", + "reference": "62a9c32e6e140de09082b40a6e99d868ad14d4e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cssjanus/php-cssjanus/zipball/62a9c32e6e140de09082b40a6e99d868ad14d4e0", + "reference": "62a9c32e6e140de09082b40a6e99d868ad14d4e0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.8.*", + "phpunit/phpunit": "3.7.*", + "squizlabs/php_codesniffer": "1.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Convert CSS stylesheets between left-to-right and right-to-left.", + "time": "2014-11-14 20:00:50" + }, + { + "name": "firebase/php-jwt", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "fb219727e199dd80a72d5274ebb5c8b24d58dd9b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/fb219727e199dd80a72d5274ebb5c8b24d58dd9b", + "reference": "fb219727e199dd80a72d5274ebb5c8b24d58dd9b", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "Authentication/", + "Exceptions/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "time": "2015-05-20 19:16:04" + }, + { + "name": "kzykhys/pygments", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/kzykhys/Pygments.php.git", + "reference": "7bde970d3c378d075ef0e005bb93a91055e17994" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kzykhys/Pygments.php/zipball/7bde970d3c378d075ef0e005bb93a91055e17994", + "reference": "7bde970d3c378d075ef0e005bb93a91055e17994", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/process": ">=2.3" + }, + "require-dev": { + "symfony/finder": ">=2.3" + }, + "type": "library", + "autoload": { + "psr-0": { + "": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "description": "A Thin Wrapper for the Python Pygments", + "time": "2013-12-18 15:22:37" + }, + { + "name": "liuggio/statsd-php-client", + "version": "v1.0.16", + "source": { + "type": "git", + "url": "https://github.com/liuggio/statsd-php-client.git", + "reference": "a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/liuggio/statsd-php-client/zipball/a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920", + "reference": "a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "monolog/monolog": ">=1.2.0" + }, + "suggest": { + "monolog/monolog": "Monolog, in order to do generate statistic from log >=1.2.0)" + }, + "type": "library", + "autoload": { + "psr-0": { + "Liuggio": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Giulio De Donato", + "email": "liuggio@gmail.com" + } + ], + "description": "Statsd (Object Oriented) client library for PHP", + "homepage": "https://github.com/liuggio/statsd-php-client/", + "keywords": [ + "etsy", + "monitoring", + "php", + "statsd" + ], + "time": "2015-04-27 08:12:26" + }, + { + "name": "mediawiki/at-ease", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/at-ease.git", + "reference": "94c0b84888841d160419f915c2745d9d08fbf0c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/at-ease/zipball/94c0b84888841d160419f915c2745d9d08fbf0c3", + "reference": "94c0b84888841d160419f915c2745d9d08fbf0c3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9", + "mediawiki/mediawiki-codesniffer": "0.3.0", + "phpunit/phpunit": "~4.5", + "squizlabs/php_codesniffer": "2.3.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Tim Starling", + "email": "tstarling@wikimedia.org" + }, + { + "name": "MediaWiki developers", + "email": "wikitech-l@lists.wikimedia.org" + } + ], + "description": "Safe replacement to @ for suppressing warnings.", + "homepage": "https://www.mediawiki.org/wiki/at-ease", + "time": "2015-09-18 07:02:06" + }, + { + "name": "monolog/monolog", + "version": "1.14.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "b287fbbe1ca27847064beff2bad7fb6920bf08cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b287fbbe1ca27847064beff2bad7fb6920bf08cc", + "reference": "b287fbbe1ca27847064beff2bad7fb6920bf08cc", + "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", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "raven/raven": "~0.8", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.14.x-dev" + } + }, + "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" + ], + "time": "2015-06-19 13:29:54" + }, + { + "name": "nmred/kafka-php", + "version": "v0.1.4", + "source": { + "type": "git", + "url": "https://github.com/nmred/kafka-php.git", + "reference": "06817c95e40b23918c3a420960ee9526e499275d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nmred/kafka-php/zipball/06817c95e40b23918c3a420960ee9526e499275d", + "reference": "06817c95e40b23918c3a420960ee9526e499275d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpcov": "*", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "psr-0": { + "Kafka\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Kafka client for php", + "homepage": "http://www.swanlinux.net", + "keywords": [ + "client", + "kafka" + ], + "time": "2015-09-06 01:39:05" + }, + { + "name": "oojs/oojs-ui", + "version": "v0.12.12", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/oojs-ui.git", + "reference": "221a66e8df215e767ff4b55b637138a73fcffdb2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/oojs-ui/zipball/221a66e8df215e767ff4b55b637138a73fcffdb2", + "reference": "221a66e8df215e767ff4b55b637138a73fcffdb2", + "shasum": "" + }, + "require": { + "mediawiki/at-ease": "1.1.0", + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9", + "mediawiki/mediawiki-codesniffer": "0.4.0", + "phpunit/phpunit": "~4.5" + }, + "type": "library", + "autoload": { + "classmap": [ + "php/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bartosz Dziewoński", + "email": "matma.rex@gmail.com" + }, + { + "name": "Ed Sanders", + "email": "esanders@wikimedia.org" + }, + { + "name": "James D. Forrester", + "email": "jforrester@wikimedia.org" + }, + { + "name": "Kirsten Menger-Anderson", + "email": "kmenger@wikimedia.org" + }, + { + "name": "Rob Moen", + "email": "rmoen@wikimedia.org" + }, + { + "name": "Roan Kattouw", + "email": "roan@wikimedia.org" + }, + { + "name": "Timo Tijhof", + "email": "timo@wikimedia.org" + }, + { + "name": "Trevor Parscal", + "email": "trevor@wikimedia.org" + } + ], + "description": "Provides library of common widgets, layouts, and windows.", + "homepage": "https://www.mediawiki.org/wiki/OOjs_UI", + "time": "2015-10-13 20:29:29" + }, + { + "name": "oyejorge/less.php", + "version": "v1.7.0.9", + "source": { + "type": "git", + "url": "https://github.com/oyejorge/less.php.git", + "reference": "fb64e2f6ef647a229c50e9fa0f2076240a3484c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/oyejorge/less.php/zipball/fb64e2f6ef647a229c50e9fa0f2076240a3484c6", + "reference": "fb64e2f6ef647a229c50e9fa0f2076240a3484c6", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "bin": [ + "bin/lessc" + ], + "type": "library", + "autoload": { + "psr-0": { + "Less": "lib/" + }, + "classmap": [ + "lessc.inc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Matt Agar", + "homepage": "https://github.com/agar" + }, + { + "name": "Martin Jantošovič", + "homepage": "https://github.com/Mordred" + }, + { + "name": "Josh Schmidt", + "homepage": "https://github.com/oyejorge" + } + ], + "description": "PHP port of the Javascript version of LESS http://lesscss.org", + "homepage": "http://lessphp.gpeasy.com", + "keywords": [ + "css", + "less", + "less.js", + "lesscss", + "php", + "stylesheet" + ], + "time": "2015-09-28 01:11:47" + }, + { + "name": "psr/log", + "version": "1.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": "" + }, + "type": "library", + "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" + ], + "time": "2012-12-21 11:40:51" + }, + { + "name": "ruflin/elastica", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/ruflin/Elastica.git", + "reference": "eb3a787259a6c50f87bce507ff24b124d91c4fe7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ruflin/Elastica/zipball/eb3a787259a6c50f87bce507ff24b124d91c4fe7", + "reference": "eb3a787259a6c50f87bce507ff24b124d91c4fe7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "psr/log": "~1.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "5.3.*", + "munkie/elasticsearch-thrift-php": "1.4.*" + }, + "suggest": { + "egeloen/http-adapter": "Allow using httpadapter transport", + "guzzlehttp/guzzle": "Allow using guzzle 5.3.x as the http transport (Requires php 5.4)", + "monolog/monolog": "Logging request", + "munkie/elasticsearch-thrift-php": "Allow using thrift transport" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Elastica\\": "lib/Elastica/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Ruflin", + "homepage": "http://ruflin.com/" + } + ], + "description": "Elasticsearch Client", + "homepage": "http://elastica.io/", + "keywords": [ + "client", + "search" + ], + "time": "2015-07-08 05:57:43" + }, + { + "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": "wikimedia/assert", + "version": "v0.2.2", + "source": { + "type": "git", + "url": "https://github.com/wmde/Assert.git", + "reference": "2da55927525975f8d52825fc3ee02e5e36f5036c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wmde/Assert/zipball/2da55927525975f8d52825fc3ee02e5e36f5036c", + "reference": "2da55927525975f8d52825fc3ee02e5e36f5036c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Wikimedia\\Assert\\": "src/", + "Wikimedia\\Assert\\Test\\": "tests/phpunit/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Kinzler" + } + ], + "description": "Provides runtime assertions", + "homepage": "https://github.com/wmde/Assert", + "keywords": [ + "assert", + "assertions", + "php", + "postcondition", + "precondition", + "qa" + ], + "time": "2015-04-29 17:23:50" + }, + { + "name": "wikimedia/avro", + "version": "v1.7.7", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/avro-php.git", + "reference": "b642da9fd895aab7cb3261a22624228115471f47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/avro-php/zipball/b642da9fd895aab7cb3261a22624228115471f47", + "reference": "b642da9fd895aab7cb3261a22624228115471f47", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9", + "phpunit/phpunit": "^4.0.0" + }, + "suggest": { + "ext-gmp": "Large integer support for 32-bit platforms." + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Michael Glaesemann", + "email": "grzm@seespotcode.net" + }, + { + "name": "Andy Wick", + "email": "awick@purple.org" + }, + { + "name": "Saleem Shafi", + "email": "saleemshafi@gmail.com" + }, + { + "name": "A B", + "email": "abawany@x.com" + }, + { + "name": "Doug Cutting", + "email": "cutting@apache.org" + }, + { + "name": "Tom White", + "email": "tom@cloudera.com" + } + ], + "description": "A library for using Apache Avro with PHP.", + "homepage": "https://avro.apache.org/", + "keywords": [ + "serialization" + ], + "time": "2015-09-05 18:49:27" + }, + { + "name": "wikimedia/cdb", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/cdb.git", + "reference": "68f8fd495ca94ca0e965dd511e234893c515bb95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/cdb/zipball/68f8fd495ca94ca0e965dd511e234893c515bb95", + "reference": "68f8fd495ca94ca0e965dd511e234893c515bb95", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9", + "mediawiki/mediawiki-codesniffer": "0.3.0", + "phpunit/phpunit": "4.6.*" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Tim Starling", + "email": "tstarling@wikimedia.org" + }, + { + "name": "Chad Horohoe", + "email": "chad@wikimedia.org" + }, + { + "name": "Ori Livneh", + "email": "ori@wikimedia.org" + } + ], + "description": "Constant Database (CDB) wrapper library for PHP. Provides pure-PHP fallback when dba_* functions are absent.", + "homepage": "https://www.mediawiki.org/wiki/CDB", + "time": "2015-09-08 19:53:04" + }, + { + "name": "wikimedia/composer-merge-plugin", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/composer-merge-plugin.git", + "reference": "bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9", + "reference": "bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": ">=5.3.2" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "jakub-onderka/php-parallel-lint": "~0.8", + "phpunit/phpunit": "~4.8|~5.0", + "squizlabs/php_codesniffer": "~2.1.0" + }, + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + }, + "class": "Wikimedia\\Composer\\MergePlugin" + }, + "autoload": { + "psr-4": { + "Wikimedia\\Composer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bryan Davis", + "email": "bd808@wikimedia.org" + } + ], + "description": "Composer plugin to merge multiple composer.json files", + "time": "2015-11-06 20:31:16" + }, + { + "name": "wikimedia/ip-set", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/IPSet.git", + "reference": "3c2dd6706546fe616e6ceba02044e64dce4fc9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/IPSet/zipball/3c2dd6706546fe616e6ceba02044e64dce4fc9be", + "reference": "3c2dd6706546fe616e6ceba02044e64dce4fc9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9", + "mediawiki/mediawiki-codesniffer": "0.3.0", + "phpunit/phpunit": "4.6.*" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Brandon Black", + "email": "blblack@gmail.com" + } + ], + "description": "Efficiently match IP addresses against a set of CIDR specifications.", + "homepage": "https://github.com/wikimedia/IPSet", + "time": "2015-06-29 20:21:27" + }, + { + "name": "wikimedia/utfnormal", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/utfnormal.git", + "reference": "bcb81d1d87bae400af45cc419a850dcf9883775b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/utfnormal/zipball/bcb81d1d87bae400af45cc419a850dcf9883775b", + "reference": "bcb81d1d87bae400af45cc419a850dcf9883775b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "ext-mbstring": "*", + "jakub-onderka/php-parallel-lint": "0.8.*", + "mediawiki/mediawiki-codesniffer": "0.1.0", + "phpunit/phpunit": "4.6.*", + "squizlabs/php_codesniffer": "2.2.*" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Brion Vibber", + "email": "bvibber@wikimedia.org" + } + ], + "description": "Contains Unicode normalization routines, including both pure PHP implementations and automatic use of the 'intl' PHP extension when present", + "homepage": "https://www.mediawiki.org/wiki/utfnormal", + "time": "2015-08-29 14:13:27" + }, + { + "name": "wikimedia/wrappedstring", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/WrappedString.git", + "reference": "1b27e0ea23bd915644dade17c3fe1e45fdbadf11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/WrappedString/zipball/1b27e0ea23bd915644dade17c3fe1e45fdbadf11", + "reference": "1b27e0ea23bd915644dade17c3fe1e45fdbadf11", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9.0.0", + "mediawiki/mediawiki-codesniffer": "^0.3.0.0", + "phpunit/phpunit": "^4.7.7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "WrappedString\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Timo Tijhof", + "email": "krinklemail@gmail.com" + } + ], + "description": "Automatically compact sequentially-outputted strings that share a common prefix / suffix pair.", + "homepage": "https://www.mediawiki.org/wiki/WrappedString", + "time": "2015-07-31 00:06:22" + }, + { + "name": "zordius/lightncandy", + "version": "v0.21", + "source": { + "type": "git", + "url": "https://github.com/zordius/lightncandy.git", + "reference": "015fed62d0ae6fe7601d3910b8e4b6a6964f86a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zordius/lightncandy/zipball/015fed62d0ae6fe7601d3910b8e4b6a6964f86a0", + "reference": "015fed62d0ae6fe7601d3910b8e4b6a6964f86a0", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.0.17" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/lightncandy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Zordius Chen", + "email": "zordius@yahoo-inc.com" + } + ], + "description": "An extremely fast PHP implementation of handlebars ( http://handlebarsjs.com/ ) and mustache ( http://mustache.github.io/ ).", + "homepage": "https://github.com/zordius/lightncandy", + "keywords": [ + "handlebars", + "logicless", + "mustache", + "php", + "template" + ], + "time": "2015-05-08 01:56:46" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=5.3.3" + }, + "platform-dev": [] +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 00000000..c8d57af8 --- /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 index 79053ea1..386604c2 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -3,9 +3,45 @@ // autoload_classmap.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); -$baseDir = dirname($vendorDir); +$baseDir = $vendorDir; return array( + 'Avro' => $vendorDir . '/wikimedia/avro/lib/avro.php', + 'AvroArraySchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroDataIO' => $vendorDir . '/wikimedia/avro/lib/avro/data_file.php', + 'AvroDataIOException' => $vendorDir . '/wikimedia/avro/lib/avro/data_file.php', + 'AvroDataIOReader' => $vendorDir . '/wikimedia/avro/lib/avro/data_file.php', + 'AvroDataIOWriter' => $vendorDir . '/wikimedia/avro/lib/avro/data_file.php', + 'AvroDebug' => $vendorDir . '/wikimedia/avro/lib/avro/debug.php', + 'AvroEnumSchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroException' => $vendorDir . '/wikimedia/avro/lib/avro.php', + 'AvroField' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroFile' => $vendorDir . '/wikimedia/avro/lib/avro/io.php', + 'AvroFixedSchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroGMP' => $vendorDir . '/wikimedia/avro/lib/avro/gmp.php', + 'AvroIO' => $vendorDir . '/wikimedia/avro/lib/avro/io.php', + 'AvroIOBinaryDecoder' => $vendorDir . '/wikimedia/avro/lib/avro/datum.php', + 'AvroIOBinaryEncoder' => $vendorDir . '/wikimedia/avro/lib/avro/datum.php', + 'AvroIODatumReader' => $vendorDir . '/wikimedia/avro/lib/avro/datum.php', + 'AvroIODatumWriter' => $vendorDir . '/wikimedia/avro/lib/avro/datum.php', + 'AvroIOException' => $vendorDir . '/wikimedia/avro/lib/avro/io.php', + 'AvroIOSchemaMatchException' => $vendorDir . '/wikimedia/avro/lib/avro/datum.php', + 'AvroIOTypeException' => $vendorDir . '/wikimedia/avro/lib/avro/datum.php', + 'AvroMapSchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroName' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroNamedSchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroNamedSchemata' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroPrimitiveSchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroProtocol' => $vendorDir . '/wikimedia/avro/lib/avro/protocol.php', + 'AvroProtocolMessage' => $vendorDir . '/wikimedia/avro/lib/avro/protocol.php', + 'AvroProtocolParseException' => $vendorDir . '/wikimedia/avro/lib/avro/protocol.php', + 'AvroRecordSchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroSchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroSchemaParseException' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroStringIO' => $vendorDir . '/wikimedia/avro/lib/avro/io.php', + 'AvroUnionSchema' => $vendorDir . '/wikimedia/avro/lib/avro/schema.php', + 'AvroUtil' => $vendorDir . '/wikimedia/avro/lib/avro/util.php', + 'BeforeValidException' => $vendorDir . '/firebase/php-jwt/Exceptions/BeforeValidException.php', 'CSSJanus' => $vendorDir . '/cssjanus/cssjanus/src/CSSJanus.php', 'CSSJanusTokenizer' => $vendorDir . '/cssjanus/cssjanus/src/CSSJanus.php', 'Cdb\\Exception' => $vendorDir . '/wikimedia/cdb/src/Exception.php', @@ -16,8 +52,322 @@ return array( 'Cdb\\Writer' => $vendorDir . '/wikimedia/cdb/src/Writer.php', 'Cdb\\Writer\\DBA' => $vendorDir . '/wikimedia/cdb/src/Writer/DBA.php', 'Cdb\\Writer\\PHP' => $vendorDir . '/wikimedia/cdb/src/Writer/PHP.php', - 'ComposerHookHandler' => $baseDir . '/includes/composer/ComposerHookHandler.php', + 'Composer\\Semver\\Comparator' => $vendorDir . '/composer/semver/src/Comparator.php', + 'Composer\\Semver\\Constraint\\AbstractConstraint' => $vendorDir . '/composer/semver/src/Constraint/AbstractConstraint.php', + 'Composer\\Semver\\Constraint\\Constraint' => $vendorDir . '/composer/semver/src/Constraint/Constraint.php', + 'Composer\\Semver\\Constraint\\ConstraintInterface' => $vendorDir . '/composer/semver/src/Constraint/ConstraintInterface.php', + 'Composer\\Semver\\Constraint\\EmptyConstraint' => $vendorDir . '/composer/semver/src/Constraint/EmptyConstraint.php', + 'Composer\\Semver\\Constraint\\MultiConstraint' => $vendorDir . '/composer/semver/src/Constraint/MultiConstraint.php', + 'Composer\\Semver\\Semver' => $vendorDir . '/composer/semver/src/Semver.php', + 'Composer\\Semver\\VersionParser' => $vendorDir . '/composer/semver/src/VersionParser.php', + 'Elastica\\AbstractUpdateAction' => $vendorDir . '/ruflin/elastica/lib/Elastica/AbstractUpdateAction.php', + 'Elastica\\Aggregation\\AbstractAggregation' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/AbstractAggregation.php', + 'Elastica\\Aggregation\\AbstractSimpleAggregation' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/AbstractSimpleAggregation.php', + 'Elastica\\Aggregation\\AbstractTermsAggregation' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/AbstractTermsAggregation.php', + 'Elastica\\Aggregation\\Avg' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Avg.php', + 'Elastica\\Aggregation\\Cardinality' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Cardinality.php', + 'Elastica\\Aggregation\\DateHistogram' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/DateHistogram.php', + 'Elastica\\Aggregation\\DateRange' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/DateRange.php', + 'Elastica\\Aggregation\\ExtendedStats' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/ExtendedStats.php', + 'Elastica\\Aggregation\\Filter' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Filter.php', + 'Elastica\\Aggregation\\Filters' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Filters.php', + 'Elastica\\Aggregation\\GeoDistance' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/GeoDistance.php', + 'Elastica\\Aggregation\\GeohashGrid' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/GeohashGrid.php', + 'Elastica\\Aggregation\\GlobalAggregation' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/GlobalAggregation.php', + 'Elastica\\Aggregation\\Histogram' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Histogram.php', + 'Elastica\\Aggregation\\IpRange' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/IpRange.php', + 'Elastica\\Aggregation\\Max' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Max.php', + 'Elastica\\Aggregation\\Min' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Min.php', + 'Elastica\\Aggregation\\Missing' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Missing.php', + 'Elastica\\Aggregation\\Nested' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Nested.php', + 'Elastica\\Aggregation\\Percentiles' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Percentiles.php', + 'Elastica\\Aggregation\\Range' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Range.php', + 'Elastica\\Aggregation\\ReverseNested' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/ReverseNested.php', + 'Elastica\\Aggregation\\ScriptedMetric' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/ScriptedMetric.php', + 'Elastica\\Aggregation\\SignificantTerms' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/SignificantTerms.php', + 'Elastica\\Aggregation\\Stats' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Stats.php', + 'Elastica\\Aggregation\\Sum' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Sum.php', + 'Elastica\\Aggregation\\Terms' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/Terms.php', + 'Elastica\\Aggregation\\TopHits' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/TopHits.php', + 'Elastica\\Aggregation\\ValueCount' => $vendorDir . '/ruflin/elastica/lib/Elastica/Aggregation/ValueCount.php', + 'Elastica\\Bulk' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk.php', + 'Elastica\\Bulk\\Action' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk/Action.php', + 'Elastica\\Bulk\\Action\\AbstractDocument' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk/Action/AbstractDocument.php', + 'Elastica\\Bulk\\Action\\CreateDocument' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk/Action/CreateDocument.php', + 'Elastica\\Bulk\\Action\\DeleteDocument' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk/Action/DeleteDocument.php', + 'Elastica\\Bulk\\Action\\IndexDocument' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk/Action/IndexDocument.php', + 'Elastica\\Bulk\\Action\\UpdateDocument' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk/Action/UpdateDocument.php', + 'Elastica\\Bulk\\Response' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk/Response.php', + 'Elastica\\Bulk\\ResponseSet' => $vendorDir . '/ruflin/elastica/lib/Elastica/Bulk/ResponseSet.php', + 'Elastica\\Client' => $vendorDir . '/ruflin/elastica/lib/Elastica/Client.php', + 'Elastica\\Cluster' => $vendorDir . '/ruflin/elastica/lib/Elastica/Cluster.php', + 'Elastica\\Cluster\\Health' => $vendorDir . '/ruflin/elastica/lib/Elastica/Cluster/Health.php', + 'Elastica\\Cluster\\Health\\Index' => $vendorDir . '/ruflin/elastica/lib/Elastica/Cluster/Health/Index.php', + 'Elastica\\Cluster\\Health\\Shard' => $vendorDir . '/ruflin/elastica/lib/Elastica/Cluster/Health/Shard.php', + 'Elastica\\Cluster\\Settings' => $vendorDir . '/ruflin/elastica/lib/Elastica/Cluster/Settings.php', + 'Elastica\\Connection' => $vendorDir . '/ruflin/elastica/lib/Elastica/Connection.php', + 'Elastica\\Connection\\ConnectionPool' => $vendorDir . '/ruflin/elastica/lib/Elastica/Connection/ConnectionPool.php', + 'Elastica\\Connection\\Strategy\\CallbackStrategy' => $vendorDir . '/ruflin/elastica/lib/Elastica/Connection/Strategy/CallbackStrategy.php', + 'Elastica\\Connection\\Strategy\\RoundRobin' => $vendorDir . '/ruflin/elastica/lib/Elastica/Connection/Strategy/RoundRobin.php', + 'Elastica\\Connection\\Strategy\\Simple' => $vendorDir . '/ruflin/elastica/lib/Elastica/Connection/Strategy/Simple.php', + 'Elastica\\Connection\\Strategy\\StrategyFactory' => $vendorDir . '/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyFactory.php', + 'Elastica\\Connection\\Strategy\\StrategyInterface' => $vendorDir . '/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyInterface.php', + 'Elastica\\Document' => $vendorDir . '/ruflin/elastica/lib/Elastica/Document.php', + 'Elastica\\Exception\\BulkException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/BulkException.php', + 'Elastica\\Exception\\Bulk\\ResponseException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/Bulk/ResponseException.php', + 'Elastica\\Exception\\Bulk\\Response\\ActionException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/Bulk/Response/ActionException.php', + 'Elastica\\Exception\\Bulk\\UdpException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/Bulk/UdpException.php', + 'Elastica\\Exception\\ClientException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/ClientException.php', + 'Elastica\\Exception\\ConnectionException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/ConnectionException.php', + 'Elastica\\Exception\\Connection\\GuzzleException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/Connection/GuzzleException.php', + 'Elastica\\Exception\\Connection\\HttpException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/Connection/HttpException.php', + 'Elastica\\Exception\\Connection\\MemcacheException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/Connection/MemcacheException.php', + 'Elastica\\Exception\\Connection\\ThriftException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/Connection/ThriftException.php', + 'Elastica\\Exception\\ElasticsearchException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/ElasticsearchException.php', + 'Elastica\\Exception\\ExceptionInterface' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/ExceptionInterface.php', + 'Elastica\\Exception\\InvalidException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/InvalidException.php', + 'Elastica\\Exception\\JSONParseException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/JSONParseException.php', + 'Elastica\\Exception\\NotFoundException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/NotFoundException.php', + 'Elastica\\Exception\\NotImplementedException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/NotImplementedException.php', + 'Elastica\\Exception\\PartialShardFailureException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/PartialShardFailureException.php', + 'Elastica\\Exception\\QueryBuilderException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/QueryBuilderException.php', + 'Elastica\\Exception\\ResponseException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/ResponseException.php', + 'Elastica\\Exception\\RuntimeException' => $vendorDir . '/ruflin/elastica/lib/Elastica/Exception/RuntimeException.php', + 'Elastica\\Facet\\AbstractFacet' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/AbstractFacet.php', + 'Elastica\\Facet\\DateHistogram' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/DateHistogram.php', + 'Elastica\\Facet\\Filter' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/Filter.php', + 'Elastica\\Facet\\GeoCluster' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/GeoCluster.php', + 'Elastica\\Facet\\GeoDistance' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/GeoDistance.php', + 'Elastica\\Facet\\Histogram' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/Histogram.php', + 'Elastica\\Facet\\Query' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/Query.php', + 'Elastica\\Facet\\Range' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/Range.php', + 'Elastica\\Facet\\Statistical' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/Statistical.php', + 'Elastica\\Facet\\Terms' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/Terms.php', + 'Elastica\\Facet\\TermsStats' => $vendorDir . '/ruflin/elastica/lib/Elastica/Facet/TermsStats.php', + 'Elastica\\Filter\\AbstractFilter' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/AbstractFilter.php', + 'Elastica\\Filter\\AbstractGeoDistance' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/AbstractGeoDistance.php', + 'Elastica\\Filter\\AbstractGeoShape' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/AbstractGeoShape.php', + 'Elastica\\Filter\\AbstractMulti' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/AbstractMulti.php', + 'Elastica\\Filter\\Bool' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Bool.php', + 'Elastica\\Filter\\BoolAnd' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/BoolAnd.php', + 'Elastica\\Filter\\BoolFilter' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/BoolFilter.php', + 'Elastica\\Filter\\BoolNot' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/BoolNot.php', + 'Elastica\\Filter\\BoolOr' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/BoolOr.php', + 'Elastica\\Filter\\Exists' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Exists.php', + 'Elastica\\Filter\\GeoBoundingBox' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/GeoBoundingBox.php', + 'Elastica\\Filter\\GeoDistance' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/GeoDistance.php', + 'Elastica\\Filter\\GeoDistanceRange' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/GeoDistanceRange.php', + 'Elastica\\Filter\\GeoPolygon' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/GeoPolygon.php', + 'Elastica\\Filter\\GeoShapePreIndexed' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/GeoShapePreIndexed.php', + 'Elastica\\Filter\\GeoShapeProvided' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/GeoShapeProvided.php', + 'Elastica\\Filter\\GeohashCell' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/GeohashCell.php', + 'Elastica\\Filter\\HasChild' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/HasChild.php', + 'Elastica\\Filter\\HasParent' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/HasParent.php', + 'Elastica\\Filter\\Ids' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Ids.php', + 'Elastica\\Filter\\Indices' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Indices.php', + 'Elastica\\Filter\\Limit' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Limit.php', + 'Elastica\\Filter\\MatchAll' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/MatchAll.php', + 'Elastica\\Filter\\Missing' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Missing.php', + 'Elastica\\Filter\\Nested' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Nested.php', + 'Elastica\\Filter\\NumericRange' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/NumericRange.php', + 'Elastica\\Filter\\Prefix' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Prefix.php', + 'Elastica\\Filter\\Query' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Query.php', + 'Elastica\\Filter\\Range' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Range.php', + 'Elastica\\Filter\\Regexp' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Regexp.php', + 'Elastica\\Filter\\Script' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Script.php', + 'Elastica\\Filter\\Term' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Term.php', + 'Elastica\\Filter\\Terms' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Terms.php', + 'Elastica\\Filter\\Type' => $vendorDir . '/ruflin/elastica/lib/Elastica/Filter/Type.php', + 'Elastica\\Index' => $vendorDir . '/ruflin/elastica/lib/Elastica/Index.php', + 'Elastica\\Index\\Settings' => $vendorDir . '/ruflin/elastica/lib/Elastica/Index/Settings.php', + 'Elastica\\Index\\Stats' => $vendorDir . '/ruflin/elastica/lib/Elastica/Index/Stats.php', + 'Elastica\\Index\\Status' => $vendorDir . '/ruflin/elastica/lib/Elastica/Index/Status.php', + 'Elastica\\JSON' => $vendorDir . '/ruflin/elastica/lib/Elastica/JSON.php', + 'Elastica\\Log' => $vendorDir . '/ruflin/elastica/lib/Elastica/Log.php', + 'Elastica\\Multi\\ResultSet' => $vendorDir . '/ruflin/elastica/lib/Elastica/Multi/ResultSet.php', + 'Elastica\\Multi\\Search' => $vendorDir . '/ruflin/elastica/lib/Elastica/Multi/Search.php', + 'Elastica\\Node' => $vendorDir . '/ruflin/elastica/lib/Elastica/Node.php', + 'Elastica\\Node\\Info' => $vendorDir . '/ruflin/elastica/lib/Elastica/Node/Info.php', + 'Elastica\\Node\\Stats' => $vendorDir . '/ruflin/elastica/lib/Elastica/Node/Stats.php', + 'Elastica\\Param' => $vendorDir . '/ruflin/elastica/lib/Elastica/Param.php', + 'Elastica\\Percolator' => $vendorDir . '/ruflin/elastica/lib/Elastica/Percolator.php', + 'Elastica\\Query' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query.php', + 'Elastica\\QueryBuilder' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder.php', + 'Elastica\\QueryBuilder\\DSL' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/DSL.php', + 'Elastica\\QueryBuilder\\DSL\\Aggregation' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Aggregation.php', + 'Elastica\\QueryBuilder\\DSL\\Filter' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Filter.php', + 'Elastica\\QueryBuilder\\DSL\\Query' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Query.php', + 'Elastica\\QueryBuilder\\DSL\\Suggest' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Suggest.php', + 'Elastica\\QueryBuilder\\Facade' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Facade.php', + 'Elastica\\QueryBuilder\\Version' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Version.php', + 'Elastica\\QueryBuilder\\Version\\Version090' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version090.php', + 'Elastica\\QueryBuilder\\Version\\Version100' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version100.php', + 'Elastica\\QueryBuilder\\Version\\Version110' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version110.php', + 'Elastica\\QueryBuilder\\Version\\Version120' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version120.php', + 'Elastica\\QueryBuilder\\Version\\Version130' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version130.php', + 'Elastica\\QueryBuilder\\Version\\Version140' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version140.php', + 'Elastica\\QueryBuilder\\Version\\Version150' => $vendorDir . '/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version150.php', + 'Elastica\\Query\\AbstractQuery' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/AbstractQuery.php', + 'Elastica\\Query\\Bool' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Bool.php', + 'Elastica\\Query\\BoolQuery' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/BoolQuery.php', + 'Elastica\\Query\\Boosting' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Boosting.php', + 'Elastica\\Query\\Builder' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Builder.php', + 'Elastica\\Query\\Common' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Common.php', + 'Elastica\\Query\\ConstantScore' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/ConstantScore.php', + 'Elastica\\Query\\DisMax' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/DisMax.php', + 'Elastica\\Query\\Filtered' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Filtered.php', + 'Elastica\\Query\\FunctionScore' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/FunctionScore.php', + 'Elastica\\Query\\Fuzzy' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Fuzzy.php', + 'Elastica\\Query\\FuzzyLikeThis' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/FuzzyLikeThis.php', + 'Elastica\\Query\\HasChild' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/HasChild.php', + 'Elastica\\Query\\HasParent' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/HasParent.php', + 'Elastica\\Query\\Ids' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Ids.php', + 'Elastica\\Query\\Image' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Image.php', + 'Elastica\\Query\\Match' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Match.php', + 'Elastica\\Query\\MatchAll' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/MatchAll.php', + 'Elastica\\Query\\MatchPhrase' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/MatchPhrase.php', + 'Elastica\\Query\\MatchPhrasePrefix' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/MatchPhrasePrefix.php', + 'Elastica\\Query\\MoreLikeThis' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/MoreLikeThis.php', + 'Elastica\\Query\\MultiMatch' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/MultiMatch.php', + 'Elastica\\Query\\Nested' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Nested.php', + 'Elastica\\Query\\Prefix' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Prefix.php', + 'Elastica\\Query\\QueryString' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/QueryString.php', + 'Elastica\\Query\\Range' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Range.php', + 'Elastica\\Query\\Regexp' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Regexp.php', + 'Elastica\\Query\\Simple' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Simple.php', + 'Elastica\\Query\\SimpleQueryString' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/SimpleQueryString.php', + 'Elastica\\Query\\Term' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Term.php', + 'Elastica\\Query\\Terms' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Terms.php', + 'Elastica\\Query\\TopChildren' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/TopChildren.php', + 'Elastica\\Query\\Wildcard' => $vendorDir . '/ruflin/elastica/lib/Elastica/Query/Wildcard.php', + 'Elastica\\Request' => $vendorDir . '/ruflin/elastica/lib/Elastica/Request.php', + 'Elastica\\Rescore\\AbstractRescore' => $vendorDir . '/ruflin/elastica/lib/Elastica/Rescore/AbstractRescore.php', + 'Elastica\\Rescore\\Query' => $vendorDir . '/ruflin/elastica/lib/Elastica/Rescore/Query.php', + 'Elastica\\Response' => $vendorDir . '/ruflin/elastica/lib/Elastica/Response.php', + 'Elastica\\Result' => $vendorDir . '/ruflin/elastica/lib/Elastica/Result.php', + 'Elastica\\ResultSet' => $vendorDir . '/ruflin/elastica/lib/Elastica/ResultSet.php', + 'Elastica\\ScanAndScroll' => $vendorDir . '/ruflin/elastica/lib/Elastica/ScanAndScroll.php', + 'Elastica\\Script' => $vendorDir . '/ruflin/elastica/lib/Elastica/Script.php', + 'Elastica\\ScriptFields' => $vendorDir . '/ruflin/elastica/lib/Elastica/ScriptFields.php', + 'Elastica\\Scroll' => $vendorDir . '/ruflin/elastica/lib/Elastica/Scroll.php', + 'Elastica\\Search' => $vendorDir . '/ruflin/elastica/lib/Elastica/Search.php', + 'Elastica\\SearchableInterface' => $vendorDir . '/ruflin/elastica/lib/Elastica/SearchableInterface.php', + 'Elastica\\Snapshot' => $vendorDir . '/ruflin/elastica/lib/Elastica/Snapshot.php', + 'Elastica\\Status' => $vendorDir . '/ruflin/elastica/lib/Elastica/Status.php', + 'Elastica\\Suggest' => $vendorDir . '/ruflin/elastica/lib/Elastica/Suggest.php', + 'Elastica\\Suggest\\AbstractSuggest' => $vendorDir . '/ruflin/elastica/lib/Elastica/Suggest/AbstractSuggest.php', + 'Elastica\\Suggest\\CandidateGenerator\\AbstractCandidateGenerator' => $vendorDir . '/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/AbstractCandidateGenerator.php', + 'Elastica\\Suggest\\CandidateGenerator\\DirectGenerator' => $vendorDir . '/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/DirectGenerator.php', + 'Elastica\\Suggest\\Completion' => $vendorDir . '/ruflin/elastica/lib/Elastica/Suggest/Completion.php', + 'Elastica\\Suggest\\Phrase' => $vendorDir . '/ruflin/elastica/lib/Elastica/Suggest/Phrase.php', + 'Elastica\\Suggest\\Term' => $vendorDir . '/ruflin/elastica/lib/Elastica/Suggest/Term.php', + 'Elastica\\Tool\\CrossIndex' => $vendorDir . '/ruflin/elastica/lib/Elastica/Tool/CrossIndex.php', + 'Elastica\\Transport\\AbstractTransport' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/AbstractTransport.php', + 'Elastica\\Transport\\Guzzle' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/Guzzle.php', + 'Elastica\\Transport\\Http' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/Http.php', + 'Elastica\\Transport\\HttpAdapter' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/HttpAdapter.php', + 'Elastica\\Transport\\Https' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/Https.php', + 'Elastica\\Transport\\Memcache' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/Memcache.php', + 'Elastica\\Transport\\Null' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/Null.php', + 'Elastica\\Transport\\NullTransport' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/NullTransport.php', + 'Elastica\\Transport\\Thrift' => $vendorDir . '/ruflin/elastica/lib/Elastica/Transport/Thrift.php', + 'Elastica\\Type' => $vendorDir . '/ruflin/elastica/lib/Elastica/Type.php', + 'Elastica\\Type\\AbstractType' => $vendorDir . '/ruflin/elastica/lib/Elastica/Type/AbstractType.php', + 'Elastica\\Type\\Mapping' => $vendorDir . '/ruflin/elastica/lib/Elastica/Type/Mapping.php', + 'Elastica\\Util' => $vendorDir . '/ruflin/elastica/lib/Elastica/Util.php', + 'ExpiredException' => $vendorDir . '/firebase/php-jwt/Exceptions/ExpiredException.php', + 'IPSet\\IPSet' => $vendorDir . '/wikimedia/ip-set/src/IPSet.php', + 'JWT' => $vendorDir . '/firebase/php-jwt/Authentication/JWT.php', + 'Kafka\\Client' => $vendorDir . '/nmred/kafka-php/src/Kafka/Client.php', + 'Kafka\\ClusterMetaData' => $vendorDir . '/nmred/kafka-php/src/Kafka/ClusterMetaData.php', + 'Kafka\\Consumer' => $vendorDir . '/nmred/kafka-php/src/Kafka/Consumer.php', + 'Kafka\\Exception' => $vendorDir . '/nmred/kafka-php/src/Kafka/Exception.php', + 'Kafka\\Exception\\NotSupported' => $vendorDir . '/nmred/kafka-php/src/Kafka/Exception/NotSupported.php', + 'Kafka\\Exception\\OutOfRange' => $vendorDir . '/nmred/kafka-php/src/Kafka/Exception/OutOfRange.php', + 'Kafka\\Exception\\Protocol' => $vendorDir . '/nmred/kafka-php/src/Kafka/Exception/Protocol.php', + 'Kafka\\Exception\\Socket' => $vendorDir . '/nmred/kafka-php/src/Kafka/Exception/Socket.php', + 'Kafka\\Exception\\SocketConnect' => $vendorDir . '/nmred/kafka-php/src/Kafka/Exception/SocketConnect.php', + 'Kafka\\Exception\\SocketEOF' => $vendorDir . '/nmred/kafka-php/src/Kafka/Exception/SocketEOF.php', + 'Kafka\\Exception\\SocketTimeout' => $vendorDir . '/nmred/kafka-php/src/Kafka/Exception/SocketTimeout.php', + 'Kafka\\Log' => $vendorDir . '/nmred/kafka-php/src/Kafka/Log.php', + 'Kafka\\MetaDataFromKafka' => $vendorDir . '/nmred/kafka-php/src/Kafka/MetaDataFromKafka.php', + 'Kafka\\Offset' => $vendorDir . '/nmred/kafka-php/src/Kafka/Offset.php', + 'Kafka\\Produce' => $vendorDir . '/nmred/kafka-php/src/Kafka/Produce.php', + 'Kafka\\Protocol\\Decoder' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Decoder.php', + 'Kafka\\Protocol\\Encoder' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Encoder.php', + 'Kafka\\Protocol\\Fetch\\Helper\\CommitOffset' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/CommitOffset.php', + 'Kafka\\Protocol\\Fetch\\Helper\\Consumer' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Consumer.php', + 'Kafka\\Protocol\\Fetch\\Helper\\FreeStream' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/FreeStream.php', + 'Kafka\\Protocol\\Fetch\\Helper\\Helper' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Helper.php', + 'Kafka\\Protocol\\Fetch\\Helper\\HelperAbstract' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/HelperAbstract.php', + 'Kafka\\Protocol\\Fetch\\Message' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/Message.php', + 'Kafka\\Protocol\\Fetch\\MessageSet' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/MessageSet.php', + 'Kafka\\Protocol\\Fetch\\Partition' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/Partition.php', + 'Kafka\\Protocol\\Fetch\\Topic' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Fetch/Topic.php', + 'Kafka\\Protocol\\Protocol' => $vendorDir . '/nmred/kafka-php/src/Kafka/Protocol/Protocol.php', + 'Kafka\\Socket' => $vendorDir . '/nmred/kafka-php/src/Kafka/Socket.php', + 'Kafka\\ZooKeeper' => $vendorDir . '/nmred/kafka-php/src/Kafka/ZooKeeper.php', + 'KzykHys\\Pygments\\Pygments' => $vendorDir . '/kzykhys/pygments/src/KzykHys/Pygments/Pygments.php', 'LCRun3' => $vendorDir . '/zordius/lightncandy/src/lightncandy.php', + 'Less_Autoloader' => $vendorDir . '/oyejorge/less.php/lib/Less/Autoloader.php', + 'Less_Cache' => $vendorDir . '/oyejorge/less.php/lib/Less/Cache.php', + 'Less_Colors' => $vendorDir . '/oyejorge/less.php/lib/Less/Colors.php', + 'Less_Configurable' => $vendorDir . '/oyejorge/less.php/lib/Less/Configurable.php', + 'Less_Environment' => $vendorDir . '/oyejorge/less.php/lib/Less/Environment.php', + 'Less_Exception_Chunk' => $vendorDir . '/oyejorge/less.php/lib/Less/Exception/Chunk.php', + 'Less_Exception_Compiler' => $vendorDir . '/oyejorge/less.php/lib/Less/Exception/Compiler.php', + 'Less_Exception_Parser' => $vendorDir . '/oyejorge/less.php/lib/Less/Exception/Parser.php', + 'Less_Functions' => $vendorDir . '/oyejorge/less.php/lib/Less/Functions.php', + 'Less_Mime' => $vendorDir . '/oyejorge/less.php/lib/Less/Mime.php', + 'Less_Output' => $vendorDir . '/oyejorge/less.php/lib/Less/Output.php', + 'Less_Output_Mapped' => $vendorDir . '/oyejorge/less.php/lib/Less/Output/Mapped.php', + 'Less_Parser' => $vendorDir . '/oyejorge/less.php/lib/Less/Parser.php', + 'Less_SourceMap_Base64VLQ' => $vendorDir . '/oyejorge/less.php/lib/Less/SourceMap/Base64VLQ.php', + 'Less_SourceMap_Generator' => $vendorDir . '/oyejorge/less.php/lib/Less/SourceMap/Generator.php', + 'Less_Tree' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree.php', + 'Less_Tree_Alpha' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Alpha.php', + 'Less_Tree_Anonymous' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Anonymous.php', + 'Less_Tree_Assignment' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Assignment.php', + 'Less_Tree_Attribute' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Attribute.php', + 'Less_Tree_Call' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Call.php', + 'Less_Tree_Color' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Color.php', + 'Less_Tree_Comment' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Comment.php', + 'Less_Tree_Condition' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Condition.php', + 'Less_Tree_DefaultFunc' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/DefaultFunc.php', + 'Less_Tree_DetachedRuleset' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/DetachedRuleset.php', + 'Less_Tree_Dimension' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Dimension.php', + 'Less_Tree_Directive' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Directive.php', + 'Less_Tree_Element' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Element.php', + 'Less_Tree_Expression' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Expression.php', + 'Less_Tree_Extend' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Extend.php', + 'Less_Tree_Import' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Import.php', + 'Less_Tree_Javascript' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Javascript.php', + 'Less_Tree_Keyword' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Keyword.php', + 'Less_Tree_Media' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Media.php', + 'Less_Tree_Mixin_Call' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Mixin/Call.php', + 'Less_Tree_Mixin_Definition' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Mixin/Definition.php', + 'Less_Tree_NameValue' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/NameValue.php', + 'Less_Tree_Negative' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Negative.php', + 'Less_Tree_Operation' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Operation.php', + 'Less_Tree_Paren' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Paren.php', + 'Less_Tree_Quoted' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Quoted.php', + 'Less_Tree_Rule' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Rule.php', + 'Less_Tree_Ruleset' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Ruleset.php', + 'Less_Tree_RulesetCall' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/RulesetCall.php', + 'Less_Tree_Selector' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Selector.php', + 'Less_Tree_UnicodeDescriptor' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/UnicodeDescriptor.php', + 'Less_Tree_Unit' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Unit.php', + 'Less_Tree_UnitConversions' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/UnitConversions.php', + 'Less_Tree_Url' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Url.php', + 'Less_Tree_Value' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Value.php', + 'Less_Tree_Variable' => $vendorDir . '/oyejorge/less.php/lib/Less/Tree/Variable.php', + 'Less_Version' => $vendorDir . '/oyejorge/less.php/lib/Less/Version.php', + 'Less_Visitor' => $vendorDir . '/oyejorge/less.php/lib/Less/Visitor.php', + 'Less_VisitorReplacing' => $vendorDir . '/oyejorge/less.php/lib/Less/VisitorReplacing.php', + 'Less_Visitor_extendFinder' => $vendorDir . '/oyejorge/less.php/lib/Less/Visitor/extendFinder.php', + 'Less_Visitor_joinSelector' => $vendorDir . '/oyejorge/less.php/lib/Less/Visitor/joinSelector.php', + 'Less_Visitor_processExtends' => $vendorDir . '/oyejorge/less.php/lib/Less/Visitor/processExtends.php', + 'Less_Visitor_toCSS' => $vendorDir . '/oyejorge/less.php/lib/Less/Visitor/toCSS.php', 'LightnCandy' => $vendorDir . '/zordius/lightncandy/src/lightncandy.php', 'Liuggio\\StatsdClient\\Entity\\StatsdData' => $vendorDir . '/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php', 'Liuggio\\StatsdClient\\Entity\\StatsdDataInterface' => $vendorDir . '/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php', @@ -30,10 +380,92 @@ return array( 'Liuggio\\StatsdClient\\Sender\\SenderInterface' => $vendorDir . '/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Sender/SenderInterface.php', 'Liuggio\\StatsdClient\\Sender\\SocketSender' => $vendorDir . '/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Sender/SocketSender.php', 'Liuggio\\StatsdClient\\Sender\\SysLogSender' => $vendorDir . '/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Sender/SysLogSender.php', + 'Liuggio\\StatsdClient\\Service\\StatsdService' => $vendorDir . '/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php', 'Liuggio\\StatsdClient\\StatsdClient' => $vendorDir . '/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php', 'Liuggio\\StatsdClient\\StatsdClientInterface' => $vendorDir . '/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClientInterface.php', + 'Monolog\\ErrorHandler' => $vendorDir . '/monolog/monolog/src/Monolog/ErrorHandler.php', + 'Monolog\\Formatter\\ChromePHPFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php', + 'Monolog\\Formatter\\ElasticaFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php', + 'Monolog\\Formatter\\FlowdockFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php', + 'Monolog\\Formatter\\FormatterInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php', + 'Monolog\\Formatter\\GelfMessageFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php', + 'Monolog\\Formatter\\HtmlFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php', + 'Monolog\\Formatter\\JsonFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php', + 'Monolog\\Formatter\\LineFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/LineFormatter.php', + 'Monolog\\Formatter\\LogglyFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php', + 'Monolog\\Formatter\\LogstashFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php', + 'Monolog\\Formatter\\MongoDBFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php', + 'Monolog\\Formatter\\NormalizerFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php', + 'Monolog\\Formatter\\ScalarFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php', + 'Monolog\\Formatter\\WildfireFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php', + 'Monolog\\Handler\\AbstractHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractHandler.php', + 'Monolog\\Handler\\AbstractProcessingHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php', + 'Monolog\\Handler\\AbstractSyslogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php', + 'Monolog\\Handler\\AmqpHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AmqpHandler.php', + 'Monolog\\Handler\\BrowserConsoleHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php', + 'Monolog\\Handler\\BufferHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/BufferHandler.php', + 'Monolog\\Handler\\ChromePHPHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php', + 'Monolog\\Handler\\CouchDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php', + 'Monolog\\Handler\\CubeHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/CubeHandler.php', + 'Monolog\\Handler\\DoctrineCouchDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php', + 'Monolog\\Handler\\DynamoDbHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php', + 'Monolog\\Handler\\ElasticSearchHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php', + 'Monolog\\Handler\\ErrorLogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php', + 'Monolog\\Handler\\FilterHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FilterHandler.php', + 'Monolog\\Handler\\FingersCrossedHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php', + 'Monolog\\Handler\\FingersCrossed\\ActivationStrategyInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php', + 'Monolog\\Handler\\FingersCrossed\\ChannelLevelActivationStrategy' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php', + 'Monolog\\Handler\\FingersCrossed\\ErrorLevelActivationStrategy' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php', + 'Monolog\\Handler\\FirePHPHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php', + 'Monolog\\Handler\\FleepHookHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php', + 'Monolog\\Handler\\FlowdockHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php', + 'Monolog\\Handler\\GelfHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/GelfHandler.php', + 'Monolog\\Handler\\GroupHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/GroupHandler.php', + 'Monolog\\Handler\\HandlerInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/HandlerInterface.php', + 'Monolog\\Handler\\HipChatHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/HipChatHandler.php', + 'Monolog\\Handler\\LogEntriesHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php', + 'Monolog\\Handler\\LogglyHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/LogglyHandler.php', + 'Monolog\\Handler\\MailHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MailHandler.php', + 'Monolog\\Handler\\MandrillHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MandrillHandler.php', + 'Monolog\\Handler\\MissingExtensionException' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php', + 'Monolog\\Handler\\MongoDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php', + 'Monolog\\Handler\\NativeMailerHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php', + 'Monolog\\Handler\\NewRelicHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php', + 'Monolog\\Handler\\NullHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NullHandler.php', + 'Monolog\\Handler\\PHPConsoleHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php', + 'Monolog\\Handler\\PsrHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/PsrHandler.php', + 'Monolog\\Handler\\PushoverHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/PushoverHandler.php', + 'Monolog\\Handler\\RavenHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RavenHandler.php', + 'Monolog\\Handler\\RedisHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RedisHandler.php', + 'Monolog\\Handler\\RollbarHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RollbarHandler.php', + 'Monolog\\Handler\\RotatingFileHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php', + 'Monolog\\Handler\\SamplingHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SamplingHandler.php', + 'Monolog\\Handler\\SlackHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SlackHandler.php', + 'Monolog\\Handler\\SocketHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SocketHandler.php', + 'Monolog\\Handler\\StreamHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/StreamHandler.php', + 'Monolog\\Handler\\SwiftMailerHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php', + 'Monolog\\Handler\\SyslogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogHandler.php', + 'Monolog\\Handler\\SyslogUdpHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php', + 'Monolog\\Handler\\SyslogUdp\\UdpSocket' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php', + 'Monolog\\Handler\\TestHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/TestHandler.php', + 'Monolog\\Handler\\WhatFailureGroupHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php', + 'Monolog\\Handler\\ZendMonitorHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php', + 'Monolog\\Logger' => $vendorDir . '/monolog/monolog/src/Monolog/Logger.php', + 'Monolog\\Processor\\GitProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/GitProcessor.php', + 'Monolog\\Processor\\IntrospectionProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php', + 'Monolog\\Processor\\MemoryPeakUsageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php', + 'Monolog\\Processor\\MemoryProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php', + 'Monolog\\Processor\\MemoryUsageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php', + 'Monolog\\Processor\\ProcessIdProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php', + 'Monolog\\Processor\\PsrLogMessageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php', + 'Monolog\\Processor\\TagProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/TagProcessor.php', + 'Monolog\\Processor\\UidProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/UidProcessor.php', + 'Monolog\\Processor\\WebProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/WebProcessor.php', + 'Monolog\\Registry' => $vendorDir . '/monolog/monolog/src/Monolog/Registry.php', + 'OOUI\\AccessKeyedElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/AccessKeyedElement.php', + 'OOUI\\ActionFieldLayout' => $vendorDir . '/oojs/oojs-ui/php/layouts/ActionFieldLayout.php', 'OOUI\\ApexTheme' => $vendorDir . '/oojs/oojs-ui/php/themes/ApexTheme.php', - 'OOUI\\ButtonElement' => $vendorDir . '/oojs/oojs-ui/php/elements/ButtonElement.php', + 'OOUI\\ButtonElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/ButtonElement.php', 'OOUI\\ButtonGroupWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/ButtonGroupWidget.php', 'OOUI\\ButtonInputWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/ButtonInputWidget.php', 'OOUI\\ButtonWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/ButtonWidget.php', @@ -44,42 +476,85 @@ return array( 'OOUI\\Exception' => $vendorDir . '/oojs/oojs-ui/php/Exception.php', 'OOUI\\FieldLayout' => $vendorDir . '/oojs/oojs-ui/php/layouts/FieldLayout.php', 'OOUI\\FieldsetLayout' => $vendorDir . '/oojs/oojs-ui/php/layouts/FieldsetLayout.php', - 'OOUI\\FlaggedElement' => $vendorDir . '/oojs/oojs-ui/php/elements/FlaggedElement.php', + 'OOUI\\FlaggedElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/FlaggedElement.php', 'OOUI\\FormLayout' => $vendorDir . '/oojs/oojs-ui/php/layouts/FormLayout.php', - 'OOUI\\GroupElement' => $vendorDir . '/oojs/oojs-ui/php/elements/GroupElement.php', + 'OOUI\\GroupElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/GroupElement.php', + 'OOUI\\HorizontalLayout' => $vendorDir . '/oojs/oojs-ui/php/layouts/HorizontalLayout.php', 'OOUI\\HtmlSnippet' => $vendorDir . '/oojs/oojs-ui/php/HtmlSnippet.php', - 'OOUI\\IconElement' => $vendorDir . '/oojs/oojs-ui/php/elements/IconElement.php', + 'OOUI\\IconElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/IconElement.php', 'OOUI\\IconWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/IconWidget.php', - 'OOUI\\IndicatorElement' => $vendorDir . '/oojs/oojs-ui/php/elements/IndicatorElement.php', + 'OOUI\\IndicatorElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/IndicatorElement.php', 'OOUI\\IndicatorWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/IndicatorWidget.php', 'OOUI\\InputWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/InputWidget.php', - 'OOUI\\LabelElement' => $vendorDir . '/oojs/oojs-ui/php/elements/LabelElement.php', + 'OOUI\\LabelElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/LabelElement.php', 'OOUI\\LabelWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/LabelWidget.php', 'OOUI\\Layout' => $vendorDir . '/oojs/oojs-ui/php/Layout.php', 'OOUI\\MediaWikiTheme' => $vendorDir . '/oojs/oojs-ui/php/themes/MediaWikiTheme.php', 'OOUI\\PanelLayout' => $vendorDir . '/oojs/oojs-ui/php/layouts/PanelLayout.php', 'OOUI\\RadioInputWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/RadioInputWidget.php', - 'OOUI\\TabIndexedElement' => $vendorDir . '/oojs/oojs-ui/php/elements/TabIndexedElement.php', + 'OOUI\\RadioSelectInputWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php', + 'OOUI\\TabIndexedElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/TabIndexedElement.php', 'OOUI\\Tag' => $vendorDir . '/oojs/oojs-ui/php/Tag.php', 'OOUI\\TextInputWidget' => $vendorDir . '/oojs/oojs-ui/php/widgets/TextInputWidget.php', 'OOUI\\Theme' => $vendorDir . '/oojs/oojs-ui/php/Theme.php', - 'OOUI\\TitledElement' => $vendorDir . '/oojs/oojs-ui/php/elements/TitledElement.php', + 'OOUI\\TitledElement' => $vendorDir . '/oojs/oojs-ui/php/mixins/TitledElement.php', 'OOUI\\Widget' => $vendorDir . '/oojs/oojs-ui/php/Widget.php', 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php', 'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php', - 'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php', 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', - 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', + 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/Exceptions/SignatureInvalidException.php', + 'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/process/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/process/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . '/symfony/process/Exception/LogicException.php', + 'Symfony\\Component\\Process\\Exception\\ProcessFailedException' => $vendorDir . '/symfony/process/Exception/ProcessFailedException.php', + 'Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => $vendorDir . '/symfony/process/Exception/ProcessTimedOutException.php', + 'Symfony\\Component\\Process\\Exception\\RuntimeException' => $vendorDir . '/symfony/process/Exception/RuntimeException.php', + 'Symfony\\Component\\Process\\ExecutableFinder' => $vendorDir . '/symfony/process/ExecutableFinder.php', + 'Symfony\\Component\\Process\\PhpExecutableFinder' => $vendorDir . '/symfony/process/PhpExecutableFinder.php', + 'Symfony\\Component\\Process\\PhpProcess' => $vendorDir . '/symfony/process/PhpProcess.php', + 'Symfony\\Component\\Process\\Pipes\\AbstractPipes' => $vendorDir . '/symfony/process/Pipes/AbstractPipes.php', + 'Symfony\\Component\\Process\\Pipes\\PipesInterface' => $vendorDir . '/symfony/process/Pipes/PipesInterface.php', + 'Symfony\\Component\\Process\\Pipes\\UnixPipes' => $vendorDir . '/symfony/process/Pipes/UnixPipes.php', + 'Symfony\\Component\\Process\\Pipes\\WindowsPipes' => $vendorDir . '/symfony/process/Pipes/WindowsPipes.php', + 'Symfony\\Component\\Process\\Process' => $vendorDir . '/symfony/process/Process.php', + 'Symfony\\Component\\Process\\ProcessBuilder' => $vendorDir . '/symfony/process/ProcessBuilder.php', + 'Symfony\\Component\\Process\\ProcessUtils' => $vendorDir . '/symfony/process/ProcessUtils.php', + 'Symfony\\Component\\Process\\Tests\\AbstractProcessTest' => $vendorDir . '/symfony/process/Tests/AbstractProcessTest.php', + 'Symfony\\Component\\Process\\Tests\\ExecutableFinderTest' => $vendorDir . '/symfony/process/Tests/ExecutableFinderTest.php', + 'Symfony\\Component\\Process\\Tests\\NonStringifiable' => $vendorDir . '/symfony/process/Tests/AbstractProcessTest.php', + 'Symfony\\Component\\Process\\Tests\\PhpExecutableFinderTest' => $vendorDir . '/symfony/process/Tests/PhpExecutableFinderTest.php', + 'Symfony\\Component\\Process\\Tests\\PhpProcessTest' => $vendorDir . '/symfony/process/Tests/PhpProcessTest.php', + 'Symfony\\Component\\Process\\Tests\\ProcessBuilderTest' => $vendorDir . '/symfony/process/Tests/ProcessBuilderTest.php', + 'Symfony\\Component\\Process\\Tests\\ProcessFailedExceptionTest' => $vendorDir . '/symfony/process/Tests/ProcessFailedExceptionTest.php', + 'Symfony\\Component\\Process\\Tests\\ProcessInSigchildEnvironment' => $vendorDir . '/symfony/process/Tests/ProcessInSigchildEnvironment.php', + 'Symfony\\Component\\Process\\Tests\\ProcessUtilsTest' => $vendorDir . '/symfony/process/Tests/ProcessUtilsTest.php', + 'Symfony\\Component\\Process\\Tests\\SigchildDisabledProcessTest' => $vendorDir . '/symfony/process/Tests/SigchildDisabledProcessTest.php', + 'Symfony\\Component\\Process\\Tests\\SigchildEnabledProcessTest' => $vendorDir . '/symfony/process/Tests/SigchildEnabledProcessTest.php', + 'Symfony\\Component\\Process\\Tests\\SimpleProcessTest' => $vendorDir . '/symfony/process/Tests/SimpleProcessTest.php', + 'Symfony\\Component\\Process\\Tests\\Stringifiable' => $vendorDir . '/symfony/process/Tests/AbstractProcessTest.php', 'UtfNormal\\Constants' => $vendorDir . '/wikimedia/utfnormal/src/Constants.php', 'UtfNormal\\Utils' => $vendorDir . '/wikimedia/utfnormal/src/Util.php', 'UtfNormal\\Validator' => $vendorDir . '/wikimedia/utfnormal/src/Validator.php', + 'Wikimedia\\Assert\\Assert' => $vendorDir . '/wikimedia/assert/src/Assert.php', + 'Wikimedia\\Assert\\AssertionException' => $vendorDir . '/wikimedia/assert/src/AssertionException.php', + 'Wikimedia\\Assert\\InvariantException' => $vendorDir . '/wikimedia/assert/src/InvariantException.php', + 'Wikimedia\\Assert\\ParameterAssertionException' => $vendorDir . '/wikimedia/assert/src/ParameterAssertionException.php', + 'Wikimedia\\Assert\\ParameterElementTypeException' => $vendorDir . '/wikimedia/assert/src/ParameterElementTypeException.php', + 'Wikimedia\\Assert\\ParameterTypeException' => $vendorDir . '/wikimedia/assert/src/ParameterTypeException.php', + 'Wikimedia\\Assert\\PostconditionException' => $vendorDir . '/wikimedia/assert/src/PostconditionException.php', + 'Wikimedia\\Assert\\PreconditionException' => $vendorDir . '/wikimedia/assert/src/PreconditionException.php', + 'Wikimedia\\Assert\\Test\\AssertTest' => $vendorDir . '/wikimedia/assert/tests/phpunit/AssertTest.php', + 'Wikimedia\\Composer\\Logger' => $vendorDir . '/wikimedia/composer-merge-plugin/src/Logger.php', 'Wikimedia\\Composer\\MergePlugin' => $vendorDir . '/wikimedia/composer-merge-plugin/src/MergePlugin.php', - 'lessc' => $vendorDir . '/leafo/lessphp/lessc.inc.php', - 'lessc_formatter_classic' => $vendorDir . '/leafo/lessphp/lessc.inc.php', - 'lessc_formatter_compressed' => $vendorDir . '/leafo/lessphp/lessc.inc.php', - 'lessc_formatter_lessjs' => $vendorDir . '/leafo/lessphp/lessc.inc.php', - 'lessc_parser' => $vendorDir . '/leafo/lessphp/lessc.inc.php', + 'Wikimedia\\Composer\\Merge\\ExtraPackage' => $vendorDir . '/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php', + 'Wikimedia\\Composer\\Merge\\MissingFileException' => $vendorDir . '/wikimedia/composer-merge-plugin/src/Merge/MissingFileException.php', + 'Wikimedia\\Composer\\Merge\\PluginState' => $vendorDir . '/wikimedia/composer-merge-plugin/src/Merge/PluginState.php', + 'Wikimedia\\Composer\\Merge\\StabilityFlags' => $vendorDir . '/wikimedia/composer-merge-plugin/src/Merge/StabilityFlags.php', + 'WrappedString\\WrappedString' => $vendorDir . '/wikimedia/wrappedstring/src/WrappedString.php', + 'lessc' => $vendorDir . '/oyejorge/less.php/lessc.inc.php', ); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 00000000..fba07a7c --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,10 @@ + array($vendorDir . '/psr/log'), 'Liuggio' => array($vendorDir . '/liuggio/statsd-php-client/src'), - 'ComposerHookHandler' => array($baseDir . '/includes/composer'), - '' => array($vendorDir . '/cssjanus/cssjanus/src'), + 'Less' => array($vendorDir . '/oyejorge/less.php/lib'), + 'Kafka\\' => array($vendorDir . '/nmred/kafka-php/src'), + '' => array($vendorDir . '/cssjanus/cssjanus/src', $vendorDir . '/kzykhys/pygments/src'), ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 74a09133..9bba7ec0 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -3,8 +3,15 @@ // autoload_psr4.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); -$baseDir = dirname($vendorDir); +$baseDir = $vendorDir; return array( + 'WrappedString\\' => array($vendorDir . '/wikimedia/wrappedstring/src'), 'Wikimedia\\Composer\\' => array($vendorDir . '/wikimedia/composer-merge-plugin/src'), + 'Wikimedia\\Assert\\Test\\' => array($vendorDir . '/wikimedia/assert/tests/phpunit'), + 'Wikimedia\\Assert\\' => array($vendorDir . '/wikimedia/assert/src'), + 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'), + 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), + 'Elastica\\' => array($vendorDir . '/ruflin/elastica/lib/Elastica'), + 'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 0c5b84c2..c98cf206 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInite2ef576e4023c6f0949f5e8e1cdf8649 +class ComposerAutoloaderInit_mediawiki_vendor { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInite2ef576e4023c6f0949f5e8e1cdf8649 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInite2ef576e4023c6f0949f5e8e1cdf8649', 'loadClassLoader'), true, false); + spl_autoload_register(array('ComposerAutoloaderInit_mediawiki_vendor', 'loadClassLoader'), true, false); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInite2ef576e4023c6f0949f5e8e1cdf8649', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit_mediawiki_vendor', 'loadClassLoader')); $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -38,13 +38,19 @@ class ComposerAutoloaderInite2ef576e4023c6f0949f5e8e1cdf8649 $loader->addClassMap($classMap); } + $loader->setClassMapAuthoritative(true); $loader->register(false); + $includeFiles = require __DIR__ . '/autoload_files.php'; + foreach ($includeFiles as $file) { + composerRequire_mediawiki_vendor($file); + } + return $loader; } } -function composerRequiree2ef576e4023c6f0949f5e8e1cdf8649($file) +function composerRequire_mediawiki_vendor($file) { require $file; } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index e882cda4..62c92430 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,46 +1,43 @@ [ { - "name": "wikimedia/composer-merge-plugin", - "version": "v1.0.0", + "name": "psr/log", + "version": "1.0.0", "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/wikimedia/composer-merge-plugin.git", - "reference": "ed426b785f9f786b33be4fd78584e43f4e962356" + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/ed426b785f9f786b33be4fd78584e43f4e962356", - "reference": "ed426b785f9f786b33be4fd78584e43f4e962356", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", "shasum": "" }, - "require": { - "composer-plugin-api": "1.0.0", - "php": ">=5.3.2" - }, - "require-dev": { - "composer/composer": "1.0.*@dev", - "jakub-onderka/php-parallel-lint": "~0.8", - "phpspec/prophecy-phpunit": "~1.0", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.1.0" - }, - "time": "2015-02-21 00:57:13", - "type": "composer-plugin", - "extra": { - "class": "Wikimedia\\Composer\\MergePlugin" - }, + "time": "2012-12-21 11:40:51", + "type": "library", "installation-source": "dist", "autoload": { - "psr-4": { - "Wikimedia\\Composer\\": "src/" + "psr-0": { + "Psr\\Log\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Composer plugin to merge multiple composer.json files" + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ] }, { "name": "cssjanus/cssjanus", @@ -80,65 +77,229 @@ "description": "Convert CSS stylesheets between left-to-right and right-to-left." }, { - "name": "leafo/lessphp", - "version": "v0.5.0", - "version_normalized": "0.5.0.0", + "name": "wikimedia/assert", + "version": "v0.2.2", + "version_normalized": "0.2.2.0", "source": { "type": "git", - "url": "https://github.com/leafo/lessphp.git", - "reference": "0f5a7f5545d2bcf4e9fad9a228c8ad89cc9aa283" + "url": "https://github.com/wmde/Assert.git", + "reference": "2da55927525975f8d52825fc3ee02e5e36f5036c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/leafo/lessphp/zipball/0f5a7f5545d2bcf4e9fad9a228c8ad89cc9aa283", - "reference": "0f5a7f5545d2bcf4e9fad9a228c8ad89cc9aa283", + "url": "https://api.github.com/repos/wmde/Assert/zipball/2da55927525975f8d52825fc3ee02e5e36f5036c", + "reference": "2da55927525975f8d52825fc3ee02e5e36f5036c", "shasum": "" }, - "time": "2014-11-24 18:39:20", + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "time": "2015-04-29 17:23:50", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.4.x-dev" + "installation-source": "dist", + "autoload": { + "psr-4": { + "Wikimedia\\Assert\\": "src/", + "Wikimedia\\Assert\\Test\\": "tests/phpunit/" } }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Kinzler" + } + ], + "description": "Provides runtime assertions", + "homepage": "https://github.com/wmde/Assert", + "keywords": [ + "assert", + "assertions", + "php", + "postcondition", + "precondition", + "qa" + ] + }, + { + "name": "zordius/lightncandy", + "version": "v0.21", + "version_normalized": "0.21.0.0", + "source": { + "type": "git", + "url": "https://github.com/zordius/lightncandy.git", + "reference": "015fed62d0ae6fe7601d3910b8e4b6a6964f86a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zordius/lightncandy/zipball/015fed62d0ae6fe7601d3910b8e4b6a6964f86a0", + "reference": "015fed62d0ae6fe7601d3910b8e4b6a6964f86a0", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.0.17" + }, + "time": "2015-05-08 01:56:46", + "type": "library", "installation-source": "dist", "autoload": { "classmap": [ - "lessc.inc.php" + "src/lightncandy.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT", - "GPL-3.0" + "MIT" + ], + "authors": [ + { + "name": "Zordius Chen", + "email": "zordius@yahoo-inc.com" + } + ], + "description": "An extremely fast PHP implementation of handlebars ( http://handlebarsjs.com/ ) and mustache ( http://mustache.github.io/ ).", + "homepage": "https://github.com/zordius/lightncandy", + "keywords": [ + "handlebars", + "logicless", + "mustache", + "php", + "template" + ] + }, + { + "name": "kzykhys/pygments", + "version": "v1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/kzykhys/Pygments.php.git", + "reference": "7bde970d3c378d075ef0e005bb93a91055e17994" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kzykhys/Pygments.php/zipball/7bde970d3c378d075ef0e005bb93a91055e17994", + "reference": "7bde970d3c378d075ef0e005bb93a91055e17994", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/process": ">=2.3" + }, + "require-dev": { + "symfony/finder": ">=2.3" + }, + "time": "2013-12-18 15:22:37", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "description": "A Thin Wrapper for the Python Pygments" + }, + { + "name": "monolog/monolog", + "version": "1.14.0", + "version_normalized": "1.14.0.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "b287fbbe1ca27847064beff2bad7fb6920bf08cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b287fbbe1ca27847064beff2bad7fb6920bf08cc", + "reference": "b287fbbe1ca27847064beff2bad7fb6920bf08cc", + "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", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "raven/raven": "~0.8", + "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-06-19 13:29:54", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.14.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" ], "authors": [ { - "name": "Leaf Corcoran", - "email": "leafot@gmail.com", - "homepage": "http://leafo.net" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" } ], - "description": "lessphp is a compiler for LESS written in PHP.", - "homepage": "http://leafo.net/lessphp/" + "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": "liuggio/statsd-php-client", - "version": "v1.0.12", - "version_normalized": "1.0.12.0", + "version": "v1.0.16", + "version_normalized": "1.0.16.0", "source": { "type": "git", "url": "https://github.com/liuggio/statsd-php-client.git", - "reference": "a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7" + "reference": "a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/liuggio/statsd-php-client/zipball/a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7", - "reference": "a8c9ccd2a3af6cc49c7fc4f5f689d7b148ab19d7", + "url": "https://api.github.com/repos/liuggio/statsd-php-client/zipball/a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920", + "reference": "a84fbef1a7afbfafd0ca4f1ebae4935bd1a7d920", "shasum": "" }, "require": { - "php": ">=5.2" + "php": ">=5.3.2" }, "require-dev": { "monolog/monolog": ">=1.2.0" @@ -146,7 +307,7 @@ "suggest": { "monolog/monolog": "Monolog, in order to do generate statistic from log >=1.2.0)" }, - "time": "2014-09-17 21:37:49", + "time": "2015-04-27 08:12:26", "type": "library", "installation-source": "dist", "autoload": { @@ -174,64 +335,89 @@ ] }, { - "name": "oojs/oojs-ui", - "version": "v0.11.3", - "version_normalized": "0.11.3.0", + "name": "wikimedia/wrappedstring", + "version": "v2.0.0", + "version_normalized": "2.0.0.0", "source": { "type": "git", - "url": "https://github.com/wikimedia/oojs-ui.git", - "reference": "a03de5681e28e4fad1e27f8cccab32a2c5b484e5" + "url": "https://github.com/wikimedia/WrappedString.git", + "reference": "1b27e0ea23bd915644dade17c3fe1e45fdbadf11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/oojs-ui/zipball/a03de5681e28e4fad1e27f8cccab32a2c5b484e5", - "reference": "a03de5681e28e4fad1e27f8cccab32a2c5b484e5", + "url": "https://api.github.com/repos/wikimedia/WrappedString/zipball/1b27e0ea23bd915644dade17c3fe1e45fdbadf11", + "reference": "1b27e0ea23bd915644dade17c3fe1e45fdbadf11", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "jakub-onderka/php-parallel-lint": "0.8.*", - "mediawiki/mediawiki-codesniffer": "0.1.0", - "squizlabs/php_codesniffer": "2.1.*" + "jakub-onderka/php-parallel-lint": "^0.9.0.0", + "mediawiki/mediawiki-codesniffer": "^0.3.0.0", + "phpunit/phpunit": "^4.7.7.0" }, - "time": "2015-05-12 11:58:55", + "time": "2015-07-31 00:06:22", "type": "library", "installation-source": "dist", "autoload": { - "classmap": [ - "php/" - ] + "psr-4": { + "WrappedString\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Provides library of common widgets, layouts, and windows.", - "homepage": "https://www.mediawiki.org/wiki/OOjs_UI" + "authors": [ + { + "name": "Timo Tijhof", + "email": "krinklemail@gmail.com" + } + ], + "description": "Automatically compact sequentially-outputted strings that share a common prefix / suffix pair.", + "homepage": "https://www.mediawiki.org/wiki/WrappedString" }, { - "name": "psr/log", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "ruflin/elastica", + "version": "2.2.0", + "version_normalized": "2.2.0.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + "url": "https://github.com/ruflin/Elastica.git", + "reference": "eb3a787259a6c50f87bce507ff24b124d91c4fe7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "url": "https://api.github.com/repos/ruflin/Elastica/zipball/eb3a787259a6c50f87bce507ff24b124d91c4fe7", + "reference": "eb3a787259a6c50f87bce507ff24b124d91c4fe7", "shasum": "" }, - "time": "2012-12-21 11:40:51", + "require": { + "php": ">=5.3.3", + "psr/log": "~1.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "5.3.*", + "munkie/elasticsearch-thrift-php": "1.4.*" + }, + "suggest": { + "egeloen/http-adapter": "Allow using httpadapter transport", + "guzzlehttp/guzzle": "Allow using guzzle 5.3.x as the http transport (Requires php 5.4)", + "monolog/monolog": "Logging request", + "munkie/elasticsearch-thrift-php": "Allow using thrift transport" + }, + "time": "2015-07-08 05:57:43", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "installation-source": "dist", "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Elastica\\": "lib/Elastica/" } }, "notification-url": "https://packagist.org/downloads/", @@ -240,155 +426,662 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Nicolas Ruflin", + "homepage": "http://ruflin.com/" } ], - "description": "Common interface for logging libraries", + "description": "Elasticsearch Client", + "homepage": "http://elastica.io/", "keywords": [ - "log", - "psr", - "psr-3" + "client", + "search" ] }, { - "name": "wikimedia/cdb", - "version": "1.0.1", - "version_normalized": "1.0.1.0", + "name": "symfony/process", + "version": "v2.7.3", + "version_normalized": "2.7.3.0", "source": { "type": "git", - "url": "https://github.com/wikimedia/cdb.git", - "reference": "3b7d5366c88eccf2517ebac57c59eb557c82f46c" + "url": "https://github.com/symfony/Process.git", + "reference": "48aeb0e48600321c272955132d7606ab0a49adb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/cdb/zipball/3b7d5366c88eccf2517ebac57c59eb557c82f46c", - "reference": "3b7d5366c88eccf2517ebac57c59eb557c82f46c", + "url": "https://api.github.com/repos/symfony/Process/zipball/48aeb0e48600321c272955132d7606ab0a49adb3", + "reference": "48aeb0e48600321c272955132d7606ab0a49adb3", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": ">=5.3.9" }, "require-dev": { - "phpunit/phpunit": "*" + "symfony/phpunit-bridge": "~2.7" }, - "time": "2014-12-08 19:26:44", + "time": "2015-07-01 11:25:50", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, "installation-source": "dist", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symfony\\Component\\Process\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0" + "MIT" ], "authors": [ { - "name": "Tim Starling", - "email": "tstarling@wikimedia.org" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Chad Horohoe", - "email": "chad@wikimedia.org" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Constant Database (CDB) wrapper library for PHP. Provides pure-PHP fallback when dba_* functions are absent.", - "homepage": "https://www.mediawiki.org/wiki/CDB" + "description": "Symfony Process Component", + "homepage": "https://symfony.com" }, { - "name": "wikimedia/utfnormal", - "version": "v1.0.2", - "version_normalized": "1.0.2.0", + "name": "firebase/php-jwt", + "version": "v2.1.0", + "version_normalized": "2.1.0.0", "source": { "type": "git", - "url": "https://github.com/wikimedia/utfnormal.git", - "reference": "bb892a53a76116ad0982445a849043687cb6e778" + "url": "https://github.com/firebase/php-jwt.git", + "reference": "fb219727e199dd80a72d5274ebb5c8b24d58dd9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/utfnormal/zipball/bb892a53a76116ad0982445a849043687cb6e778", - "reference": "bb892a53a76116ad0982445a849043687cb6e778", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/fb219727e199dd80a72d5274ebb5c8b24d58dd9b", + "reference": "fb219727e199dd80a72d5274ebb5c8b24d58dd9b", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "ext-mbstring": "*", - "jakub-onderka/php-parallel-lint": "0.8.*", - "mediawiki/mediawiki-codesniffer": "0.1.0", - "phpunit/phpunit": "4.4.*", - "squizlabs/php_codesniffer": "2.1.*" + "php": ">=5.2.0" }, - "time": "2015-03-12 01:54:47", + "time": "2015-05-20 19:16:04", "type": "library", "installation-source": "dist", "autoload": { "classmap": [ - "src/" + "Authentication/", + "Exceptions/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "BSD-3-Clause" ], "authors": [ { - "name": "Brion Vibber", - "email": "bvibber@wikimedia.org" + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" } ], - "homepage": "https://www.mediawiki.org/wiki/utfnormal" + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt" }, { - "name": "zordius/lightncandy", - "version": "v0.18", - "version_normalized": "0.18.0.0", + "name": "wikimedia/ip-set", + "version": "1.0.1", + "version_normalized": "1.0.1.0", "source": { "type": "git", - "url": "https://github.com/zordius/lightncandy.git", - "reference": "24be6909c37391f4648ce1fdf19036b11bd56d05" + "url": "https://github.com/wikimedia/IPSet.git", + "reference": "3c2dd6706546fe616e6ceba02044e64dce4fc9be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zordius/lightncandy/zipball/24be6909c37391f4648ce1fdf19036b11bd56d05", - "reference": "24be6909c37391f4648ce1fdf19036b11bd56d05", + "url": "https://api.github.com/repos/wikimedia/IPSet/zipball/3c2dd6706546fe616e6ceba02044e64dce4fc9be", + "reference": "3c2dd6706546fe616e6ceba02044e64dce4fc9be", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "4.0.17" + "jakub-onderka/php-parallel-lint": "0.9", + "mediawiki/mediawiki-codesniffer": "0.3.0", + "phpunit/phpunit": "4.6.*" }, - "time": "2015-01-01 04:37:19", + "time": "2015-06-29 20:21:27", "type": "library", "installation-source": "dist", "autoload": { "classmap": [ - "src/lightncandy.php" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Zordius Chen", - "email": "zordius@yahoo-inc.com" + "name": "Brandon Black", + "email": "blblack@gmail.com" } ], - "description": "An extremely fast PHP implementation of handlebars ( http://handlebarsjs.com/ ) and mustache ( http://mustache.github.io/ ).", - "homepage": "https://github.com/zordius/lightncandy", - "keywords": [ - "handlebars", - "logicless", - "mustache", - "php", - "template" - ] + "description": "Efficiently match IP addresses against a set of CIDR specifications.", + "homepage": "https://github.com/wikimedia/IPSet" + }, + { + "name": "wikimedia/utfnormal", + "version": "v1.0.3", + "version_normalized": "1.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/utfnormal.git", + "reference": "bcb81d1d87bae400af45cc419a850dcf9883775b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/utfnormal/zipball/bcb81d1d87bae400af45cc419a850dcf9883775b", + "reference": "bcb81d1d87bae400af45cc419a850dcf9883775b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "ext-mbstring": "*", + "jakub-onderka/php-parallel-lint": "0.8.*", + "mediawiki/mediawiki-codesniffer": "0.1.0", + "phpunit/phpunit": "4.6.*", + "squizlabs/php_codesniffer": "2.2.*" + }, + "time": "2015-08-29 14:13:27", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Brion Vibber", + "email": "bvibber@wikimedia.org" + } + ], + "description": "Contains Unicode normalization routines, including both pure PHP implementations and automatic use of the 'intl' PHP extension when present", + "homepage": "https://www.mediawiki.org/wiki/utfnormal" + }, + { + "name": "wikimedia/cdb", + "version": "1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/cdb.git", + "reference": "68f8fd495ca94ca0e965dd511e234893c515bb95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/cdb/zipball/68f8fd495ca94ca0e965dd511e234893c515bb95", + "reference": "68f8fd495ca94ca0e965dd511e234893c515bb95", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9", + "mediawiki/mediawiki-codesniffer": "0.3.0", + "phpunit/phpunit": "4.6.*" + }, + "time": "2015-09-08 19:53:04", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Tim Starling", + "email": "tstarling@wikimedia.org" + }, + { + "name": "Chad Horohoe", + "email": "chad@wikimedia.org" + }, + { + "name": "Ori Livneh", + "email": "ori@wikimedia.org" + } + ], + "description": "Constant Database (CDB) wrapper library for PHP. Provides pure-PHP fallback when dba_* functions are absent.", + "homepage": "https://www.mediawiki.org/wiki/CDB" + }, + { + "name": "nmred/kafka-php", + "version": "v0.1.4", + "version_normalized": "0.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/nmred/kafka-php.git", + "reference": "06817c95e40b23918c3a420960ee9526e499275d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nmred/kafka-php/zipball/06817c95e40b23918c3a420960ee9526e499275d", + "reference": "06817c95e40b23918c3a420960ee9526e499275d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpcov": "*", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "dev-master" + }, + "time": "2015-09-06 01:39:05", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Kafka\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Kafka client for php", + "homepage": "http://www.swanlinux.net", + "keywords": [ + "client", + "kafka" + ] + }, + { + "name": "wikimedia/avro", + "version": "v1.7.7", + "version_normalized": "1.7.7.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/avro-php.git", + "reference": "b642da9fd895aab7cb3261a22624228115471f47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/avro-php/zipball/b642da9fd895aab7cb3261a22624228115471f47", + "reference": "b642da9fd895aab7cb3261a22624228115471f47", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9", + "phpunit/phpunit": "^4.0.0" + }, + "suggest": { + "ext-gmp": "Large integer support for 32-bit platforms." + }, + "time": "2015-09-05 18:49:27", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Michael Glaesemann", + "email": "grzm@seespotcode.net" + }, + { + "name": "Andy Wick", + "email": "awick@purple.org" + }, + { + "name": "Saleem Shafi", + "email": "saleemshafi@gmail.com" + }, + { + "name": "A B", + "email": "abawany@x.com" + }, + { + "name": "Doug Cutting", + "email": "cutting@apache.org" + }, + { + "name": "Tom White", + "email": "tom@cloudera.com" + } + ], + "description": "A library for using Apache Avro with PHP.", + "homepage": "https://avro.apache.org/", + "keywords": [ + "serialization" + ] + }, + { + "name": "mediawiki/at-ease", + "version": "v1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/at-ease.git", + "reference": "94c0b84888841d160419f915c2745d9d08fbf0c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/at-ease/zipball/94c0b84888841d160419f915c2745d9d08fbf0c3", + "reference": "94c0b84888841d160419f915c2745d9d08fbf0c3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9", + "mediawiki/mediawiki-codesniffer": "0.3.0", + "phpunit/phpunit": "~4.5", + "squizlabs/php_codesniffer": "2.3.0" + }, + "time": "2015-09-18 07:02:06", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/Functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Tim Starling", + "email": "tstarling@wikimedia.org" + }, + { + "name": "MediaWiki developers", + "email": "wikitech-l@lists.wikimedia.org" + } + ], + "description": "Safe replacement to @ for suppressing warnings.", + "homepage": "https://www.mediawiki.org/wiki/at-ease" + }, + { + "name": "oyejorge/less.php", + "version": "v1.7.0.9", + "version_normalized": "1.7.0.9", + "source": { + "type": "git", + "url": "https://github.com/oyejorge/less.php.git", + "reference": "fb64e2f6ef647a229c50e9fa0f2076240a3484c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/oyejorge/less.php/zipball/fb64e2f6ef647a229c50e9fa0f2076240a3484c6", + "reference": "fb64e2f6ef647a229c50e9fa0f2076240a3484c6", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "time": "2015-09-28 01:11:47", + "bin": [ + "bin/lessc" + ], + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Less": "lib/" + }, + "classmap": [ + "lessc.inc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Matt Agar", + "homepage": "https://github.com/agar" + }, + { + "name": "Martin Jantošovič", + "homepage": "https://github.com/Mordred" + }, + { + "name": "Josh Schmidt", + "homepage": "https://github.com/oyejorge" + } + ], + "description": "PHP port of the Javascript version of LESS http://lesscss.org", + "homepage": "http://lessphp.gpeasy.com", + "keywords": [ + "css", + "less", + "less.js", + "lesscss", + "php", + "stylesheet" + ] + }, + { + "name": "composer/semver", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "time": "2015-09-21 09:42:36", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com" + }, + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ] + }, + { + "name": "oojs/oojs-ui", + "version": "v0.12.12", + "version_normalized": "0.12.12.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/oojs-ui.git", + "reference": "221a66e8df215e767ff4b55b637138a73fcffdb2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/oojs-ui/zipball/221a66e8df215e767ff4b55b637138a73fcffdb2", + "reference": "221a66e8df215e767ff4b55b637138a73fcffdb2", + "shasum": "" + }, + "require": { + "mediawiki/at-ease": "1.1.0", + "php": ">=5.3.3" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9", + "mediawiki/mediawiki-codesniffer": "0.4.0", + "phpunit/phpunit": "~4.5" + }, + "time": "2015-10-13 20:29:29", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "php/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bartosz Dziewoński", + "email": "matma.rex@gmail.com" + }, + { + "name": "Ed Sanders", + "email": "esanders@wikimedia.org" + }, + { + "name": "James D. Forrester", + "email": "jforrester@wikimedia.org" + }, + { + "name": "Kirsten Menger-Anderson", + "email": "kmenger@wikimedia.org" + }, + { + "name": "Rob Moen", + "email": "rmoen@wikimedia.org" + }, + { + "name": "Roan Kattouw", + "email": "roan@wikimedia.org" + }, + { + "name": "Timo Tijhof", + "email": "timo@wikimedia.org" + }, + { + "name": "Trevor Parscal", + "email": "trevor@wikimedia.org" + } + ], + "description": "Provides library of common widgets, layouts, and windows.", + "homepage": "https://www.mediawiki.org/wiki/OOjs_UI" + }, + { + "name": "wikimedia/composer-merge-plugin", + "version": "v1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/composer-merge-plugin.git", + "reference": "bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9", + "reference": "bfed1f8d4eb97e9ba80eee57ea46229d7e5364d9", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": ">=5.3.2" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "jakub-onderka/php-parallel-lint": "~0.8", + "phpunit/phpunit": "~4.8|~5.0", + "squizlabs/php_codesniffer": "~2.1.0" + }, + "time": "2015-11-06 20:31:16", + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + }, + "class": "Wikimedia\\Composer\\MergePlugin" + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Wikimedia\\Composer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bryan Davis", + "email": "bd808@wikimedia.org" + } + ], + "description": "Composer plugin to merge multiple composer.json files" } ] diff --git a/vendor/composer/semver/CHANGELOG.md b/vendor/composer/semver/CHANGELOG.md new file mode 100644 index 00000000..8352cb72 --- /dev/null +++ b/vendor/composer/semver/CHANGELOG.md @@ -0,0 +1,28 @@ +# Change Log + +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). + +### [1.0.0] 2015-09-21 + + * Break: `VersionConstraint` renamed to `Constraint`. + * Break: `SpecificConstraint` renamed to `AbstractConstraint`. + * Break: `LinkConstraintInterface` renamed to `ConstraintInterface`. + * Break: `VersionParser::parseNameVersionPairs` was removed. + * Changed: `VersionParser::parseConstraints` allows (but ignores) build metadata now. + * Changed: `VersionParser::parseConstraints` allows (but ignores) prefixing numeric versions with a 'v' now. + * Changed: Fixed namespace(s) of test files. + * Changed: `Comparator::compare` no longer throws `InvalidArgumentException`. + * Changed: `VersionConstraint` now throws `InvalidArgumentException`. + +### [0.1.0] 2015-07-23 + + * Added: `Composer\Semver\Comparator`, various methods to compare versions. + * Added: various documents such as README.md, LICENSE, etc. + * Added: configuration files for Git, Travis, php-cs-fixer, phpunit. + * Break: the following namespaces were renamed: + - Namespace: `Composer\Package\Version` -> `Composer\Semver` + - Namespace: `Composer\Package\LinkConstraint` -> `Composer\Semver\Constraint` + - Namespace: `Composer\Test\Package\Version` -> `Composer\Test\Semver` + - Namespace: `Composer\Test\Package\LinkConstraint` -> `Composer\Test\Semver\Constraint` + * Changed: code style using php-cs-fixer. diff --git a/vendor/composer/semver/LICENSE b/vendor/composer/semver/LICENSE new file mode 100644 index 00000000..46697586 --- /dev/null +++ b/vendor/composer/semver/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2015 Composer + +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/semver/README.md b/vendor/composer/semver/README.md new file mode 100644 index 00000000..c8b69798 --- /dev/null +++ b/vendor/composer/semver/README.md @@ -0,0 +1,70 @@ +composer/semver +=============== + +Semver library that offers utilities, version constraint parsing and validation. + +Originally written as part of [composer/composer](https://github.com/composer/composer), +now extracted and made available as a stand-alone library. + +[![Build Status](https://travis-ci.org/composer/semver.svg?branch=master)](https://travis-ci.org/composer/semver) + + +Installation +------------ + +Install the latest version with: + +```bash +$ composer require composer/semver +``` + + +Requirements +------------ + +* PHP 5.3.2 is required but using the latest version of PHP is highly recommended. + + +Version Comparison +------------------ + +For details on how versions are compared, refer to the [Versions](https://getcomposer.org/doc/articles/versions.md) +article in the documentation section of the [getcomposer.org](https://getcomposer.org) website. + + +Basic usage +----------- + +### Comparator + +The `Composer\Semver\Comparator` class provides the following methods for comparing versions: + +* greaterThan($v1, $v2) +* greaterThanOrEqualTo($v1, $v2) +* lessThan($v1, $v2) +* lessThanOrEqualTo($v1, $v2) +* equalTo($v1, $v2) +* notEqualTo($v1, $v2) + +Each function takes two version strings as arguments. For example: + +```php +use Composer\Semver\Comparator; + +Comparator::greaterThan('1.25.0', '1.24.0'); // 1.25.0 > 1.24.0 +``` + +### Semver + +The `Composer\Semver\Semver` class providers the following methods: + +* satisfies($version, $constraints) +* satisfiedBy($constraint, array $versions) +* sort($versions) +* rsort($versions) + + +License +------- + +composer/semver is licensed under the MIT License, see the LICENSE file for details. diff --git a/vendor/composer/semver/composer.json b/vendor/composer/semver/composer.json new file mode 100644 index 00000000..b996186f --- /dev/null +++ b/vendor/composer/semver/composer.json @@ -0,0 +1,57 @@ +{ + "name": "composer/semver", + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "type": "library", + "license": "MIT", + "keywords": [ + "semver", + "semantic", + "versioning", + "validation" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com" + } + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Composer\\Semver\\Test\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "scripts": { + "test": "phpunit" + } +} diff --git a/vendor/composer/semver/src/Comparator.php b/vendor/composer/semver/src/Comparator.php new file mode 100644 index 00000000..a9d758f1 --- /dev/null +++ b/vendor/composer/semver/src/Comparator.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 Composer\Semver; + +use Composer\Semver\Constraint\Constraint; + +class Comparator +{ + /** + * Evaluates the expression: $version1 > $version2. + * + * @param string $version1 + * @param string $version2 + * + * @return bool + */ + public static function greaterThan($version1, $version2) + { + return self::compare($version1, '>', $version2); + } + + /** + * Evaluates the expression: $version1 >= $version2. + * + * @param string $version1 + * @param string $version2 + * + * @return bool + */ + public static function greaterThanOrEqualTo($version1, $version2) + { + return self::compare($version1, '>=', $version2); + } + + /** + * Evaluates the expression: $version1 < $version2. + * + * @param string $version1 + * @param string $version2 + * + * @return bool + */ + public static function lessThan($version1, $version2) + { + return self::compare($version1, '<', $version2); + } + + /** + * Evaluates the expression: $version1 <= $version2. + * + * @param string $version1 + * @param string $version2 + * + * @return bool + */ + public static function lessThanOrEqualTo($version1, $version2) + { + return self::compare($version1, '<=', $version2); + } + + /** + * Evaluates the expression: $version1 == $version2. + * + * @param string $version1 + * @param string $version2 + * + * @return bool + */ + public static function equalTo($version1, $version2) + { + return self::compare($version1, '==', $version2); + } + + /** + * Evaluates the expression: $version1 != $version2. + * + * @param string $version1 + * @param string $version2 + * + * @return bool + */ + public static function notEqualTo($version1, $version2) + { + return self::compare($version1, '!=', $version2); + } + + /** + * Evaluates the expression: $version1 $operator $version2. + * + * @param string $version1 + * @param string $operator + * @param string $version2 + * + * @return bool + */ + public static function compare($version1, $operator, $version2) + { + $constraint = new Constraint($operator, $version2); + + return $constraint->matches(new Constraint('==', $version1)); + } +} diff --git a/vendor/composer/semver/src/Constraint/AbstractConstraint.php b/vendor/composer/semver/src/Constraint/AbstractConstraint.php new file mode 100644 index 00000000..ccd834f6 --- /dev/null +++ b/vendor/composer/semver/src/Constraint/AbstractConstraint.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 Composer\Semver\Constraint; + +/** + * Base constraint class. + */ +abstract class AbstractConstraint implements ConstraintInterface +{ + /** @var string */ + protected $prettyString; + + /** + * @param ConstraintInterface $provider + * + * @return bool + */ + public function matches(ConstraintInterface $provider) + { + if ($provider instanceof MultiConstraint) { + // turn matching around to find a match + return $provider->matches($this); + } + + if ($provider instanceof $this) { + // see note at bottom of this class declaration + return $this->matchSpecific($provider); + } + + return true; + } + + /** + * @param string $prettyString + */ + public function setPrettyString($prettyString) + { + $this->prettyString = $prettyString; + } + + /** + * @return string + */ + public function getPrettyString() + { + if ($this->prettyString) { + return $this->prettyString; + } + + return $this->__toString(); + } + + // implementations must implement a method of this format: + // not declared abstract here because type hinting violates parameter coherence (TODO right word?) + // public function matchSpecific( $provider); +} diff --git a/vendor/composer/semver/src/Constraint/Constraint.php b/vendor/composer/semver/src/Constraint/Constraint.php new file mode 100644 index 00000000..8bc68db7 --- /dev/null +++ b/vendor/composer/semver/src/Constraint/Constraint.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\Semver\Constraint; + +/** + * Defines a constraint. + */ +class Constraint extends AbstractConstraint +{ + /* operator integer values */ + const OP_EQ = 0; + const OP_LT = 1; + const OP_LE = 2; + const OP_GT = 3; + const OP_GE = 4; + const OP_NE = 5; + + /** + * Operator to integer translation table. + * + * @var array + */ + private static $transOpStr = array( + '=' => self::OP_EQ, + '==' => self::OP_EQ, + '<' => self::OP_LT, + '<=' => self::OP_LE, + '>' => self::OP_GT, + '>=' => self::OP_GE, + '<>' => self::OP_NE, + '!=' => self::OP_NE, + ); + + /** + * Integer to operator translation table. + * + * @var array + */ + private static $transOpInt = array( + self::OP_EQ => '==', + self::OP_LT => '<', + self::OP_LE => '<=', + self::OP_GT => '>', + self::OP_GE => '>=', + self::OP_NE => '!=', + ); + + /** @var string */ + private $operator; + + /** @var string */ + private $version; + + /** + * Get all supported comparison operators. + * + * @return array + */ + public static function getSupportedOperators() + { + return array_keys(self::$transOpStr); + } + + /** + * Sets operator and version to compare with. + * + * @param string $operator + * @param string $version + * + * @throws \InvalidArgumentException if invalid operator is given. + */ + public function __construct($operator, $version) + { + if (!isset(self::$transOpStr[$operator])) { + throw new \InvalidArgumentException(sprintf( + 'Invalid operator "%s" given, expected one of: %s', + $operator, + implode(', ', self::getSupportedOperators()) + )); + } + + $this->operator = self::$transOpStr[$operator]; + $this->version = $version; + } + + /** + * @param string $a + * @param string $b + * @param string $operator + * @param bool $compareBranches + * + * @throws \InvalidArgumentException if invalid operator is given. + * + * @return bool + */ + public function versionCompare($a, $b, $operator, $compareBranches = false) + { + if (!isset(self::$transOpStr[$operator])) { + throw new \InvalidArgumentException(sprintf( + 'Invalid operator "%s" given, expected one of: %s', + $operator, + implode(', ', self::getSupportedOperators()) + )); + } + + $aIsBranch = 'dev-' === substr($a, 0, 4); + $bIsBranch = 'dev-' === substr($b, 0, 4); + + if ($aIsBranch && $bIsBranch) { + return $operator === '==' && $a === $b; + } + + // when branches are not comparable, we make sure dev branches never match anything + if (!$compareBranches && ($aIsBranch || $bIsBranch)) { + return false; + } + + return version_compare($a, $b, $operator); + } + + /** + * @param Constraint $provider + * @param bool $compareBranches + * + * @return bool + */ + public function matchSpecific(Constraint $provider, $compareBranches = false) + { + $noEqualOp = str_replace('=', '', self::$transOpInt[$this->operator]); + $providerNoEqualOp = str_replace('=', '', self::$transOpInt[$provider->operator]); + + $isEqualOp = self::OP_EQ === $this->operator; + $isNonEqualOp = self::OP_NE === $this->operator; + $isProviderEqualOp = self::OP_EQ === $provider->operator; + $isProviderNonEqualOp = self::OP_NE === $provider->operator; + + // '!=' operator is match when other operator is not '==' operator or version is not match + // these kinds of comparisons always have a solution + if ($isNonEqualOp || $isProviderNonEqualOp) { + return !$isEqualOp && !$isProviderEqualOp + || $this->versionCompare($provider->version, $this->version, '!=', $compareBranches); + } + + // an example for the condition is <= 2.0 & < 1.0 + // these kinds of comparisons always have a solution + if ($this->operator !== self::OP_EQ && $noEqualOp === $providerNoEqualOp) { + return true; + } + + if ($this->versionCompare($provider->version, $this->version, self::$transOpInt[$this->operator], $compareBranches)) { + // special case, e.g. require >= 1.0 and provide < 1.0 + // 1.0 >= 1.0 but 1.0 is outside of the provided interval + if ($provider->version === $this->version + && self::$transOpInt[$provider->operator] === $providerNoEqualOp + && self::$transOpInt[$this->operator] !== $noEqualOp) { + return false; + } + + return true; + } + + return false; + } + + /** + * @return string + */ + public function __toString() + { + return self::$transOpInt[$this->operator] . ' ' . $this->version; + } +} diff --git a/vendor/composer/semver/src/Constraint/ConstraintInterface.php b/vendor/composer/semver/src/Constraint/ConstraintInterface.php new file mode 100644 index 00000000..78c099ce --- /dev/null +++ b/vendor/composer/semver/src/Constraint/ConstraintInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\Semver\Constraint; + +interface ConstraintInterface +{ + /** + * @param ConstraintInterface $provider + * + * @return bool + */ + public function matches(ConstraintInterface $provider); + + /** + * @param string $prettyString + */ + public function setPrettyString($prettyString); + + /** + * @return string + */ + public function getPrettyString(); + + /** + * @return string + */ + public function __toString(); +} diff --git a/vendor/composer/semver/src/Constraint/EmptyConstraint.php b/vendor/composer/semver/src/Constraint/EmptyConstraint.php new file mode 100644 index 00000000..faba56bf --- /dev/null +++ b/vendor/composer/semver/src/Constraint/EmptyConstraint.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 Composer\Semver\Constraint; + +/** + * Defines the absence of a constraint. + */ +class EmptyConstraint implements ConstraintInterface +{ + /** @var string */ + protected $prettyString; + + /** + * @param ConstraintInterface $provider + * + * @return bool + */ + public function matches(ConstraintInterface $provider) + { + return true; + } + + /** + * @param $prettyString + */ + public function setPrettyString($prettyString) + { + $this->prettyString = $prettyString; + } + + /** + * @return string + */ + public function getPrettyString() + { + if ($this->prettyString) { + return $this->prettyString; + } + + return $this->__toString(); + } + + /** + * @return string + */ + public function __toString() + { + return '[]'; + } +} diff --git a/vendor/composer/semver/src/Constraint/MultiConstraint.php b/vendor/composer/semver/src/Constraint/MultiConstraint.php new file mode 100644 index 00000000..0d769b7c --- /dev/null +++ b/vendor/composer/semver/src/Constraint/MultiConstraint.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 Composer\Semver\Constraint; + +/** + * Defines a conjunctive or disjunctive set of constraints. + */ +class MultiConstraint implements ConstraintInterface +{ + /** @var ConstraintInterface[] */ + protected $constraints; + + /** @var string */ + protected $prettyString; + + /** @var bool */ + protected $conjunctive; + + /** + * @param ConstraintInterface[] $constraints A set of constraints + * @param bool $conjunctive Whether the constraints should be treated as conjunctive or disjunctive + */ + public function __construct(array $constraints, $conjunctive = true) + { + $this->constraints = $constraints; + $this->conjunctive = $conjunctive; + } + + /** + * @param ConstraintInterface $provider + * + * @return bool + */ + public function matches(ConstraintInterface $provider) + { + if (false === $this->conjunctive) { + foreach ($this->constraints as $constraint) { + if ($constraint->matches($provider)) { + return true; + } + } + + return false; + } + + foreach ($this->constraints as $constraint) { + if (!$constraint->matches($provider)) { + return false; + } + } + + return true; + } + + /** + * @param string $prettyString + */ + public function setPrettyString($prettyString) + { + $this->prettyString = $prettyString; + } + + /** + * @return string + */ + public function getPrettyString() + { + if ($this->prettyString) { + return $this->prettyString; + } + + return $this->__toString(); + } + + /** + * @return string + */ + public function __toString() + { + $constraints = array(); + foreach ($this->constraints as $constraint) { + $constraints[] = (string) $constraint; + } + + return '[' . implode($this->conjunctive ? ' ' : ' || ', $constraints) . ']'; + } +} diff --git a/vendor/composer/semver/src/Semver.php b/vendor/composer/semver/src/Semver.php new file mode 100644 index 00000000..0225bb55 --- /dev/null +++ b/vendor/composer/semver/src/Semver.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 Composer\Semver; + +use Composer\Semver\Constraint\Constraint; + +class Semver +{ + const SORT_ASC = 1; + const SORT_DESC = -1; + + /** @var VersionParser */ + private static $versionParser; + + /** + * Determine if given version satisfies given constraints. + * + * @param string $version + * @param string $constraints + * + * @return bool + */ + public static function satisfies($version, $constraints) + { + if (null === self::$versionParser) { + self::$versionParser = new VersionParser(); + } + + $versionParser = self::$versionParser; + $provider = new Constraint('==', $versionParser->normalize($version)); + $constraints = $versionParser->parseConstraints($constraints); + + return $constraints->matches($provider); + } + + /** + * Return all versions that satisfy given constraints. + * + * @param array $versions + * @param string $constraints + * + * @return array + */ + public static function satisfiedBy(array $versions, $constraints) + { + $versions = array_filter($versions, function ($version) use ($constraints) { + return Semver::satisfies($version, $constraints); + }); + + return array_values($versions); + } + + /** + * Sort given array of versions. + * + * @param array $versions + * + * @return array + */ + public static function sort(array $versions) + { + return self::usort($versions, self::SORT_ASC); + } + + /** + * Sort given array of versions in reverse. + * + * @param array $versions + * + * @return array + */ + public static function rsort(array $versions) + { + return self::usort($versions, self::SORT_DESC); + } + + /** + * @param array $versions + * @param int $direction + * + * @return array + */ + private static function usort(array $versions, $direction) + { + if (null === self::$versionParser) { + self::$versionParser = new VersionParser(); + } + + $versionParser = self::$versionParser; + $normalized = array(); + + // Normalize outside of usort() scope for minor performance increase. + // Creates an array of arrays: [[normalized, key], ...] + foreach ($versions as $key => $version) { + $normalized[] = array($versionParser->normalize($version), $key); + } + + usort($normalized, function (array $left, array $right) use ($direction) { + if ($left[0] === $right[0]) { + return 0; + } + + if (Comparator::lessThan($left[0], $right[0])) { + return -$direction; + } + + return $direction; + }); + + // Recreate input array, using the original indexes which are now in sorted order. + $sorted = array(); + foreach ($normalized as $item) { + $sorted[] = $versions[$item[1]]; + } + + return $sorted; + } +} diff --git a/vendor/composer/semver/src/VersionParser.php b/vendor/composer/semver/src/VersionParser.php new file mode 100644 index 00000000..269aee94 --- /dev/null +++ b/vendor/composer/semver/src/VersionParser.php @@ -0,0 +1,520 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\Semver; + +use Composer\Semver\Constraint\ConstraintInterface; +use Composer\Semver\Constraint\EmptyConstraint; +use Composer\Semver\Constraint\MultiConstraint; +use Composer\Semver\Constraint\Constraint; + +/** + * Version parser. + * + * @author Jordi Boggiano + */ +class VersionParser +{ + /** @var string */ + private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)(?:[.-]?(\d+))?)?([.-]?dev)?'; + + /** @var array */ + private static $stabilities = array( + 'stable', 'RC', 'beta', 'alpha', 'dev', + ); + + /** + * Returns the stability of a version. + * + * @param string $version + * + * @return string + */ + public static function parseStability($version) + { + $version = preg_replace('{#.+$}i', '', $version); + + if ('dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4)) { + return 'dev'; + } + + preg_match('{' . self::$modifierRegex . '$}i', strtolower($version), $match); + if (!empty($match[3])) { + return 'dev'; + } + + if (!empty($match[1])) { + if ('beta' === $match[1] || 'b' === $match[1]) { + return 'beta'; + } + if ('alpha' === $match[1] || 'a' === $match[1]) { + return 'alpha'; + } + if ('rc' === $match[1]) { + return 'RC'; + } + } + + return 'stable'; + } + + /** + * @param string $stability + * + * @return string + */ + public static function normalizeStability($stability) + { + $stability = strtolower($stability); + + return $stability === 'rc' ? 'RC' : $stability; + } + + /** + * Normalizes a version string to be able to perform comparisons on it. + * + * @param string $version + * @param string $fullVersion optional complete version string to give more context + * + * @throws \UnexpectedValueException + * + * @return string + */ + public function normalize($version, $fullVersion = null) + { + $version = trim($version); + if (null === $fullVersion) { + $fullVersion = $version; + } + + // strip off aliasing + if (preg_match('{^([^,\s]+) +as +([^,\s]+)$}', $version, $match)) { + $version = $match[1]; + } + + // strip off build metadata + if (preg_match('{^([^,\s+]+)\+[^\s]+$}', $version, $match)) { + $version = $match[1]; + } + + // match master-like branches + if (preg_match('{^(?:dev-)?(?:master|trunk|default)$}i', $version)) { + return '9999999-dev'; + } + + if ('dev-' === strtolower(substr($version, 0, 4))) { + return 'dev-' . substr($version, 4); + } + + // match classical versioning + if (preg_match('{^v?(\d{1,5})(\.\d+)?(\.\d+)?(\.\d+)?' . self::$modifierRegex . '$}i', $version, $matches)) { + $version = $matches[1] + . (!empty($matches[2]) ? $matches[2] : '.0') + . (!empty($matches[3]) ? $matches[3] : '.0') + . (!empty($matches[4]) ? $matches[4] : '.0'); + $index = 5; + // match date(time) based versioning + } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) { + $version = preg_replace('{\D}', '-', $matches[1]); + $index = 2; + } + + // add version modifiers if a version was matched + if (isset($index)) { + if (!empty($matches[$index])) { + if ('stable' === $matches[$index]) { + return $version; + } + $version .= '-' . $this->expandStability($matches[$index]) . (!empty($matches[$index + 1]) ? $matches[$index + 1] : ''); + } + + if (!empty($matches[$index + 2])) { + $version .= '-dev'; + } + + return $version; + } + + // match dev branches + if (preg_match('{(.*?)[.-]?dev$}i', $version, $match)) { + try { + return $this->normalizeBranch($match[1]); + } catch (\Exception $e) { + } + } + + $extraMessage = ''; + if (preg_match('{ +as +' . preg_quote($version) . '$}', $fullVersion)) { + $extraMessage = ' in "' . $fullVersion . '", the alias must be an exact version'; + } elseif (preg_match('{^' . preg_quote($version) . ' +as +}', $fullVersion)) { + $extraMessage = ' in "' . $fullVersion . '", the alias source must be an exact version, if it is a branch name you should prefix it with dev-'; + } + + throw new \UnexpectedValueException('Invalid version string "' . $version . '"' . $extraMessage); + } + + /** + * Extract numeric prefix from alias, if it is in numeric format, suitable for version comparison. + * + * @param string $branch Branch name (e.g. 2.1.x-dev) + * + * @return string|false Numeric prefix if present (e.g. 2.1.) or false + */ + public function parseNumericAliasPrefix($branch) + { + if (preg_match('{^(?P(\d+\\.)*\d+)(?:\.x)?-dev$}i', $branch, $matches)) { + return $matches['version'] . '.'; + } + + return false; + } + + /** + * Normalizes a branch name to be able to perform comparisons on it. + * + * @param string $name + * + * @return string + */ + public function normalizeBranch($name) + { + $name = trim($name); + + if (in_array($name, array('master', 'trunk', 'default'))) { + return $this->normalize($name); + } + + if (preg_match('{^v?(\d+)(\.(?:\d+|[xX*]))?(\.(?:\d+|[xX*]))?(\.(?:\d+|[xX*]))?$}i', $name, $matches)) { + $version = ''; + for ($i = 1; $i < 5; ++$i) { + $version .= isset($matches[$i]) ? str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x'; + } + + return str_replace('x', '9999999', $version) . '-dev'; + } + + return 'dev-' . $name; + } + + /** + * Parses as constraint string into LinkConstraint objects. + * + * @param string $constraints + * + * @return ConstraintInterface + */ + public function parseConstraints($constraints) + { + $prettyConstraint = $constraints; + + if (preg_match('{^([^,\s]*?)@(' . implode('|', self::$stabilities) . ')$}i', $constraints, $match)) { + $constraints = empty($match[1]) ? '*' : $match[1]; + } + + if (preg_match('{^(dev-[^,\s@]+?|[^,\s@]+?\.x-dev)#.+$}i', $constraints, $match)) { + $constraints = $match[1]; + } + + $orConstraints = preg_split('{\s*\|\|?\s*}', trim($constraints)); + $orGroups = array(); + foreach ($orConstraints as $constraints) { + $andConstraints = preg_split('{(?< ,]) *(? 1) { + $constraintObjects = array(); + foreach ($andConstraints as $constraint) { + foreach ($this->parseConstraint($constraint) as $parsedConstraint) { + $constraintObjects[] = $parsedConstraint; + } + } + } else { + $constraintObjects = $this->parseConstraint($andConstraints[0]); + } + + if (1 === count($constraintObjects)) { + $constraint = $constraintObjects[0]; + } else { + $constraint = new MultiConstraint($constraintObjects); + } + + $orGroups[] = $constraint; + } + + if (1 === count($orGroups)) { + $constraint = $orGroups[0]; + } else { + $constraint = new MultiConstraint($orGroups, false); + } + + $constraint->setPrettyString($prettyConstraint); + + return $constraint; + } + + /** + * @param string $constraint + * + * @throws \UnexpectedValueException + * + * @return array + */ + private function parseConstraint($constraint) + { + if (preg_match('{^([^,\s]+?)@(' . implode('|', self::$stabilities) . ')$}i', $constraint, $match)) { + $constraint = $match[1]; + if ($match[2] !== 'stable') { + $stabilityModifier = $match[2]; + } + } + + if (preg_match('{^[xX*](\.[xX*])*$}i', $constraint)) { + return array(new EmptyConstraint()); + } + + $versionRegex = 'v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?' . self::$modifierRegex . '(?:\+[^\s]+)?'; + + // Tilde Range + // + // Like wildcard constraints, unsuffixed tilde constraints say that they must be greater than the previous + // version, to ensure that unstable instances of the current version are allowed. However, if a stability + // suffix is added to the constraint, then a >= match on the current version is used instead. + if (preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) { + if (substr($constraint, 0, 2) === '~>') { + throw new \UnexpectedValueException( + 'Could not parse version constraint ' . $constraint . ': ' . + 'Invalid operator "~>", you probably meant to use the "~" operator' + ); + } + + // Work out which position in the version we are operating at + if (isset($matches[4]) && '' !== $matches[4]) { + $position = 4; + } elseif (isset($matches[3]) && '' !== $matches[3]) { + $position = 3; + } elseif (isset($matches[2]) && '' !== $matches[2]) { + $position = 2; + } else { + $position = 1; + } + + // Calculate the stability suffix + $stabilitySuffix = ''; + if (!empty($matches[5])) { + $stabilitySuffix .= '-' . $this->expandStability($matches[5]) . (!empty($matches[6]) ? $matches[6] : ''); + } + + if (!empty($matches[7])) { + $stabilitySuffix .= '-dev'; + } + + if (!$stabilitySuffix) { + $stabilitySuffix = '-dev'; + } + + $lowVersion = $this->manipulateVersionString($matches, $position, 0) . $stabilitySuffix; + $lowerBound = new Constraint('>=', $lowVersion); + + // For upper bound, we increment the position of one more significance, + // but highPosition = 0 would be illegal + $highPosition = max(1, $position - 1); + $highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev'; + $upperBound = new Constraint('<', $highVersion); + + return array( + $lowerBound, + $upperBound, + ); + } + + // Caret Range + // + // Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple. + // In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for + // versions 0.X >=0.1.0, and no updates for versions 0.0.X + if (preg_match('{^\^' . $versionRegex . '($)}i', $constraint, $matches)) { + // Work out which position in the version we are operating at + if ('0' !== $matches[1] || '' === $matches[2]) { + $position = 1; + } elseif ('0' !== $matches[2] || '' === $matches[3]) { + $position = 2; + } else { + $position = 3; + } + + // Calculate the stability suffix + $stabilitySuffix = ''; + if (empty($matches[5]) && empty($matches[7])) { + $stabilitySuffix .= '-dev'; + } + + $lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1)); + $lowerBound = new Constraint('>=', $lowVersion); + + // For upper bound, we increment the position of one more significance, + // but highPosition = 0 would be illegal + $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev'; + $upperBound = new Constraint('<', $highVersion); + + return array( + $lowerBound, + $upperBound, + ); + } + + // X Range + // + // Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple. + // A partial version range is treated as an X-Range, so the special character is in fact optional. + if (preg_match('{^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.[xX*])+$}', $constraint, $matches)) { + if (isset($matches[3]) && '' !== $matches[3]) { + $position = 3; + } elseif (isset($matches[2]) && '' !== $matches[2]) { + $position = 2; + } else { + $position = 1; + } + + $lowVersion = $this->manipulateVersionString($matches, $position) . '-dev'; + $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev'; + + if ($lowVersion === '0.0.0.0-dev') { + return array(new Constraint('<', $highVersion)); + } + + return array( + new Constraint('>=', $lowVersion), + new Constraint('<', $highVersion), + ); + } + + // Hyphen Range + // + // Specifies an inclusive set. If a partial version is provided as the first version in the inclusive range, + // then the missing pieces are replaced with zeroes. If a partial version is provided as the second version in + // the inclusive range, then all versions that start with the supplied parts of the tuple are accepted, but + // nothing that would be greater than the provided tuple parts. + if (preg_match('{^(?P' . $versionRegex . ') +- +(?P' . $versionRegex . ')($)}i', $constraint, $matches)) { + // Calculate the stability suffix + $lowStabilitySuffix = ''; + if (empty($matches[6]) && empty($matches[8])) { + $lowStabilitySuffix = '-dev'; + } + + $lowVersion = $this->normalize($matches['from']); + $lowerBound = new Constraint('>=', $lowVersion . $lowStabilitySuffix); + + $empty = function ($x) { + return ($x === 0 || $x === '0') ? false : empty($x); + }; + + if ((!$empty($matches[11]) && !$empty($matches[12])) || !empty($matches[14]) || !empty($matches[16])) { + $highVersion = $this->normalize($matches['to']); + $upperBound = new Constraint('<=', $highVersion); + } else { + $highMatch = array('', $matches[10], $matches[11], $matches[12], $matches[13]); + $highVersion = $this->manipulateVersionString($highMatch, $empty($matches[11]) ? 1 : 2, 1) . '-dev'; + $upperBound = new Constraint('<', $highVersion); + } + + return array( + $lowerBound, + $upperBound, + ); + } + + // Basic Comparators + if (preg_match('{^(<>|!=|>=?|<=?|==?)?\s*(.*)}', $constraint, $matches)) { + try { + $version = $this->normalize($matches[2]); + + if (!empty($stabilityModifier) && $this->parseStability($version) === 'stable') { + $version .= '-' . $stabilityModifier; + } elseif ('<' === $matches[1] || '>=' === $matches[1]) { + if (!preg_match('/-' . self::$modifierRegex . '$/', strtolower($matches[2]))) { + if (substr($matches[2], 0, 4) !== 'dev-') { + $version .= '-dev'; + } + } + } + + return array(new Constraint($matches[1] ?: '=', $version)); + } catch (\Exception $e) { + } + } + + $message = 'Could not parse version constraint ' . $constraint; + if (isset($e)) { + $message .= ': ' . $e->getMessage(); + } + + throw new \UnexpectedValueException($message); + } + + /** + * Increment, decrement, or simply pad a version number. + * + * Support function for {@link parseConstraint()} + * + * @param array $matches Array with version parts in array indexes 1,2,3,4 + * @param int $position 1,2,3,4 - which segment of the version to increment/decrement + * @param int $increment + * @param string $pad The string to pad version parts after $position + * + * @return string The new version + */ + private function manipulateVersionString($matches, $position, $increment = 0, $pad = '0') + { + for ($i = 4; $i > 0; --$i) { + if ($i > $position) { + $matches[$i] = $pad; + } elseif ($i === $position && $increment) { + $matches[$i] += $increment; + // If $matches[$i] was 0, carry the decrement + if ($matches[$i] < 0) { + $matches[$i] = $pad; + --$position; + + // Return null on a carry overflow + if ($i === 1) { + return; + } + } + } + } + + return $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.' . $matches[4]; + } + + /** + * Expand shorthand stability string to long version. + * + * @param string $stability + * + * @return string + */ + private function expandStability($stability) + { + $stability = strtolower($stability); + + switch ($stability) { + case 'a': + return 'alpha'; + case 'b': + return 'beta'; + case 'p': + case 'pl': + return 'patch'; + case 'rc': + return 'RC'; + default: + return $stability; + } + } +} diff --git a/vendor/firebase/php-jwt/Authentication/JWT.php b/vendor/firebase/php-jwt/Authentication/JWT.php new file mode 100644 index 00000000..7d6665bd --- /dev/null +++ b/vendor/firebase/php-jwt/Authentication/JWT.php @@ -0,0 +1,334 @@ + + * @author Anant Narayanan + * @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD + * @link https://github.com/firebase/php-jwt + */ +class JWT +{ + + /** + * When checking nbf, iat or expiration times, + * we want to provide some extra leeway time to + * account for clock skew. + */ + public static $leeway = 0; + + public static $supported_algs = array( + 'HS256' => array('hash_hmac', 'SHA256'), + 'HS512' => array('hash_hmac', 'SHA512'), + 'HS384' => array('hash_hmac', 'SHA384'), + 'RS256' => array('openssl', 'SHA256'), + ); + + /** + * Decodes a JWT string into a PHP object. + * + * @param string $jwt The JWT + * @param string|Array|null $key The secret key, or map of keys + * @param Array $allowed_algs List of supported verification algorithms + * + * @return object The JWT's payload as a PHP object + * + * @throws DomainException Algorithm was not provided + * @throws UnexpectedValueException Provided JWT was invalid + * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed + * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf' + * @throws BeforeValidException Provided JWT is trying to be used before it's been created as defined by 'iat' + * @throws ExpiredException Provided JWT has since expired, as defined by the 'exp' claim + * + * @uses jsonDecode + * @uses urlsafeB64Decode + */ + public static function decode($jwt, $key = null, $allowed_algs = array()) + { + $tks = explode('.', $jwt); + if (count($tks) != 3) { + throw new UnexpectedValueException('Wrong number of segments'); + } + list($headb64, $bodyb64, $cryptob64) = $tks; + if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) { + throw new UnexpectedValueException('Invalid header encoding'); + } + if (null === $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) { + throw new UnexpectedValueException('Invalid claims encoding'); + } + $sig = JWT::urlsafeB64Decode($cryptob64); + if (isset($key)) { + if (empty($header->alg)) { + throw new DomainException('Empty algorithm'); + } + if (empty(self::$supported_algs[$header->alg])) { + throw new DomainException('Algorithm not supported'); + } + if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) { + throw new DomainException('Algorithm not allowed'); + } + if (is_array($key) || $key instanceof \ArrayAccess) { + if (isset($header->kid)) { + $key = $key[$header->kid]; + } else { + throw new DomainException('"kid" empty, unable to lookup correct key'); + } + } + + // Check the signature + if (!JWT::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) { + throw new SignatureInvalidException('Signature verification failed'); + } + + // Check if the nbf if it is defined. This is the time that the + // token can actually be used. If it's not yet that time, abort. + if (isset($payload->nbf) && $payload->nbf > (time() + self::$leeway)) { + throw new BeforeValidException( + 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf) + ); + } + + // Check that this token has been created before 'now'. This prevents + // using tokens that have been created for later use (and haven't + // correctly used the nbf claim). + if (isset($payload->iat) && $payload->iat > (time() + self::$leeway)) { + throw new BeforeValidException( + 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat) + ); + } + + // Check if this token has expired. + if (isset($payload->exp) && (time() - self::$leeway) >= $payload->exp) { + throw new ExpiredException('Expired token'); + } + } + + return $payload; + } + + /** + * Converts and signs a PHP object or array into a JWT string. + * + * @param object|array $payload PHP object or array + * @param string $key The secret key + * @param string $alg The signing algorithm. Supported + * algorithms are 'HS256', 'HS384' and 'HS512' + * + * @return string A signed JWT + * @uses jsonEncode + * @uses urlsafeB64Encode + */ + public static function encode($payload, $key, $alg = 'HS256', $keyId = null) + { + $header = array('typ' => 'JWT', 'alg' => $alg); + if ($keyId !== null) { + $header['kid'] = $keyId; + } + $segments = array(); + $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($header)); + $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($payload)); + $signing_input = implode('.', $segments); + + $signature = JWT::sign($signing_input, $key, $alg); + $segments[] = JWT::urlsafeB64Encode($signature); + + return implode('.', $segments); + } + + /** + * Sign a string with a given key and algorithm. + * + * @param string $msg The message to sign + * @param string|resource $key The secret key + * @param string $alg The signing algorithm. Supported algorithms + * are 'HS256', 'HS384', 'HS512' and 'RS256' + * + * @return string An encrypted message + * @throws DomainException Unsupported algorithm was specified + */ + public static function sign($msg, $key, $alg = 'HS256') + { + if (empty(self::$supported_algs[$alg])) { + throw new DomainException('Algorithm not supported'); + } + list($function, $algorithm) = self::$supported_algs[$alg]; + switch($function) { + case 'hash_hmac': + return hash_hmac($algorithm, $msg, $key, true); + case 'openssl': + $signature = ''; + $success = openssl_sign($msg, $signature, $key, $algorithm); + if (!$success) { + throw new DomainException("OpenSSL unable to sign data"); + } else { + return $signature; + } + } + } + + /** + * Verify a signature with the mesage, key and method. Not all methods + * are symmetric, so we must have a separate verify and sign method. + * @param string $msg the original message + * @param string $signature + * @param string|resource $key for HS*, a string key works. for RS*, must be a resource of an openssl public key + * @param string $alg + * @return bool + * @throws DomainException Invalid Algorithm or OpenSSL failure + */ + private static function verify($msg, $signature, $key, $alg) + { + if (empty(self::$supported_algs[$alg])) { + throw new DomainException('Algorithm not supported'); + } + + list($function, $algorithm) = self::$supported_algs[$alg]; + switch($function) { + case 'openssl': + $success = openssl_verify($msg, $signature, $key, $algorithm); + if (!$success) { + throw new DomainException("OpenSSL unable to verify data: " . openssl_error_string()); + } else { + return $signature; + } + case 'hash_hmac': + default: + $hash = hash_hmac($algorithm, $msg, $key, true); + if (function_exists('hash_equals')) { + return hash_equals($signature, $hash); + } + $len = min(self::safeStrlen($signature), self::safeStrlen($hash)); + + $status = 0; + for ($i = 0; $i < $len; $i++) { + $status |= (ord($signature[$i]) ^ ord($hash[$i])); + } + $status |= (self::safeStrlen($signature) ^ self::safeStrlen($hash)); + + return ($status === 0); + } + } + + /** + * Decode a JSON string into a PHP object. + * + * @param string $input JSON string + * + * @return object Object representation of JSON string + * @throws DomainException Provided string was invalid JSON + */ + public static function jsonDecode($input) + { + if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) { + /** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you + * to specify that large ints (like Steam Transaction IDs) should be treated as + * strings, rather than the PHP default behaviour of converting them to floats. + */ + $obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING); + } else { + /** Not all servers will support that, however, so for older versions we must + * manually detect large ints in the JSON string and quote them (thus converting + *them to strings) before decoding, hence the preg_replace() call. + */ + $max_int_length = strlen((string) PHP_INT_MAX) - 1; + $json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input); + $obj = json_decode($json_without_bigints); + } + + if (function_exists('json_last_error') && $errno = json_last_error()) { + JWT::handleJsonError($errno); + } elseif ($obj === null && $input !== 'null') { + throw new DomainException('Null result with non-null input'); + } + return $obj; + } + + /** + * Encode a PHP object into a JSON string. + * + * @param object|array $input A PHP object or array + * + * @return string JSON representation of the PHP object or array + * @throws DomainException Provided object could not be encoded to valid JSON + */ + public static function jsonEncode($input) + { + $json = json_encode($input); + if (function_exists('json_last_error') && $errno = json_last_error()) { + JWT::handleJsonError($errno); + } elseif ($json === 'null' && $input !== null) { + throw new DomainException('Null result with non-null input'); + } + return $json; + } + + /** + * Decode a string with URL-safe Base64. + * + * @param string $input A Base64 encoded string + * + * @return string A decoded string + */ + public static function urlsafeB64Decode($input) + { + $remainder = strlen($input) % 4; + if ($remainder) { + $padlen = 4 - $remainder; + $input .= str_repeat('=', $padlen); + } + return base64_decode(strtr($input, '-_', '+/')); + } + + /** + * Encode a string with URL-safe Base64. + * + * @param string $input The string you want encoded + * + * @return string The base64 encode of what you passed in + */ + public static function urlsafeB64Encode($input) + { + return str_replace('=', '', strtr(base64_encode($input), '+/', '-_')); + } + + /** + * Helper method to create a JSON error. + * + * @param int $errno An error number from json_last_error() + * + * @return void + */ + private static function handleJsonError($errno) + { + $messages = array( + JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', + JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', + JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON' + ); + throw new DomainException( + isset($messages[$errno]) + ? $messages[$errno] + : 'Unknown JSON error: ' . $errno + ); + } + + /** + * Get the number of bytes in cryptographic strings. + * + * @param string + * @return int + */ + private static function safeStrlen($str) + { + if (function_exists('mb_strlen')) { + return mb_strlen($str, '8bit'); + } + return strlen($str); + } +} diff --git a/vendor/firebase/php-jwt/Exceptions/BeforeValidException.php b/vendor/firebase/php-jwt/Exceptions/BeforeValidException.php new file mode 100644 index 00000000..5a84975e --- /dev/null +++ b/vendor/firebase/php-jwt/Exceptions/BeforeValidException.php @@ -0,0 +1,6 @@ + "http://example.org", + "aud" => "http://example.com", + "iat" => 1356999524, + "nbf" => 1357000000 +); + +/** + * IMPORTANT: + * You must specify supported algorithms for your application. See + * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 + * for a list of spec-compliant algorithms. + */ +$jwt = JWT::encode($token, $key); +$decoded = JWT::decode($jwt, $key, array('HS256')); + +print_r($decoded); + +/* + NOTE: This will now be an object instead of an associative array. To get + an associative array, you will need to cast it as such: +*/ + +$decoded_array = (array) $decoded; + +/** + * You can add a leeway to account for when there is a clock skew times between + * the signing and verifying servers. It is recommended that this leeway should + * not be bigger than a few minutes. + * + * Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef + */ +JWT::$leeway = 60; // $leeway in seconds +$decoded = JWT::decode($jwt, $key, array('HS256')); + +?> +``` + +Changelog +--------- + +#### 2.1.0 / 2015-05-20 +- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew +between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! +- Add support for passing an object implementing the `ArrayAccess` interface for +`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! + +#### 2.0.0 / 2015-04-01 +- **Note**: It is strongly recommended that you update to > v2.0.0 to address + known security vulnerabilities in prior versions when both symmetric and + asymmetric keys are used together. +- Update signature for `JWT::decode(...)` to require an array of supported + algorithms to use when verifying token signatures. + + +Tests +----- +Run the tests using phpunit: + +```bash +$ pear install PHPUnit +$ phpunit --configuration phpunit.xml.dist +PHPUnit 3.7.10 by Sebastian Bergmann. +..... +Time: 0 seconds, Memory: 2.50Mb +OK (5 tests, 5 assertions) +``` + +License +------- +[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause). diff --git a/vendor/firebase/php-jwt/composer.json b/vendor/firebase/php-jwt/composer.json new file mode 100644 index 00000000..95560afd --- /dev/null +++ b/vendor/firebase/php-jwt/composer.json @@ -0,0 +1,25 @@ +{ + "name": "firebase/php-jwt", + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "license": "BSD-3-Clause", + "require": { + "php": ">=5.2.0" + }, + "autoload": { + "classmap": ["Authentication/", "Exceptions/"] + }, + "minimum-stability": "dev" +} diff --git a/vendor/firebase/php-jwt/package.xml b/vendor/firebase/php-jwt/package.xml new file mode 100644 index 00000000..b40da26d --- /dev/null +++ b/vendor/firebase/php-jwt/package.xml @@ -0,0 +1,77 @@ + + + JWT + pear.php.net + A JWT encoder/decoder. + A JWT encoder/decoder library for PHP. + + Neuman Vong + lcfrs + neuman+pear@twilio.com + yes + + + Firebase Operations + firebase + operations@firebase.com + yes + + 2015-05-20 + + 2.1.0 + 2.1.0 + + + beta + beta + + BSD 3-Clause License + +Initial release with basic support for JWT encoding, decoding and signature verification. + + + + + + + + + + + + + 5.1 + + + 1.7.0 + + + json + + + hash + + + + + + + + 0.1.0 + 0.1.0 + + + beta + beta + + 2015-04-01 + BSD 3-Clause License + +Initial release with basic support for JWT encoding, decoding and signature verification. + + + + diff --git a/vendor/firebase/php-jwt/phpunit.xml.dist b/vendor/firebase/php-jwt/phpunit.xml.dist new file mode 100644 index 00000000..9f85f5ba --- /dev/null +++ b/vendor/firebase/php-jwt/phpunit.xml.dist @@ -0,0 +1,19 @@ + + + + + + ./tests + + + diff --git a/vendor/firebase/php-jwt/run-tests.sh b/vendor/firebase/php-jwt/run-tests.sh new file mode 100644 index 00000000..d37c30fd --- /dev/null +++ b/vendor/firebase/php-jwt/run-tests.sh @@ -0,0 +1,38 @@ + +#!/usr/bin/env bash +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 + +# Let's grab the latest release and its signature +if [ ! -f phpunit.phar ]; then + wget https://phar.phpunit.de/phpunit.phar +fi +if [ ! -f phpunit.phar.asc ]; then + wget https://phar.phpunit.de/phpunit.phar.asc +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 + php --version + php phpunit.phar --configuration phpunit.xml.dist +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! PHPUnit has been moved to /tmp/bad-phpunit.phar\033[0m" + exit 1 +fi diff --git a/vendor/firebase/php-jwt/tests/JWTTest.php b/vendor/firebase/php-jwt/tests/JWTTest.php new file mode 100644 index 00000000..0605e4ca --- /dev/null +++ b/vendor/firebase/php-jwt/tests/JWTTest.php @@ -0,0 +1,231 @@ +assertEquals(JWT::decode($msg, 'my_key', array('HS256')), 'abc'); + } + + public function testDecodeFromPython() + { + $msg = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.Iio6aHR0cDovL2FwcGxpY2F0aW9uL2NsaWNreT9ibGFoPTEuMjMmZi5vbz00NTYgQUMwMDAgMTIzIg.E_U8X2YpMT5K1cEiT_3-IvBYfrdIFIeVYeOqre_Z5Cg'; + $this->assertEquals( + JWT::decode($msg, 'my_key', array('HS256')), + '*:http://application/clicky?blah=1.23&f.oo=456 AC000 123' + ); + } + + public function testUrlSafeCharacters() + { + $encoded = JWT::encode('f?', 'a'); + $this->assertEquals('f?', JWT::decode($encoded, 'a', array('HS256'))); + } + + public function testMalformedUtf8StringsFail() + { + $this->setExpectedException('DomainException'); + JWT::encode(pack('c', 128), 'a'); + } + + public function testMalformedJsonThrowsException() + { + $this->setExpectedException('DomainException'); + JWT::jsonDecode('this is not valid JSON string'); + } + + public function testExpiredToken() + { + $this->setExpectedException('ExpiredException'); + $payload = array( + "message" => "abc", + "exp" => time() - 20); // time in the past + $encoded = JWT::encode($payload, 'my_key'); + JWT::decode($encoded, 'my_key', array('HS256')); + } + + public function testBeforeValidTokenWithNbf() + { + $this->setExpectedException('BeforeValidException'); + $payload = array( + "message" => "abc", + "nbf" => time() + 20); // time in the future + $encoded = JWT::encode($payload, 'my_key'); + JWT::decode($encoded, 'my_key', array('HS256')); + } + + public function testBeforeValidTokenWithIat() + { + $this->setExpectedException('BeforeValidException'); + $payload = array( + "message" => "abc", + "iat" => time() + 20); // time in the future + $encoded = JWT::encode($payload, 'my_key'); + JWT::decode($encoded, 'my_key', array('HS256')); + } + + public function testValidToken() + { + $payload = array( + "message" => "abc", + "exp" => time() + JWT::$leeway + 20); // time in the future + $encoded = JWT::encode($payload, 'my_key'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + $this->assertEquals($decoded->message, 'abc'); + } + + public function testValidTokenWithLeeway() + { + JWT::$leeway = 60; + $payload = array( + "message" => "abc", + "exp" => time() - 20); // time in the past + $encoded = JWT::encode($payload, 'my_key'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + $this->assertEquals($decoded->message, 'abc'); + JWT::$leeway = 0; + } + + public function testExpiredTokenWithLeeway() + { + JWT::$leeway = 60; + $payload = array( + "message" => "abc", + "exp" => time() - 70); // time far in the past + $this->setExpectedException('ExpiredException'); + $encoded = JWT::encode($payload, 'my_key'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + $this->assertEquals($decoded->message, 'abc'); + JWT::$leeway = 0; + } + + public function testValidTokenWithList() + { + $payload = array( + "message" => "abc", + "exp" => time() + 20); // time in the future + $encoded = JWT::encode($payload, 'my_key'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256', 'HS512')); + $this->assertEquals($decoded->message, 'abc'); + } + + public function testValidTokenWithNbf() + { + $payload = array( + "message" => "abc", + "iat" => time(), + "exp" => time() + 20, // time in the future + "nbf" => time() - 20); + $encoded = JWT::encode($payload, 'my_key'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + $this->assertEquals($decoded->message, 'abc'); + } + + public function testValidTokenWithNbfLeeway() + { + JWT::$leeway = 60; + $payload = array( + "message" => "abc", + "nbf" => time() + 20); // not before in near (leeway) future + $encoded = JWT::encode($payload, 'my_key'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + $this->assertEquals($decoded->message, 'abc'); + JWT::$leeway = 0; + } + + public function testInvalidTokenWithNbfLeeway() + { + JWT::$leeway = 60; + $payload = array( + "message" => "abc", + "nbf" => time() + 65); // not before too far in future + $encoded = JWT::encode($payload, 'my_key'); + $this->setExpectedException('BeforeValidException'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + JWT::$leeway = 0; + } + + public function testValidTokenWithIatLeeway() + { + JWT::$leeway = 60; + $payload = array( + "message" => "abc", + "iat" => time() + 20); // issued in near (leeway) future + $encoded = JWT::encode($payload, 'my_key'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + $this->assertEquals($decoded->message, 'abc'); + JWT::$leeway = 0; + } + + public function testInvalidTokenWithIatLeeway() + { + JWT::$leeway = 60; + $payload = array( + "message" => "abc", + "iat" => time() + 65); // issued too far in future + $encoded = JWT::encode($payload, 'my_key'); + $this->setExpectedException('BeforeValidException'); + $decoded = JWT::decode($encoded, 'my_key', array('HS256')); + JWT::$leeway = 0; + } + + public function testInvalidToken() + { + $payload = array( + "message" => "abc", + "exp" => time() + 20); // time in the future + $encoded = JWT::encode($payload, 'my_key'); + $this->setExpectedException('SignatureInvalidException'); + $decoded = JWT::decode($encoded, 'my_key2', array('HS256')); + } + + public function testRSEncodeDecode() + { + $privKey = openssl_pkey_new(array('digest_alg' => 'sha256', + 'private_key_bits' => 1024, + 'private_key_type' => OPENSSL_KEYTYPE_RSA)); + $msg = JWT::encode('abc', $privKey, 'RS256'); + $pubKey = openssl_pkey_get_details($privKey); + $pubKey = $pubKey['key']; + $decoded = JWT::decode($msg, $pubKey, array('RS256')); + $this->assertEquals($decoded, 'abc'); + } + + public function testKIDChooser() + { + $keys = array('1' => 'my_key', '2' => 'my_key2'); + $msg = JWT::encode('abc', $keys['1'], 'HS256', '1'); + $decoded = JWT::decode($msg, $keys, array('HS256')); + $this->assertEquals($decoded, 'abc'); + } + + public function testArrayAccessKIDChooser() + { + $keys = new ArrayObject(array('1' => 'my_key', '2' => 'my_key2')); + $msg = JWT::encode('abc', $keys['1'], 'HS256', '1'); + $decoded = JWT::decode($msg, $keys, array('HS256')); + $this->assertEquals($decoded, 'abc'); + } + + public function testNoneAlgorithm() + { + $msg = JWT::encode('abc', 'my_key'); + $this->setExpectedException('DomainException'); + JWT::decode($msg, 'my_key', array('none')); + } + + public function testIncorrectAlgorithm() + { + $msg = JWT::encode('abc', 'my_key'); + $this->setExpectedException('DomainException'); + JWT::decode($msg, 'my_key', array('RS256')); + } + + public function testMissingAlgorithm() + { + $msg = JWT::encode('abc', 'my_key'); + $this->setExpectedException('DomainException'); + JWT::decode($msg, 'my_key'); + } +} diff --git a/vendor/firebase/php-jwt/tests/autoload.php.dist b/vendor/firebase/php-jwt/tests/autoload.php.dist new file mode 100644 index 00000000..2e4310a0 --- /dev/null +++ b/vendor/firebase/php-jwt/tests/autoload.php.dist @@ -0,0 +1,17 @@ +=1.0" + } +} +``` + +Usage +----- + +### Highlight the source code + +``` php +highlight(file_get_contents('index.php'), 'php', 'html'); +$text = $pygments->highlight('package main', 'go', 'ansi'); +``` + +### Generate a CSS + +``` php +getCss('monokai'); +$prefixedCss = $pygments->getCss('default', '.syntax'); +``` + +### Guesses a lexer name + +``` php +guessLexer('foo.rb'); // ruby +``` + +### Get a list of lexers/formatters/styles + +``` php +getLexers() +$pygments->getFormatters(); +$pygments->getStyles(); +``` + +### Custom `pygmentize` path + +``` php +=5.3.2", + "symfony/process": ">=2.3" + }, + "require-dev": { + "symfony/finder": ">=2.3" + }, + "autoload": { + "psr-0": { + "": "src" + } + } +} \ No newline at end of file diff --git a/vendor/kzykhys/pygments/composer.lock b/vendor/kzykhys/pygments/composer.lock new file mode 100644 index 00000000..fa031822 --- /dev/null +++ b/vendor/kzykhys/pygments/composer.lock @@ -0,0 +1,118 @@ +{ + "_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" + ], + "hash": "d2e111fb167611c09ab96baa0504b60b", + "packages": [ + { + "name": "symfony/process", + "version": "v2.4.0", + "target-dir": "Symfony/Component/Process", + "source": { + "type": "git", + "url": "https://github.com/symfony/Process.git", + "reference": "87738ff42e2467730ed74d941866e95513844b70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Process/zipball/87738ff42e2467730ed74d941866e95513844b70", + "reference": "87738ff42e2467730ed74d941866e95513844b70", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Process\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "http://symfony.com", + "time": "2013-11-26 16:40:27" + } + ], + "packages-dev": [ + { + "name": "symfony/finder", + "version": "v2.4.0", + "target-dir": "Symfony/Component/Finder", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "72356bf0646b11af1bae666c28a639bd8ede459f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/72356bf0646b11af1bae666c28a639bd8ede459f", + "reference": "72356bf0646b11af1bae666c28a639bd8ede459f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "http://symfony.com", + "time": "2013-11-26 16:40:27" + } + ], + "aliases": [ + + ], + "minimum-stability": "stable", + "stability-flags": [ + + ], + "platform": { + "php": ">=5.3.2" + }, + "platform-dev": [ + + ] +} diff --git a/vendor/kzykhys/pygments/phpunit.xml.dist b/vendor/kzykhys/pygments/phpunit.xml.dist new file mode 100644 index 00000000..ad8dd7b0 --- /dev/null +++ b/vendor/kzykhys/pygments/phpunit.xml.dist @@ -0,0 +1,28 @@ + + + + + + + + test + + + + + + src + + + + \ No newline at end of file diff --git a/vendor/kzykhys/pygments/src/KzykHys/Pygments/Pygments.php b/vendor/kzykhys/pygments/src/KzykHys/Pygments/Pygments.php new file mode 100644 index 00000000..6ebd6522 --- /dev/null +++ b/vendor/kzykhys/pygments/src/KzykHys/Pygments/Pygments.php @@ -0,0 +1,200 @@ + + */ +class Pygments +{ + + /** + * @var string + */ + private $pygmentize; + + /** + * Constructor + * + * @param string $pygmentize The path to pygmentize command + */ + public function __construct($pygmentize = 'pygmentize') + { + $this->pygmentize = $pygmentize; + } + + /** + * Highlight the input code + * + * @param string $code The code to highlight + * @param string $lexer The name of the lexer (php, html,...) + * @param string $formatter The name of the formatter (html, ansi,...) + * @param array $options An array of options + * + * @return string + */ + public function highlight($code, $lexer = null, $formatter = null, $options = array()) + { + $builder = $this->createProcessBuilder(); + + if ($lexer) { + $builder->add('-l')->add($lexer); + } else { + $builder->add('-g'); + } + + if ($formatter) { + $builder->add('-f')->add($formatter); + } + + if (count($options)) { + $arg = array(); + + foreach ($options as $key => $value) { + $arg[] = sprintf('%s=%s', $key, $value); + } + + $builder->add('-O')->add(implode(',', $arg)); + } + + $process = $builder->getProcess()->setStdin($code); + + return $this->getOutput($process); + } + + /** + * Gets style definition + * + * @param string $style The name of the style (default, colorful,...) + * @param string $selector The css selector + * + * @return string + */ + public function getCss($style = 'default', $selector = null) + { + $builder = $this->createProcessBuilder(); + $builder->add('-f')->add('html'); + $builder->add('-S')->add($style); + + if ($selector) { + $builder->add('-a')->add($selector); + } + + return $this->getOutput($builder->getProcess()); + } + + /** + * Guesses a lexer name based solely on the given filename + * + * @param string $fileName The file does not need to exist, or be readable. + * + * @return string + */ + public function guessLexer($fileName) + { + $process = $this->createProcessBuilder() + ->setArguments(array('-N', $fileName)) + ->getProcess(); + + return trim($this->getOutput($process)); + } + + /** + * Gets a list of lexers + * + * @return array + */ + public function getLexers() + { + $process = $this->createProcessBuilder() + ->setArguments(array('-L', 'lexer')) + ->getProcess(); + + $output = $this->getOutput($process); + + return $this->parseList($output); + } + + /** + * Gets a list of formatters + * + * @return array + */ + public function getFormatters() + { + $process = $this->createProcessBuilder() + ->setArguments(array('-L', 'formatter')) + ->getProcess(); + + $output = $this->getOutput($process); + + return $this->parseList($output); + } + + /** + * Gets a list of styles + * + * @return array + */ + public function getStyles() + { + $process = $this->createProcessBuilder() + ->setArguments(array('-L', 'style')) + ->getProcess(); + + $output = $this->getOutput($process); + + return $this->parseList($output); + } + + /** + * @return ProcessBuilder + */ + protected function createProcessBuilder() + { + return ProcessBuilder::create()->setPrefix($this->pygmentize); + } + + /** + * @param Process $process + * @throws \RuntimeException + * @return string + */ + protected function getOutput(Process $process) + { + $process->run(); + + if (!$process->isSuccessful()) { + throw new \RuntimeException($process->getErrorOutput()); + } + + return $process->getOutput(); + } + + /** + * @param string $input + * @return array + */ + protected function parseList($input) + { + $list = array(); + + if (preg_match_all('/^\* (.*?):\r?\n *([^\r\n]*?)$/m', $input, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $names = explode(',', $match[1]); + + foreach ($names as $name) { + $list[trim($name)] = $match[2]; + } + } + } + + return $list; + } + +} \ No newline at end of file diff --git a/vendor/kzykhys/pygments/test/KzykHys/Pygments/PygmentsTest.php b/vendor/kzykhys/pygments/test/KzykHys/Pygments/PygmentsTest.php new file mode 100644 index 00000000..2110e0d8 --- /dev/null +++ b/vendor/kzykhys/pygments/test/KzykHys/Pygments/PygmentsTest.php @@ -0,0 +1,116 @@ + + */ +class PygmentsTest extends PHPUnit_Framework_TestCase +{ + + /** + * @dataProvider provideSamples + */ + public function testHighlight($input, $expected, $expectedL, $lexer) + { + $pygments = new Pygments(); + + $this->assertEquals($expected, $pygments->highlight($input, null, 'html')); + $this->assertEquals($expected, $pygments->highlight($input, $lexer, 'html')); + $this->assertEquals($expectedL, $pygments->highlight($input, null, 'html', array('linenos' => 1))); + } + + /** + * @dataProvider provideCss + */ + public function testGetCss($expected, $expectedA, $style) + { + $pygments = new Pygments(); + + $this->assertEquals($expected, $pygments->getCss($style)); + $this->assertEquals($expectedA, $pygments->getCss($style, '.syntax')); + } + + public function testGetLexers() + { + $pygments = new Pygments(); + $lexers = $pygments->getLexers(); + + $this->assertArrayHasKey('python', $lexers); + } + + public function testGetFormatters() + { + $pygments = new Pygments(); + $formatters = $pygments->getFormatters(); + + $this->assertArrayHasKey('html', $formatters); + } + + public function testGetStyles() + { + $pygments = new Pygments(); + $styles = $pygments->getStyles(); + + $this->assertArrayHasKey('monokai', $styles); + } + + public function testGuessLexer() + { + $pygments = new Pygments(); + + $this->assertEquals('php', $pygments->guessLexer('index.php')); + $this->assertEquals('go', $pygments->guessLexer('main.go')); + } + + public function provideSamples() + { + $finder = new Finder(); + $finder + ->in(__DIR__ . '/Resources/example') + ->name("*.in") + ->notName('*.linenos.out') + ->files() + ->ignoreVCS(true); + + $samples = array(); + + /* @var \Symfony\Component\Finder\SplFileInfo $file */ + foreach ($finder as $file) { + $samples[] = array( + $file->getContents(), + file_get_contents(str_replace('.in', '.out', $file->getPathname())), + file_get_contents(str_replace('.in', '.linenos.out', $file->getPathname())), + preg_replace('/\..*/', '', $file->getFilename()) + ); + } + + return $samples; + } + + public function provideCss() + { + $finder = new Finder(); + $finder + ->in(__DIR__ . '/Resources/css') + ->files() + ->ignoreVCS(true) + ->name('*.css') + ->notName('*.prefix.css'); + + $css = array(); + + /* @var \Symfony\Component\Finder\SplFileInfo $file */ + foreach ($finder as $file) { + $css[] = array( + $file->getContents(), + file_get_contents(str_replace('.css', '.prefix.css', $file->getPathname())), + str_replace('.css', '', $file->getFilename()) + ); + } + + return $css; + } + +} \ No newline at end of file diff --git a/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/css/default.css b/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/css/default.css new file mode 100644 index 00000000..67e6ea39 --- /dev/null +++ b/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/css/default.css @@ -0,0 +1,61 @@ +.hll { background-color: #ffffcc } +.c { color: #408080; font-style: italic } /* Comment */ +.err { border: 1px solid #FF0000 } /* Error */ +.k { color: #008000; font-weight: bold } /* Keyword */ +.o { color: #666666 } /* Operator */ +.cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.cp { color: #BC7A00 } /* Comment.Preproc */ +.c1 { color: #408080; font-style: italic } /* Comment.Single */ +.cs { color: #408080; font-style: italic } /* Comment.Special */ +.gd { color: #A00000 } /* Generic.Deleted */ +.ge { font-style: italic } /* Generic.Emph */ +.gr { color: #FF0000 } /* Generic.Error */ +.gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.gi { color: #00A000 } /* Generic.Inserted */ +.go { color: #888888 } /* Generic.Output */ +.gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.gt { color: #0044DD } /* Generic.Traceback */ +.kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #008000 } /* Keyword.Pseudo */ +.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #B00040 } /* Keyword.Type */ +.m { color: #666666 } /* Literal.Number */ +.s { color: #BA2121 } /* Literal.String */ +.na { color: #7D9029 } /* Name.Attribute */ +.nb { color: #008000 } /* Name.Builtin */ +.nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.no { color: #880000 } /* Name.Constant */ +.nd { color: #AA22FF } /* Name.Decorator */ +.ni { color: #999999; font-weight: bold } /* Name.Entity */ +.ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.nf { color: #0000FF } /* Name.Function */ +.nl { color: #A0A000 } /* Name.Label */ +.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.nt { color: #008000; font-weight: bold } /* Name.Tag */ +.nv { color: #19177C } /* Name.Variable */ +.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.w { color: #bbbbbb } /* Text.Whitespace */ +.mf { color: #666666 } /* Literal.Number.Float */ +.mh { color: #666666 } /* Literal.Number.Hex */ +.mi { color: #666666 } /* Literal.Number.Integer */ +.mo { color: #666666 } /* Literal.Number.Oct */ +.sb { color: #BA2121 } /* Literal.String.Backtick */ +.sc { color: #BA2121 } /* Literal.String.Char */ +.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.s2 { color: #BA2121 } /* Literal.String.Double */ +.se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.sh { color: #BA2121 } /* Literal.String.Heredoc */ +.si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.sx { color: #008000 } /* Literal.String.Other */ +.sr { color: #BB6688 } /* Literal.String.Regex */ +.s1 { color: #BA2121 } /* Literal.String.Single */ +.ss { color: #19177C } /* Literal.String.Symbol */ +.bp { color: #008000 } /* Name.Builtin.Pseudo */ +.vc { color: #19177C } /* Name.Variable.Class */ +.vg { color: #19177C } /* Name.Variable.Global */ +.vi { color: #19177C } /* Name.Variable.Instance */ +.il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/css/default.prefix.css b/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/css/default.prefix.css new file mode 100644 index 00000000..eb17bc3e --- /dev/null +++ b/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/css/default.prefix.css @@ -0,0 +1,62 @@ +.syntax .hll { background-color: #ffffcc } +.syntax { background: #f8f8f8; } +.syntax .c { color: #408080; font-style: italic } /* Comment */ +.syntax .err { border: 1px solid #FF0000 } /* Error */ +.syntax .k { color: #008000; font-weight: bold } /* Keyword */ +.syntax .o { color: #666666 } /* Operator */ +.syntax .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.syntax .cp { color: #BC7A00 } /* Comment.Preproc */ +.syntax .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.syntax .cs { color: #408080; font-style: italic } /* Comment.Special */ +.syntax .gd { color: #A00000 } /* Generic.Deleted */ +.syntax .ge { font-style: italic } /* Generic.Emph */ +.syntax .gr { color: #FF0000 } /* Generic.Error */ +.syntax .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.syntax .gi { color: #00A000 } /* Generic.Inserted */ +.syntax .go { color: #888888 } /* Generic.Output */ +.syntax .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.syntax .gs { font-weight: bold } /* Generic.Strong */ +.syntax .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.syntax .gt { color: #0044DD } /* Generic.Traceback */ +.syntax .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.syntax .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.syntax .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.syntax .kp { color: #008000 } /* Keyword.Pseudo */ +.syntax .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.syntax .kt { color: #B00040 } /* Keyword.Type */ +.syntax .m { color: #666666 } /* Literal.Number */ +.syntax .s { color: #BA2121 } /* Literal.String */ +.syntax .na { color: #7D9029 } /* Name.Attribute */ +.syntax .nb { color: #008000 } /* Name.Builtin */ +.syntax .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.syntax .no { color: #880000 } /* Name.Constant */ +.syntax .nd { color: #AA22FF } /* Name.Decorator */ +.syntax .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.syntax .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.syntax .nf { color: #0000FF } /* Name.Function */ +.syntax .nl { color: #A0A000 } /* Name.Label */ +.syntax .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.syntax .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.syntax .nv { color: #19177C } /* Name.Variable */ +.syntax .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.syntax .w { color: #bbbbbb } /* Text.Whitespace */ +.syntax .mf { color: #666666 } /* Literal.Number.Float */ +.syntax .mh { color: #666666 } /* Literal.Number.Hex */ +.syntax .mi { color: #666666 } /* Literal.Number.Integer */ +.syntax .mo { color: #666666 } /* Literal.Number.Oct */ +.syntax .sb { color: #BA2121 } /* Literal.String.Backtick */ +.syntax .sc { color: #BA2121 } /* Literal.String.Char */ +.syntax .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.syntax .s2 { color: #BA2121 } /* Literal.String.Double */ +.syntax .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.syntax .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.syntax .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.syntax .sx { color: #008000 } /* Literal.String.Other */ +.syntax .sr { color: #BB6688 } /* Literal.String.Regex */ +.syntax .s1 { color: #BA2121 } /* Literal.String.Single */ +.syntax .ss { color: #19177C } /* Literal.String.Symbol */ +.syntax .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.syntax .vc { color: #19177C } /* Name.Variable.Class */ +.syntax .vg { color: #19177C } /* Name.Variable.Global */ +.syntax .vi { color: #19177C } /* Name.Variable.Instance */ +.syntax .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.in b/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.in new file mode 100644 index 00000000..b5d94041 --- /dev/null +++ b/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.in @@ -0,0 +1,21 @@ +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
<?php
+
+class Foo
+{
+    const TEST_CONST = 1;
+
+    public static $staticProperty = null;
+
+    public $property = null;
+
+    public static function staticMethod()
+    {
+        return new static();
+    }
+
+    public function method()
+    {
+        return $this;
+    }
+
+}
+
+ \ No newline at end of file diff --git a/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.out b/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.out new file mode 100644 index 00000000..c5e907f1 --- /dev/null +++ b/vendor/kzykhys/pygments/test/KzykHys/Pygments/Resources/example/php.php.out @@ -0,0 +1,22 @@ +
<?php
+
+class Foo
+{
+    const TEST_CONST = 1;
+
+    public static $staticProperty = null;
+
+    public $property = null;
+
+    public static function staticMethod()
+    {
+        return new static();
+    }
+
+    public function method()
+    {
+        return $this;
+    }
+
+}
+
diff --git a/vendor/leafo/lessphp/LICENSE b/vendor/leafo/lessphp/LICENSE deleted file mode 100644 index 49c9ea41..00000000 --- a/vendor/leafo/lessphp/LICENSE +++ /dev/null @@ -1,660 +0,0 @@ -For ease of distribution, lessphp 0.4.0 is under a dual license. -You are free to pick which one suits your needs. - - - - -MIT LICENSE - - - - -Copyright (c) 2013 Leaf Corcoran, http://leafo.net/lessphp - -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. - - - - -GPL VERSION 3 - - - - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - diff --git a/vendor/leafo/lessphp/Makefile b/vendor/leafo/lessphp/Makefile deleted file mode 100644 index a5d262cd..00000000 --- a/vendor/leafo/lessphp/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - phpunit --colors tests - -release: - ./package.sh - diff --git a/vendor/leafo/lessphp/README.md b/vendor/leafo/lessphp/README.md deleted file mode 100644 index 1379ddce..00000000 --- a/vendor/leafo/lessphp/README.md +++ /dev/null @@ -1,96 +0,0 @@ -[![Build Status](https://travis-ci.org/leafo/lessphp.svg?branch=master)](https://travis-ci.org/leafo/lessphp) - -# lessphp v0.5.0 -### - -`lessphp` is a compiler for LESS written in PHP. The documentation is great, -so check it out: . - -Here's a quick tutorial: - -### How to use in your PHP project - -The only file required is `lessc.inc.php`, so copy that to your include directory. - -The typical flow of **lessphp** is to create a new instance of `lessc`, -configure it how you like, then tell it to compile something using one built in -compile methods. - -The `compile` method compiles a string of LESS code to CSS. - -```php -compile(".block { padding: 3 + 4px }"); -``` - -The `compileFile` method reads and compiles a file. It will either return the -result or write it to the path specified by an optional second argument. - -```php -compileFile("input.less"); -``` - -The `compileChecked` method is like `compileFile`, but it only compiles if the output -file doesn't exist or it's older than the input file: - -```php -checkedCompile("input.less", "output.css"); -``` - -If there any problem compiling your code, an exception is thrown with a helpful message: - -```php -compile("invalid LESS } {"); -} catch (exception $e) { - echo "fatal error: " . $e->getMessage(); -} -``` - -The `lessc` object can be configured through an assortment of instance methods. -Some possible configuration options include [changing the output format][1], -[setting variables from PHP][2], and [controlling the preservation of -comments][3], writing [custom functions][4] and much more. It's all described -in [the documentation][0]. - - - [0]: http://leafo.net/lessphp/docs/ - [1]: http://leafo.net/lessphp/docs/#output_formatting - [2]: http://leafo.net/lessphp/docs/#setting_variables_from_php - [3]: http://leafo.net/lessphp/docs/#preserving_comments - [4]: http://leafo.net/lessphp/docs/#custom_functions - - -### How to use from the command line - -An additional script has been included to use the compiler from the command -line. In the simplest invocation, you specify an input file and the compiled -css is written to standard out: - - $ plessc input.less > output.css - -Using the -r flag, you can specify LESS code directly as an argument or, if -the argument is left off, from standard in: - - $ plessc -r "my less code here" - -Finally, by using the -w flag you can watch a specified input file and have it -compile as needed to the output file: - - $ plessc -w input-file output-file - -Errors from watch mode are written to standard out. - -The -f flag sets the [output formatter][1]. For example, to compress the -output run this: - - $ plessc -f=compressed myfile.less - -For more help, run `plessc --help` - diff --git a/vendor/leafo/lessphp/composer.json b/vendor/leafo/lessphp/composer.json deleted file mode 100644 index 0f06ba09..00000000 --- a/vendor/leafo/lessphp/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "leafo/lessphp", - "type": "library", - "description": "lessphp is a compiler for LESS written in PHP.", - "homepage": "http://leafo.net/lessphp/", - "license": [ - "MIT", - "GPL-3.0" - ], - "authors": [ - { - "name": "Leaf Corcoran", - "email": "leafot@gmail.com", - "homepage": "http://leafo.net" - } - ], - "autoload": { - "classmap": ["lessc.inc.php"] - }, - "extra": { - "branch-alias": { - "dev-master": "0.4.x-dev" - } - } -} diff --git a/vendor/leafo/lessphp/docs/docs.md b/vendor/leafo/lessphp/docs/docs.md deleted file mode 100644 index 112dc2ee..00000000 --- a/vendor/leafo/lessphp/docs/docs.md +++ /dev/null @@ -1,1400 +0,0 @@ - title: v0.5.0 documentation - link_to_home: true --- - -

Documentation v0.5.0

- -
$index
- -**lessphp** is a compiler that generates CSS from a superset language which -adds a collection of convenient features often seen in other languages. All CSS -is compatible with LESS, so you can start using new features with your existing CSS. - -It is designed to be compatible with [less.js](http://lesscss.org), and suitable -as a drop in replacement for PHP projects. - -## Getting Started - -The homepage for **lessphp** can be found at [http://leafo.net/lessphp/][1]. - -You can follow development at the project's [GitHub][2]. - -Including **lessphp** in your project is as simple as dropping the single -include file into your code base and running the appropriate compile method as -described in the [PHP Interface](#php_interface). - - [1]: http://leafo.net/lessphp "lessphp homepage" - [2]: https://github.com/leafo/lessphp "lessphp GitHub page" - -## Installation - -**lessphp** is distributed entirely in a single stand-alone file. Download the -latest version from either [the homepage][1] or [GitHub][2]. - -Development versions can also be downloading from GitHub. - -Place `lessphp.inc.php` in a location available to your PHP scripts, and -include it. That's it! you're ready to begin. - -## The Language - -**lessphp** is very easy to learn because it generally functions how you would -expect it to. If you feel something is challenging or missing, feel free to -open an issue on the [bug tracker](https://github.com/leafo/lessphp/issues). - -It is also easy to learn because any standards-compliant CSS code is valid LESS -code. You are free to gradually enhance your existing CSS code base with LESS -features without having to worry about rewriting anything. - -The following is a description of the new languages features provided by LESS. - -### Line Comments - -Simple but very useful; line comments are started with `//`: - - ```less - // this is a comment - body { - color: red; // as is this - /* block comments still work also */ - } - ``` - -### Variables - -Variables are identified with a name that starts with `@`. To declare a -variable, you create an appropriately named CSS property and assign it a value: - - ```less - @family: "verdana"; - @color: red; - body { - @mycolor: red; - font-family: @family; - color: @color; - border-bottom: 1px solid @color; - } - ``` - -Variable declarations will not appear in the output. Variables can be declared -in the outer most scope of the file, or anywhere else a CSS property may -appear. They can hold any CSS property value. - -Variables are only visible for use from their current scope, or any enclosed -scopes. - -If you have a string or keyword in a variable, you can reference another -variable by that name by repeating the `@`: - - ```less - @value: 20px; - @value_name: "value"; - - width: @@value_name; - ``` - -### Expressions - -Expressions let you combine values and variables in meaningful ways. For -example you can add to a color to make it a different shade. Or divide up the -width of your layout logically. You can even concatenate strings. - -Use the mathematical operators to evaluate an expression: - - ```less - @width: 960px; - .nav { - width: @width / 3; - color: #001 + #abc; - } - .body { - width: 2 * @width / 3; - font-family: "hel" + "vetica"; - } - ``` - -Parentheses can be used to control the order of evaluation. They can also be -used to force an evaluation for cases where CSS's syntax makes the expression -ambiguous. - -The following property will produce two numbers, instead of doing the -subtraction: - - ```less - margin: 10px -5px; - ``` - -To force the subtraction: - - ```less - margin: (10px -5px); - ``` - -It is also safe to surround mathematical operators by spaces to ensure that -they are evaluated: - - ```less - margin: 10px - 5px; - ``` - -Division has a special quirk. There are certain CSS properties that use the `/` -operator as part of their value's syntax. Namely, the [font][4] shorthand and -[border-radius][3]. - - [3]: https://developer.mozilla.org/en/CSS/border-radius - [4]: https://developer.mozilla.org/en/CSS/font - - -Thus, **lessphp** will ignore any division in these properties unless it is -wrapped in parentheses. For example, no division will take place here: - - ```less - .font { - font: 20px/80px "Times New Roman"; - } - ``` - -In order to force division we must wrap the expression in parentheses: - - ```less - .font { - font: (20px/80px) "Times New Roman"; - } - ``` - -If you want to write a literal `/` expression without dividing in another -property (or a variable), you can use [string unquoting](#string_unquoting): - - ```less - .var { - @size: ~"20px/80px"; - font: @size sans-serif; - } - ``` - -### Nested Blocks - -By nesting blocks we can build up a chain of CSS selectors through scope -instead of repeating them. In addition to reducing repetition, this also helps -logically organize the structure of our CSS. - - ```less - ol.list { - li.special { - border: 1px solid red; - } - - li.plain { - font-weight: bold; - } - } - ``` - - -This will produce two blocks, a `ol.list li.special` and `ol.list li.plain`. - -Blocks can be nested as deep as required in order to build a hierarchy of -relationships. - -The `&` operator can be used in a selector to represent its parent's selector. -If the `&` operator is used, then the default action of appending the parent to -the front of the child selector separated by space is not performed. - - ```less - b { - a & { - color: red; - } - - // the following have the same effect - - & i { - color: blue; - } - - i { - color: blue; - } - } - ``` - - -Because the `&` operator respects the whitespace around it, we can use it to -control how the child blocks are joined. Consider the differences between the -following: - - ```less - div { - .child-class { color: purple; } - - &.isa-class { color: green; } - - #child-id { height: 200px; } - - &#div-id { height: 400px; } - - &:hover { color: red; } - - :link { color: blue; } - } - ``` - -The `&` operator also works with [mixins](#mixins), which produces interesting results: - - ```less - .within_box_style() { - .box & { - color: blue; - } - } - - #menu { - .within_box_style; - } - ``` - -### Mixins - -Any block can be mixed in just by naming it: - - ```less - .mymixin { - color: blue; - border: 1px solid red; - - .special { - font-weight: bold; - } - } - - - h1 { - font-size: 200px; - .mymixin; - } - ``` - -All properties and child blocks are mixed in. - -Mixins can be made parametric, meaning they can take arguments, in order to -enhance their utility. A parametric mixin all by itself is not outputted when -compiled. Its properties will only appear when mixed into another block. - -The canonical example is to create a rounded corners mixin that works across -browsers: - - ```less - .rounded-corners(@radius: 5px) { - border-radius: @radius; - -webkit-border-radius: @radius; - -moz-border-radius: @radius; - } - - .header { - .rounded-corners(); - } - - .info { - background: red; - .rounded-corners(14px); - } - ``` - -If you have a mixin that doesn't have any arguments, but you don't want it to -show up in the output, give it a blank argument list: - - ```less - .secret() { - font-size: 6000px; - } - - .div { - .secret; - } - ``` - -If the mixin doesn't need any arguments, you can leave off the parentheses when -mixing it in, as seen above. - -You can also mixin a block that is nested inside other blocks. You can think of -the outer block as a way of making a scope for your mixins. You just list the -names of the mixins separated by spaces, which describes the path to the mixin -you want to include. Optionally you can separate them by `>`. - - ```less - .my_scope { - .some_color { - color: red; - .inner_block { - text-decoration: underline; - } - } - .bold { - font-weight: bold; - color: blue; - } - } - - .a_block { - .my_scope .some_color; - .my_scope .some_color .inner_block; - } - - .another_block { - // the alternative syntax - .my_scope > .bold; - } - ``` - - -#### Mixin Arguments - -When declaring a mixin you can specify default values for each argument. Any -argument left out will be given the default value specified. Here's the -syntax: - -```less -.mix(@color: red, @height: 20px, @pad: 12px) { - border: 1px solid @color; - height: @height - @pad; - padding: @pad; -} - -.default1 { - .mix(); -} - -.default2 { - .mix(blue); -} - -.default3 { - .mix(blue, 40px, 5px); -} -``` - -Additionally, you can also call a mixin using the argument names, this is -useful if you want to replace a specific argument while having all the others -take the default regardless of what position the argument appears in. The -syntax looks something like this: - - -```lessbasic -div { - .my_mixin(@paddding: 4px); // @color and @height get default values - .my_mixin(@paddding: 4px, @height: 50px); // you can specify them in any order -} -``` - -You can also combine the ordered arguments with the named ones: - -```lessbasic -div { - // @color is blue, @padding is 4px, @height is default - .my_mixin(blue, @padding: 4px); -} -``` - -Mixin arguments can be delimited with either a `,` or `;`, but only one can be -active at once. This means that each argument is separated by either `,` or -`;`. By default `,` is the delimiter, in all the above examples we used a `,`. - -A problem arises though, sometimes CSS value lists are made up with commas. In -order to be able to pass a comma separated list literal we need to use `;` as -the delimiter. (You don't need to worry about this if your list is stored in a -variable) - -If a `;` appears anywhere in the argument list, then it will be used as the -argument delimiter, and all commas we be used as part of the argument values. - -Here's a basic example: - -```less -.fancy_mixin(@box_shadow, @color: blue) { - border: 1px solid @color; - box-shadow: @box_shadow; -} - - -div { - // two arguments passed separated by ; - .fancy_mixin(2px 2px, -2px -2px; red); -} - -pre { - // one argument passed, ends in ; - .fancy_mixin(inset 4px 4px, -2px 2px;); -} - -``` - -If we only want to pass a single comma separated value we still need to use -`;`, to do this we stick it on the end as demonstrated above. - - -#### `@arguments` Variable - -Within an mixin there is a special variable named `@arguments` that contains -all the arguments passed to the mixin along with any remaining arguments that -have default values. The value of the variable has all the values separated by -spaces. - -This useful for quickly assigning all the arguments: - - ```less - .box-shadow(@x, @y, @blur, @color) { - box-shadow: @arguments; - -webkit-box-shadow: @arguments; - -moz-box-shadow: @arguments; - } - .menu { - .box-shadow(1px, 1px, 5px, #aaa); - } - ``` - -In addition to the arguments passed to the mixin, `@arguments` will also include -remaining default values assigned by the mixin: - - - ```less - .border-mixin(@width, @style: solid, @color: black) { - border: @arguments; - } - - pre { - .border-mixin(4px, dotted); - } - - ``` - - -#### Pattern Matching - -When you *mix in* a mixin, all the available mixins of that name in the current -scope are checked to see if they match based on what was passed to the mixin -and how it was declared. - -The simplest case is matching by number of arguments. Only the mixins that -match the number of arguments passed in are used. - - ```less - .simple() { // matches no arguments - height: 10px; - } - - .simple(@a, @b) { // matches two arguments - color: red; - } - - .simple(@a) { // matches one argument - color: blue; - } - - div { - .simple(10); - } - - span { - .simple(10, 20); - } - ``` - -Whether an argument has default values is also taken into account when matching -based on number of arguments: - - ```less - // matches one or two arguments - .hello(@a, @b: blue) { - height: @a; - color: @b; - } - - .hello(@a, @b) { // matches only two - width: @a; - border-color: @b; - } - - .hello(@a) { // matches only one - padding: 1em; - } - - div { - .hello(10px); - } - - pre { - .hello(10px, yellow); - } - ``` - -Additionally, a *vararg* value can be used to further control how things are -matched. A mixin's argument list can optionally end in the special argument -named `...`. The `...` may match any number of arguments, including 0. - - ```less - // this will match any number of arguments - .first(...) { - color: blue; - } - - // matches at least 1 argument - .second(@arg, ...) { - height: 200px + @arg; - } - - div { .first("some", "args"); } - pre { .second(10px); } - ``` - -If you want to capture the values that get captured by the *vararg* you can -give it a variable name by putting it directly before the `...`. This variable -must be the last argument defined. It's value is just like the special -[`@arguments` variable](#arguments_variable), a space separated list. - - - ```less - .hello(@first, @rest...) { - color: @first; - text-shadow: @rest; - } - - span { - .hello(red, 1px, 1px, 0px, white); - } - - ``` - -Another way of controlling whether a mixin matches is by specifying a value in -place of an argument name when declaring the mixin: - - ```less - .style(old, @size) { - font: @size serif; - } - - .style(new, @size) { - font: @size sans-serif; - } - - .style(@_, @size) { - letter-spacing: floor(@size / 6px); - } - - em { - @switch: old; - .style(@switch, 15px); - } - ``` - -Notice that two of the three mixins were matched. The mixin with a matching -first argument, and the generic mixin that matches two arguments. It's common -to use `@_` as the name of a variable we intend to not use. It has no special -meaning to LESS, just to the reader of the code. - -#### Guards - -Another way of restricting when a mixin is mixed in is by using guards. A guard -is a special expression that is associated with a mixin declaration that is -evaluated during the mixin process. It must evaluate to true before the mixin -can be used. - -We use the `when` keyword to begin describing a list of guard expressions. - -Here's a simple example: - - ```less - .guarded(@arg) when (@arg = hello) { - color: blue; - } - - div { - .guarded(hello); // match - } - - span { - .guarded(world); // no match - } - ``` -Only the `div`'s mixin will match in this case, because the guard expression -requires that `@arg` is equal to `hello`. - -We can include many different guard expressions by separating them by commas. -Only one of them needs to match to trigger the mixin: - - ```less - .x(@a, @b) when (@a = hello), (@b = world) { - width: 960px; - } - - div { - .x(hello, bar); // match - } - - span { - .x(foo, world); // match - } - - pre { - .x(foo, bar); // no match - } - ``` - -Instead of a comma, we can use `and` keyword to make it so all of the guards -must match in order to trigger the mixin. `and` has higher precedence than the -comma. - - ```less - .y(@a, @b) when (@a = hello) and (@b = world) { - height: 600px; - } - - div { - .y(hello, world); // match - } - - span { - .y(hello, bar); // no match - } - ``` - -Commas and `and`s can be mixed and matched. - -You can also negate a guard expression by using `not` in from of the parentheses: - - ```less - .x(@a) when not (@a = hello) { - color: blue; - } - - div { - .x(hello); // no match - } - ``` - -The `=` operator is used to check equality between any two values. For numbers -the following comparison operators are also defined: - -`<`, `>`, `=<`, `>=` - -There is also a collection of predicate functions that can be used to test the -type of a value. - -These are `isnumber`, `iscolor`, `iskeyword`, `isstring`, `ispixel`, -`ispercentage` and `isem`. - - ```less - .mix(@a) when (ispercentage(@a)) { - height: 500px * @a; - } - .mix(@a) when (ispixel(@a)) { - height: @a; - } - - div.a { - .mix(50%); - } - - div.a { - .mix(350px); - } - ``` - -#### !important - -If you want to apply the `!important` suffix to every property when mixing in a -mixin, just append `!important` to the end of the call to the mixin: - - ```less - .make_bright { - color: red; - font-weight: bold; - } - - .color { - color: green; - } - - body { - .make_bright() !important; - .color(); - } - - ``` - -### Selector Expressions - -Sometimes we want to dynamically generate the selector of a block based on some -variable or expression. We can do this by using *selector expressions*. Selector -expressions are CSS selectors that are evaluated in the current scope before -being written out. - -A simple example is a mixin that dynamically creates a selector named after the -mixin's argument: - - ```less - .create-selector(@name) { - @{name} { - color: red; - } - } - - .create-selector(hello); - .create-selector(world); - ``` - -The string interpolation syntax works inside of selectors, letting you insert varaibles. - -Here's an interesting example adapted from Twitter Bootstrap. A couple advanced -things are going on. We are using [Guards](#guards) along with a recursive -mixin to work like a loop to generate a series of CSS blocks. - - - ```less - // create our recursive mixin: - .spanX (@index) when (@index > 0) { - .span@{index} { - width: @index * 100px; - } - .spanX(@index - 1); - } - .spanX (0) {} - - // mix it into the global scopee: - .spanX(4); - ``` - -### Import - -Multiple LESS files can be compiled into a single CSS file by using the -`@import` statement. Be careful, the LESS import statement shares syntax with -the CSS import statement. If the file being imported ends in a `.less` -extension, or no extension, then it is treated as a LESS import. Otherwise it -is left alone and outputted directly: - - ```lessbasic - // my_file.less - .some-mixin(@height) { - height: @height; - } - - // main.less - @import "main.less" // will import the file if it can be found - @import "main.css" // will be left alone - - body { - .some-mixin(400px); - } - ``` - -All of the following lines are valid ways to import the same file: - - ```lessbasic - @import "file"; - @import 'file.less'; - @import url("file"); - @import url('file'); - @import url(file); - ``` - -When importing, the `importDir` is searched for files. This can be configured, -see [PHP Interface](#php_interface). - -A file is only imported once. If you try to include the same file multiple -times all the import statements after the first produce no output. - -### String Interpolation - -String interpolation is a convenient way to insert the value of a variable -right into a string literal. Given some variable named `@var_name`, you just -need to write it as `@{var_name}` from within the string to have its value -inserted: - - ```less - @symbol: ">"; - h1:before { - content: "@{symbol}: "; - } - - h2:before { - content: "@{symbol}@{symbol}: "; - } - ``` - -There are two kinds of strings, implicit and explicit strings. Explicit strings -are wrapped by double quotes, `"hello I am a string"`, or single quotes `'I am -another string'`. Implicit strings only appear when using `url()`. The text -between the parentheses is considered a string and thus string interpolation is -possible: - - ```less - @path: "files/"; - body { - background: url(@{path}my_background.png); - } - ``` - -### String Format Function - -The `%` function can be used to insert values into strings using a *format -string*. It works similar to `printf` seen in other languages. It has the -same purpose as string interpolation above, but gives explicit control over -the output format. - - ```less - @symbol: ">"; - h1:before { - content: %("%s: ", @symbol); - } - ``` - -The `%` function takes as its first argument the format string, following any -number of addition arguments that are inserted in place of the format -directives. - -A format directive starts with a `%` and is followed by a single character that -is either `a`, `d`, or `s`: - - ```less - strings: %("%a %d %s %a", hi, 1, 'ok', 'cool'); - ``` - -`%a` and `%d` format the value the same way: they compile the argument to its -CSS value and insert it directly. When used with a string, the quotes are -included in the output. This typically isn't what we want, so we have the `%s` -format directive which strips quotes from strings before inserting them. - -The `%d` directive functions the same as `%a`, but is typically used for numbers -assuming the output format of numbers might change in the future. - -### String Unquoting - -Sometimes you will need to write proprietary CSS syntax that is unable to be -parsed. As a workaround you can place the code into a string and unquote it. -Unquoting is the process of outputting a string without its surrounding quotes. -There are two ways to unquote a string. - -The `~` operator in front of a string will unquote that string: - - ```less - .class { - // a made up, but problematic vendor specific CSS - filter: ~"Microsoft.AlphaImage(src='image.png')"; - } - ``` - -If you are working with other types, such as variables, there is a built in -function that let's you unquote any value. It is called `e`. - - ```less - @color: "red"; - .class { - color: e(@color); - } - ``` - -### Built In Functions - -**lessphp** has a collection of built in functions: - -* `e(str)` -- returns a string without the surrounding quotes. - See [String Unquoting](#string_unquoting) - -* `floor(number)` -- returns the floor of a numerical input -* `round(number, [precision])` -- returns the rounded value of numerical input with optional precision - -* `lighten(color, percent)` -- lightens `color` by `percent` and returns it -* `darken(color, percent)` -- darkens `color` by `percent` and returns it - -* `saturate(color, percent)` -- saturates `color` by `percent` and returns it -* `desaturate(color, percent)` -- desaturates `color` by `percent` and returns it - -* `fadein(color, percent)` -- makes `color` less transparent by `percent` and returns it -* `fadeout(color, percent)` -- makes `color` more transparent by `percent` and returns it - -* `spin(color, amount)` -- returns a color with `amount` degrees added to hue - -* `fade(color, amount)` -- returns a color with the alpha set to `amount` - -* `hue(color)` -- returns the hue of `color` - -* `saturation(color)` -- returns the saturation of `color` - -* `lightness(color)` -- returns the lightness of `color` - -* `alpha(color)` -- returns the alpha value of `color` or 1.0 if it doesn't have an alpha - -* `percentage(number)` -- converts a floating point number to a percentage, e.g. `0.65` -> `65%` - -* `mix(color1, color1, percent)` -- mixes two colors by percentage where 100% - keeps all of `color1`, and 0% keeps all of `color2`. Will take into account - the alpha of the colors if it exists. See - . - -* `contrast(color, dark, light)` -- if `color` has a lightness value greater - than 50% then `dark` is returned, otherwise return `light`. - -* `extract(list, index)` -- returns the `index`th item from `list`. The list is - `1` indexed, meaning the first item's index is 1, the second is 2, and etc. - -* `pow(base, exp)` -- returns `base` raised to the power of `exp` - -* `pi()` -- returns pi - -* `mod(a,b)` -- returns `a` modulus `b` - -* `tan(a)` -- returns tangent of `a` where `a` is in radians - -* `cos(a)` -- returns cosine of `a` where `a` is in radians - -* `sin(a)` -- returns sine of `a` where `a` is in radians - -* `atan(a)` -- returns arc tangent of `a` - -* `acos(a)` -- returns arc cosine of `a` - -* `asin(a)` -- returns arc sine of `a` - -* `sqrt(a)` -- returns square root of `a` - -* `rgbahex(color)` -- returns a string containing 4 part hex color. - - This is used to convert a CSS color into the hex format that IE's filter - method expects when working with an alpha component. - - ```less - .class { - @start: rgbahex(rgba(25, 34, 23, .5)); - @end: rgbahex(rgba(85, 74, 103, .6)); - // abridged example - -ms-filter: - e("gradient(start=@{start},end=@{end})"); - } - ``` - -## PHP Interface - -When working with **lessphp** from PHP, the typical flow is to create a new -instance of `lessc`, configure it how you like, then tell it to compile -something using one built in compile methods. - -Methods: - -* [`compile($string)`](#compiling[) -- Compile a string - -* [`compileFile($inFile, [$outFile])`](#compiling) -- Compile a file to another or return it - -* [`checkedCompile($inFile, $outFile)`](#compiling) -- Compile a file only if it's newer - -* [`cachedCompile($cacheOrFile, [$force])`](#compiling_automatically) -- Conditionally compile while tracking imports - -* [`setFormatter($formatterName)`](#output_formatting) -- Change how CSS output looks - -* [`setPreserveComments($keepComments)`](#preserving_comments) -- Change if comments are kept in output - -* [`registerFunction($name, $callable)`](#custom_functions) -- Add a custom function - -* [`unregisterFunction($name)`](#custom_functions) -- Remove a registered function - -* [`setVariables($vars)`](#setting_variables_from_php) -- Set a variable from PHP - -* [`unsetVariable($name)`](#setting_variables_from_php) -- Remove a PHP variable - -* [`setImportDir($dirs)`](#import_directory) -- Set the search path for imports - -* [`addImportDir($dir)`](#import_directory) -- Append directory to search path for imports - - -### Compiling - -The `compile` method compiles a string of LESS code to CSS. - - ```php - compile(".block { padding: 3 + 4px }"); - ``` - -The `compileFile` method reads and compiles a file. It will either return the -result or write it to the path specified by an optional second argument. - - ```php - echo $less->compileFile("input.less"); - ``` - -The `compileChecked` method is like `compileFile`, but it only compiles if the output -file doesn't exist or it's older than the input file: - - ```php - $less->checkedCompile("input.less", "output.css"); - ``` - -See [Compiling Automatically](#compiling_automatically) for a description of -the more advanced `cachedCompile` method. - -### Output Formatting - -Output formatting controls the indentation of the output CSS. Besides the -default formatter, two additional ones are included and it's also easy to make -your own. - -To use a formatter, the method `setFormatter` is used. Just -pass the name of the formatter: - - ```php - $less = new lessc; - - $less->setFormatter("compressed"); - echo $less->compile("div { color: lighten(blue, 10%) }"); - ``` - -In this example, the `compressed` formatter is used. The formatters are: - - * `lessjs` *(default)* -- Same style used in LESS for JavaScript - - * `compressed` -- Compresses all the unrequired whitespace - - * `classic` -- **lessphp**'s original formatter - -To revert to the default formatter, call `setFormatter` with a value of `null`. - -#### Custom Formatter - -The easiest way to customize the formatter is to create your own instance of an -existing formatter and alter its public properties before passing it off to -**lessphp**. The `setFormatter` method can also take an instance of a -formatter. - -Each of the formatter names corresponds to a class with `lessc_formatter_` -prepended in front of it. Here the classic formatter is customized to use tabs -instead of spaces: - - - ```php - $formatter = new lessc_formatter_classic; - $formatter->indentChar = "\t"; - - $less = new lessc; - $less->setFormatter($formatter); - echo $less->compileFile("myfile.less"); - ``` - -For more information about what can be configured with the formatter consult -the source code. - -### Preserving Comments - -By default, all comments in the source LESS file are stripped when compiling. -You might want to keep the `/* */` comments in the output though. For -example, bundling a license in the file. - -Enable or disable comment preservation by calling `setPreserveComments`: - - ```php - $less = new lessc; - $less->setPreserveComments(true); - echo $less->compile("/* hello! */"); - ``` - -Comments are disabled by default because there is additional overhead, and more -often than not they aren't needed. - - -### Compiling Automatically - -Often, you want to only compile a LESS file only if it has been modified since -last compile. This is very important because compiling is performance intensive -and you should avoid a recompile if it possible. - -The `checkedCompile` compile method will do just that. It will check if the -input file is newer than the output file, or if the output file doesn't exist -yet, and compile only then. - - ```php - $less->checkedCompile("input.less", "output.css"); - ``` - -There's a problem though. `checkedCompile` is very basic, it only checks the -input file's modification time. It is unaware of any files from `@import`. - - -For this reason we also have `cachedCompile`. It's slightly more complex, but -gives us the ability to check changes to all files including those imported. It -takes one argument, either the name of the file we want to compile, or an -existing *cache object*. Its return value is an updated cache object. - -If we don't have a cache object, then we call the function with the name of the -file to get the initial cache object. If we do have a cache object, then we -call the function with it. In both cases, an updated cache object is returned. - -The cache object keeps track of all the files that must be checked in order to -determine if a rebuild is required. - -The cache object is a plain PHP `array`. It stores the last time it compiled in -`$cache["updated"]` and output of the compile in `$cache["compiled"]`. - -Here we demonstrate creating an new cache object, then using it to see if we -have a recompiled version available to be written: - - - ```php - $inputFile = "myfile.less"; - $outputFile = "myfile.css"; - - $less = new lessc; - - // create a new cache object, and compile - $cache = $less->cachedCompile($inputFile); - - file_put_contents($outputFile, $cache["compiled"]); - - // the next time we run, write only if it has updated - $last_updated = $cache["updated"]; - $cache = $less->cachedCompile($cache); - if ($cache["updated"] > $last_updated) { - file_put_contents($outputFile, $cache["compiled"]); - } - - ``` - -In order for the system to fully work, we must save cache object between -requests. Because it's a plain PHP `array`, it's sufficient to -[`serialize`](http://php.net/serialize) it and save it the string somewhere -like a file or in persistent memory. - -An example with saving cache object to a file: - - ```php - function autoCompileLess($inputFile, $outputFile) { - // load the cache - $cacheFile = $inputFile.".cache"; - - if (file_exists($cacheFile)) { - $cache = unserialize(file_get_contents($cacheFile)); - } else { - $cache = $inputFile; - } - - $less = new lessc; - $newCache = $less->cachedCompile($cache); - - if (!is_array($cache) || $newCache["updated"] > $cache["updated"]) { - file_put_contents($cacheFile, serialize($newCache)); - file_put_contents($outputFile, $newCache['compiled']); - } - } - - autoCompileLess('myfile.less', 'myfile.css'); - ``` - -`cachedCompile` method takes an optional second argument, `$force`. Passing in -true will cause the input to always be recompiled. - -### Error Handling - -All of the compile methods will throw an `Exception` if the parsing fails or -there is a compile time error. Compile time errors include things like passing -incorrectly typed values for functions that expect specific things, like the -color manipulation functions. - - ```php - $less = new lessc; - try { - $less->compile("} invalid LESS }}}"); - } catch (Exception $ex) { - echo "lessphp fatal error: ".$ex->getMessage(); - } - ``` -### Setting Variables From PHP - -Before compiling any code you can set initial LESS variables from PHP. The -`setVariables` method lets us do this. It takes an associative array of names -to values. The values must be strings, and will be parsed into correct CSS -values. - - - ```php - $less = new lessc; - - $less->setVariables(array( - "color" => "red", - "base" => "960px" - )); - - echo $less->compile(".magic { color: @color; width: @base - 200; }"); - ``` - -If you need to unset a variable, the `unsetVariable` method is available. It -takes the name of the variable to unset. - - ```php - $less->unsetVariable("color"); - ``` - -Be aware that the value of the variable is a string containing a CSS value. So -if you want to pass a LESS string in, you're going to need two sets of quotes. -One for PHP and one for LESS. - - - ```php - $less->setVariables(array( - "url" => "'http://example.com.com/'" - )); - - echo $less->compile("body { background: url("@{url}/bg.png"); }"); - ``` - -### Import Directory - -When running the `@import` directive, an array of directories called the import -search path is searched through to find the file being asked for. - -By default, when using `compile`, the import search path just contains `""`, -which is equivalent to the current directory of the script. If `compileFile` is -used, then the directory of the file being compiled is used as the starting -import search path. - -Two methods are available for configuring the search path. - -`setImportDir` will overwrite the search path with its argument. If the value -isn't an array it will be converted to one. - - -In this example, `@import "colors";` will look for either -`assets/less/colors.less` or `assets/bootstrap/colors.less` in that order: - - ```php - $less->setImportDir(array("assets/less/", "assets/bootstrap")); - - echo $less->compile('@import "colors";'); - ``` - -`addImportDir` will append a single path to the import search path instead of -overwriting the whole thing. - - ```php - $less->addImportDir("public/stylesheets"); - ``` - -### Custom Functions - -**lessphp** has a simple extension interface where you can implement user -functions that will be exposed in LESS code during the compile. They can be a -little tricky though because you need to work with the **lessphp** type system. - -The two methods we are interested in are `registerFunction` and -`unregisterFunction`. `registerFunction` takes two arguments, a name and a -callable value. `unregisterFunction` just takes the name of an existing -function to remove. - -Here's an example that adds a function called `double` that doubles any numeric -argument: - - ```php - registerFunction("double", "lessphp_double"); - - // gives us a width of 800px - echo $less->compile("div { width: double(400px); }"); - ``` - -The second argument to `registerFunction` is any *callable value* that is -understood by [`call_user_func`](http://php.net/call_user_func). - -If we are using PHP 5.3 or above then we are free to pass a function literal -like so: - - ```php - $less->registerFunction("double", function($arg) { - list($type, $value, $unit) = $arg; - return array($type, $value*2, $unit); - }); - ``` - -Now let's talk about the `double` function itself. - -Although a little verbose, the implementation gives us some insight on the type -system. All values in **lessphp** are stored in an array where the 0th element -is a string representing the type, and the other elements make up the -associated data for that value. - -The best way to get an understanding of the system is to register is dummy -function which does a `var_dump` on the argument. Try passing the function -different values from LESS and see what the results are. - -The return value of the registered function must also be a **lessphp** type, -but if it is a string or numeric value, it will automatically be coerced into -an appropriate typed value. In our example, we reconstruct the value with our -modifications while making sure that we preserve the original type. - -The instance of **lessphp** itself is sent to the registered function as the -second argument in addition to the arguments array. - -## Command Line Interface - -**lessphp** comes with a command line script written in PHP that can be used to -invoke the compiler from the terminal. On Linux and OSX, all you need to do is -place `plessc` and `lessc.inc.php` somewhere in your PATH (or you can run it in -the current directory as well). On windows you'll need a copy of `php.exe` to -run the file. To compile a file, `input.less` to CSS, run: - - ```bash - $ plessc input.less - ``` - -To write to a file, redirect standard out: - - ```bash - $ plessc input.less > output.css - ``` - -To compile code directly on the command line: - - ```bash - $ plessc -r "@color: red; body { color: @color; }" - ``` - -To watch a file for changes, and compile it as needed, use the `-w` flag: - - ```bash - $ plessc -w input-file output-file - ``` - -Errors from watch mode are written to standard out. - - -## License - -Copyright (c) 2012 Leaf Corcoran, - -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. - - -*Also under GPL3 if required, see `LICENSE` file* - diff --git a/vendor/leafo/lessphp/lessc.inc.php b/vendor/leafo/lessphp/lessc.inc.php deleted file mode 100644 index 2292f219..00000000 --- a/vendor/leafo/lessphp/lessc.inc.php +++ /dev/null @@ -1,3768 +0,0 @@ - - * Licensed under MIT or GPLv3, see LICENSE - */ - - -/** - * The LESS compiler and parser. - * - * Converting LESS to CSS is a three stage process. The incoming file is parsed - * by `lessc_parser` into a syntax tree, then it is compiled into another tree - * representing the CSS structure by `lessc`. The CSS tree is fed into a - * formatter, like `lessc_formatter` which then outputs CSS as a string. - * - * During the first compile, all values are *reduced*, which means that their - * types are brought to the lowest form before being dump as strings. This - * handles math equations, variable dereferences, and the like. - * - * The `parse` function of `lessc` is the entry point. - * - * In summary: - * - * The `lessc` class creates an instance of the parser, feeds it LESS code, - * then transforms the resulting tree to a CSS tree. This class also holds the - * evaluation context, such as all available mixins and variables at any given - * time. - * - * The `lessc_parser` class is only concerned with parsing its input. - * - * The `lessc_formatter` takes a CSS tree, and dumps it to a formatted string, - * handling things like indentation. - */ -class lessc { - static public $VERSION = "v0.5.0"; - - static public $TRUE = array("keyword", "true"); - static public $FALSE = array("keyword", "false"); - - protected $libFunctions = array(); - protected $registeredVars = array(); - protected $preserveComments = false; - - public $vPrefix = '@'; // prefix of abstract properties - public $mPrefix = '$'; // prefix of abstract blocks - public $parentSelector = '&'; - - public $importDisabled = false; - public $importDir = ''; - - protected $numberPrecision = null; - - protected $allParsedFiles = array(); - - // set to the parser that generated the current line when compiling - // so we know how to create error messages - protected $sourceParser = null; - protected $sourceLoc = null; - - static protected $nextImportId = 0; // uniquely identify imports - - // attempts to find the path of an import url, returns null for css files - protected function findImport($url) { - foreach ((array)$this->importDir as $dir) { - $full = $dir.(substr($dir, -1) != '/' ? '/' : '').$url; - if ($this->fileExists($file = $full.'.less') || $this->fileExists($file = $full)) { - return $file; - } - } - - return null; - } - - protected function fileExists($name) { - return is_file($name); - } - - static public function compressList($items, $delim) { - if (!isset($items[1]) && isset($items[0])) return $items[0]; - else return array('list', $delim, $items); - } - - static public function preg_quote($what) { - return preg_quote($what, '/'); - } - - protected function tryImport($importPath, $parentBlock, $out) { - if ($importPath[0] == "function" && $importPath[1] == "url") { - $importPath = $this->flattenList($importPath[2]); - } - - $str = $this->coerceString($importPath); - if ($str === null) return false; - - $url = $this->compileValue($this->lib_e($str)); - - // don't import if it ends in css - if (substr_compare($url, '.css', -4, 4) === 0) return false; - - $realPath = $this->findImport($url); - - if ($realPath === null) return false; - - if ($this->importDisabled) { - return array(false, "/* import disabled */"); - } - - if (isset($this->allParsedFiles[realpath($realPath)])) { - return array(false, null); - } - - $this->addParsedFile($realPath); - $parser = $this->makeParser($realPath); - $root = $parser->parse(file_get_contents($realPath)); - - // set the parents of all the block props - foreach ($root->props as $prop) { - if ($prop[0] == "block") { - $prop[1]->parent = $parentBlock; - } - } - - // copy mixins into scope, set their parents - // bring blocks from import into current block - // TODO: need to mark the source parser these came from this file - foreach ($root->children as $childName => $child) { - if (isset($parentBlock->children[$childName])) { - $parentBlock->children[$childName] = array_merge( - $parentBlock->children[$childName], - $child); - } else { - $parentBlock->children[$childName] = $child; - } - } - - $pi = pathinfo($realPath); - $dir = $pi["dirname"]; - - list($top, $bottom) = $this->sortProps($root->props, true); - $this->compileImportedProps($top, $parentBlock, $out, $parser, $dir); - - return array(true, $bottom, $parser, $dir); - } - - protected function compileImportedProps($props, $block, $out, $sourceParser, $importDir) { - $oldSourceParser = $this->sourceParser; - - $oldImport = $this->importDir; - - // TODO: this is because the importDir api is stupid - $this->importDir = (array)$this->importDir; - array_unshift($this->importDir, $importDir); - - foreach ($props as $prop) { - $this->compileProp($prop, $block, $out); - } - - $this->importDir = $oldImport; - $this->sourceParser = $oldSourceParser; - } - - /** - * Recursively compiles a block. - * - * A block is analogous to a CSS block in most cases. A single LESS document - * is encapsulated in a block when parsed, but it does not have parent tags - * so all of it's children appear on the root level when compiled. - * - * Blocks are made up of props and children. - * - * Props are property instructions, array tuples which describe an action - * to be taken, eg. write a property, set a variable, mixin a block. - * - * The children of a block are just all the blocks that are defined within. - * This is used to look up mixins when performing a mixin. - * - * Compiling the block involves pushing a fresh environment on the stack, - * and iterating through the props, compiling each one. - * - * See lessc::compileProp() - * - */ - protected function compileBlock($block) { - switch ($block->type) { - case "root": - $this->compileRoot($block); - break; - case null: - $this->compileCSSBlock($block); - break; - case "media": - $this->compileMedia($block); - break; - case "directive": - $name = "@" . $block->name; - if (!empty($block->value)) { - $name .= " " . $this->compileValue($this->reduce($block->value)); - } - - $this->compileNestedBlock($block, array($name)); - break; - default: - $this->throwError("unknown block type: $block->type\n"); - } - } - - protected function compileCSSBlock($block) { - $env = $this->pushEnv(); - - $selectors = $this->compileSelectors($block->tags); - $env->selectors = $this->multiplySelectors($selectors); - $out = $this->makeOutputBlock(null, $env->selectors); - - $this->scope->children[] = $out; - $this->compileProps($block, $out); - - $block->scope = $env; // mixins carry scope with them! - $this->popEnv(); - } - - protected function compileMedia($media) { - $env = $this->pushEnv($media); - $parentScope = $this->mediaParent($this->scope); - - $query = $this->compileMediaQuery($this->multiplyMedia($env)); - - $this->scope = $this->makeOutputBlock($media->type, array($query)); - $parentScope->children[] = $this->scope; - - $this->compileProps($media, $this->scope); - - if (count($this->scope->lines) > 0) { - $orphanSelelectors = $this->findClosestSelectors(); - if (!is_null($orphanSelelectors)) { - $orphan = $this->makeOutputBlock(null, $orphanSelelectors); - $orphan->lines = $this->scope->lines; - array_unshift($this->scope->children, $orphan); - $this->scope->lines = array(); - } - } - - $this->scope = $this->scope->parent; - $this->popEnv(); - } - - protected function mediaParent($scope) { - while (!empty($scope->parent)) { - if (!empty($scope->type) && $scope->type != "media") { - break; - } - $scope = $scope->parent; - } - - return $scope; - } - - protected function compileNestedBlock($block, $selectors) { - $this->pushEnv($block); - $this->scope = $this->makeOutputBlock($block->type, $selectors); - $this->scope->parent->children[] = $this->scope; - - $this->compileProps($block, $this->scope); - - $this->scope = $this->scope->parent; - $this->popEnv(); - } - - protected function compileRoot($root) { - $this->pushEnv(); - $this->scope = $this->makeOutputBlock($root->type); - $this->compileProps($root, $this->scope); - $this->popEnv(); - } - - protected function compileProps($block, $out) { - foreach ($this->sortProps($block->props) as $prop) { - $this->compileProp($prop, $block, $out); - } - $out->lines = $this->deduplicate($out->lines); - } - - /** - * Deduplicate lines in a block. Comments are not deduplicated. If a - * duplicate rule is detected, the comments immediately preceding each - * occurence are consolidated. - */ - protected function deduplicate($lines) { - $unique = array(); - $comments = array(); - - foreach($lines as $line) { - if (strpos($line, '/*') === 0) { - $comments[] = $line; - continue; - } - if (!in_array($line, $unique)) { - $unique[] = $line; - } - array_splice($unique, array_search($line, $unique), 0, $comments); - $comments = array(); - } - return array_merge($unique, $comments); - } - - protected function sortProps($props, $split = false) { - $vars = array(); - $imports = array(); - $other = array(); - $stack = array(); - - foreach ($props as $prop) { - switch ($prop[0]) { - case "comment": - $stack[] = $prop; - break; - case "assign": - $stack[] = $prop; - if (isset($prop[1][0]) && $prop[1][0] == $this->vPrefix) { - $vars = array_merge($vars, $stack); - } else { - $other = array_merge($other, $stack); - } - $stack = array(); - break; - case "import": - $id = self::$nextImportId++; - $prop[] = $id; - $stack[] = $prop; - $imports = array_merge($imports, $stack); - $other[] = array("import_mixin", $id); - $stack = array(); - break; - default: - $stack[] = $prop; - $other = array_merge($other, $stack); - $stack = array(); - break; - } - } - $other = array_merge($other, $stack); - - if ($split) { - return array(array_merge($imports, $vars), $other); - } else { - return array_merge($imports, $vars, $other); - } - } - - protected function compileMediaQuery($queries) { - $compiledQueries = array(); - foreach ($queries as $query) { - $parts = array(); - foreach ($query as $q) { - switch ($q[0]) { - case "mediaType": - $parts[] = implode(" ", array_slice($q, 1)); - break; - case "mediaExp": - if (isset($q[2])) { - $parts[] = "($q[1]: " . - $this->compileValue($this->reduce($q[2])) . ")"; - } else { - $parts[] = "($q[1])"; - } - break; - case "variable": - $parts[] = $this->compileValue($this->reduce($q)); - break; - } - } - - if (count($parts) > 0) { - $compiledQueries[] = implode(" and ", $parts); - } - } - - $out = "@media"; - if (!empty($parts)) { - $out .= " " . - implode($this->formatter->selectorSeparator, $compiledQueries); - } - return $out; - } - - protected function multiplyMedia($env, $childQueries = null) { - if (is_null($env) || - !empty($env->block->type) && $env->block->type != "media") - { - return $childQueries; - } - - // plain old block, skip - if (empty($env->block->type)) { - return $this->multiplyMedia($env->parent, $childQueries); - } - - $out = array(); - $queries = $env->block->queries; - if (is_null($childQueries)) { - $out = $queries; - } else { - foreach ($queries as $parent) { - foreach ($childQueries as $child) { - $out[] = array_merge($parent, $child); - } - } - } - - return $this->multiplyMedia($env->parent, $out); - } - - protected function expandParentSelectors(&$tag, $replace) { - $parts = explode("$&$", $tag); - $count = 0; - foreach ($parts as &$part) { - $part = str_replace($this->parentSelector, $replace, $part, $c); - $count += $c; - } - $tag = implode($this->parentSelector, $parts); - return $count; - } - - protected function findClosestSelectors() { - $env = $this->env; - $selectors = null; - while ($env !== null) { - if (isset($env->selectors)) { - $selectors = $env->selectors; - break; - } - $env = $env->parent; - } - - return $selectors; - } - - - // multiply $selectors against the nearest selectors in env - protected function multiplySelectors($selectors) { - // find parent selectors - - $parentSelectors = $this->findClosestSelectors(); - if (is_null($parentSelectors)) { - // kill parent reference in top level selector - foreach ($selectors as &$s) { - $this->expandParentSelectors($s, ""); - } - - return $selectors; - } - - $out = array(); - foreach ($parentSelectors as $parent) { - foreach ($selectors as $child) { - $count = $this->expandParentSelectors($child, $parent); - - // don't prepend the parent tag if & was used - if ($count > 0) { - $out[] = trim($child); - } else { - $out[] = trim($parent . ' ' . $child); - } - } - } - - return $out; - } - - // reduces selector expressions - protected function compileSelectors($selectors) { - $out = array(); - - foreach ($selectors as $s) { - if (is_array($s)) { - list(, $value) = $s; - $out[] = trim($this->compileValue($this->reduce($value))); - } else { - $out[] = $s; - } - } - - return $out; - } - - protected function eq($left, $right) { - return $left == $right; - } - - protected function patternMatch($block, $orderedArgs, $keywordArgs) { - // match the guards if it has them - // any one of the groups must have all its guards pass for a match - if (!empty($block->guards)) { - $groupPassed = false; - foreach ($block->guards as $guardGroup) { - foreach ($guardGroup as $guard) { - $this->pushEnv(); - $this->zipSetArgs($block->args, $orderedArgs, $keywordArgs); - - $negate = false; - if ($guard[0] == "negate") { - $guard = $guard[1]; - $negate = true; - } - - $passed = $this->reduce($guard) == self::$TRUE; - if ($negate) $passed = !$passed; - - $this->popEnv(); - - if ($passed) { - $groupPassed = true; - } else { - $groupPassed = false; - break; - } - } - - if ($groupPassed) break; - } - - if (!$groupPassed) { - return false; - } - } - - if (empty($block->args)) { - return $block->isVararg || empty($orderedArgs) && empty($keywordArgs); - } - - $remainingArgs = $block->args; - if ($keywordArgs) { - $remainingArgs = array(); - foreach ($block->args as $arg) { - if ($arg[0] == "arg" && isset($keywordArgs[$arg[1]])) { - continue; - } - - $remainingArgs[] = $arg; - } - } - - $i = -1; // no args - // try to match by arity or by argument literal - foreach ($remainingArgs as $i => $arg) { - switch ($arg[0]) { - case "lit": - if (empty($orderedArgs[$i]) || !$this->eq($arg[1], $orderedArgs[$i])) { - return false; - } - break; - case "arg": - // no arg and no default value - if (!isset($orderedArgs[$i]) && !isset($arg[2])) { - return false; - } - break; - case "rest": - $i--; // rest can be empty - break 2; - } - } - - if ($block->isVararg) { - return true; // not having enough is handled above - } else { - $numMatched = $i + 1; - // greater than becuase default values always match - return $numMatched >= count($orderedArgs); - } - } - - protected function patternMatchAll($blocks, $orderedArgs, $keywordArgs, $skip=array()) { - $matches = null; - foreach ($blocks as $block) { - // skip seen blocks that don't have arguments - if (isset($skip[$block->id]) && !isset($block->args)) { - continue; - } - - if ($this->patternMatch($block, $orderedArgs, $keywordArgs)) { - $matches[] = $block; - } - } - - return $matches; - } - - // attempt to find blocks matched by path and args - protected function findBlocks($searchIn, $path, $orderedArgs, $keywordArgs, $seen=array()) { - if ($searchIn == null) return null; - if (isset($seen[$searchIn->id])) return null; - $seen[$searchIn->id] = true; - - $name = $path[0]; - - if (isset($searchIn->children[$name])) { - $blocks = $searchIn->children[$name]; - if (count($path) == 1) { - $matches = $this->patternMatchAll($blocks, $orderedArgs, $keywordArgs, $seen); - if (!empty($matches)) { - // This will return all blocks that match in the closest - // scope that has any matching block, like lessjs - return $matches; - } - } else { - $matches = array(); - foreach ($blocks as $subBlock) { - $subMatches = $this->findBlocks($subBlock, - array_slice($path, 1), $orderedArgs, $keywordArgs, $seen); - - if (!is_null($subMatches)) { - foreach ($subMatches as $sm) { - $matches[] = $sm; - } - } - } - - return count($matches) > 0 ? $matches : null; - } - } - if ($searchIn->parent === $searchIn) return null; - return $this->findBlocks($searchIn->parent, $path, $orderedArgs, $keywordArgs, $seen); - } - - // sets all argument names in $args to either the default value - // or the one passed in through $values - protected function zipSetArgs($args, $orderedValues, $keywordValues) { - $assignedValues = array(); - - $i = 0; - foreach ($args as $a) { - if ($a[0] == "arg") { - if (isset($keywordValues[$a[1]])) { - // has keyword arg - $value = $keywordValues[$a[1]]; - } elseif (isset($orderedValues[$i])) { - // has ordered arg - $value = $orderedValues[$i]; - $i++; - } elseif (isset($a[2])) { - // has default value - $value = $a[2]; - } else { - $this->throwError("Failed to assign arg " . $a[1]); - $value = null; // :( - } - - $value = $this->reduce($value); - $this->set($a[1], $value); - $assignedValues[] = $value; - } else { - // a lit - $i++; - } - } - - // check for a rest - $last = end($args); - if ($last[0] == "rest") { - $rest = array_slice($orderedValues, count($args) - 1); - $this->set($last[1], $this->reduce(array("list", " ", $rest))); - } - - // wow is this the only true use of PHP's + operator for arrays? - $this->env->arguments = $assignedValues + $orderedValues; - } - - // compile a prop and update $lines or $blocks appropriately - protected function compileProp($prop, $block, $out) { - // set error position context - $this->sourceLoc = isset($prop[-1]) ? $prop[-1] : -1; - - switch ($prop[0]) { - case 'assign': - list(, $name, $value) = $prop; - if ($name[0] == $this->vPrefix) { - $this->set($name, $value); - } else { - $out->lines[] = $this->formatter->property($name, - $this->compileValue($this->reduce($value))); - } - break; - case 'block': - list(, $child) = $prop; - $this->compileBlock($child); - break; - case 'mixin': - list(, $path, $args, $suffix) = $prop; - - $orderedArgs = array(); - $keywordArgs = array(); - foreach ((array)$args as $arg) { - $argval = null; - switch ($arg[0]) { - case "arg": - if (!isset($arg[2])) { - $orderedArgs[] = $this->reduce(array("variable", $arg[1])); - } else { - $keywordArgs[$arg[1]] = $this->reduce($arg[2]); - } - break; - - case "lit": - $orderedArgs[] = $this->reduce($arg[1]); - break; - default: - $this->throwError("Unknown arg type: " . $arg[0]); - } - } - - $mixins = $this->findBlocks($block, $path, $orderedArgs, $keywordArgs); - - if ($mixins === null) { - $this->throwError("{$prop[1][0]} is undefined"); - } - - foreach ($mixins as $mixin) { - if ($mixin === $block && !$orderedArgs) { - continue; - } - - $haveScope = false; - if (isset($mixin->parent->scope)) { - $haveScope = true; - $mixinParentEnv = $this->pushEnv(); - $mixinParentEnv->storeParent = $mixin->parent->scope; - } - - $haveArgs = false; - if (isset($mixin->args)) { - $haveArgs = true; - $this->pushEnv(); - $this->zipSetArgs($mixin->args, $orderedArgs, $keywordArgs); - } - - $oldParent = $mixin->parent; - if ($mixin != $block) $mixin->parent = $block; - - foreach ($this->sortProps($mixin->props) as $subProp) { - if ($suffix !== null && - $subProp[0] == "assign" && - is_string($subProp[1]) && - $subProp[1]{0} != $this->vPrefix) - { - $subProp[2] = array( - 'list', ' ', - array($subProp[2], array('keyword', $suffix)) - ); - } - - $this->compileProp($subProp, $mixin, $out); - } - - $mixin->parent = $oldParent; - - if ($haveArgs) $this->popEnv(); - if ($haveScope) $this->popEnv(); - } - - break; - case 'raw': - $out->lines[] = $prop[1]; - break; - case "directive": - list(, $name, $value) = $prop; - $out->lines[] = "@$name " . $this->compileValue($this->reduce($value)).';'; - break; - case "comment": - $out->lines[] = $prop[1]; - break; - case "import"; - list(, $importPath, $importId) = $prop; - $importPath = $this->reduce($importPath); - - if (!isset($this->env->imports)) { - $this->env->imports = array(); - } - - $result = $this->tryImport($importPath, $block, $out); - - $this->env->imports[$importId] = $result === false ? - array(false, "@import " . $this->compileValue($importPath).";") : - $result; - - break; - case "import_mixin": - list(,$importId) = $prop; - $import = $this->env->imports[$importId]; - if ($import[0] === false) { - if (isset($import[1])) { - $out->lines[] = $import[1]; - } - } else { - list(, $bottom, $parser, $importDir) = $import; - $this->compileImportedProps($bottom, $block, $out, $parser, $importDir); - } - - break; - default: - $this->throwError("unknown op: {$prop[0]}\n"); - } - } - - - /** - * Compiles a primitive value into a CSS property value. - * - * Values in lessphp are typed by being wrapped in arrays, their format is - * typically: - * - * array(type, contents [, additional_contents]*) - * - * The input is expected to be reduced. This function will not work on - * things like expressions and variables. - */ - public function compileValue($value) { - switch ($value[0]) { - case 'list': - // [1] - delimiter - // [2] - array of values - return implode($value[1], array_map(array($this, 'compileValue'), $value[2])); - case 'raw_color': - if (!empty($this->formatter->compressColors)) { - return $this->compileValue($this->coerceColor($value)); - } - return $value[1]; - case 'keyword': - // [1] - the keyword - return $value[1]; - case 'number': - list(, $num, $unit) = $value; - // [1] - the number - // [2] - the unit - if ($this->numberPrecision !== null) { - $num = round($num, $this->numberPrecision); - } - return $num . $unit; - case 'string': - // [1] - contents of string (includes quotes) - list(, $delim, $content) = $value; - foreach ($content as &$part) { - if (is_array($part)) { - $part = $this->compileValue($part); - } - } - return $delim . implode($content) . $delim; - case 'color': - // [1] - red component (either number or a %) - // [2] - green component - // [3] - blue component - // [4] - optional alpha component - list(, $r, $g, $b) = $value; - $r = round($r); - $g = round($g); - $b = round($b); - - if (count($value) == 5 && $value[4] != 1) { // rgba - return 'rgba('.$r.','.$g.','.$b.','.$value[4].')'; - } - - $h = sprintf("#%02x%02x%02x", $r, $g, $b); - - if (!empty($this->formatter->compressColors)) { - // Converting hex color to short notation (e.g. #003399 to #039) - if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) { - $h = '#' . $h[1] . $h[3] . $h[5]; - } - } - - return $h; - - case 'function': - list(, $name, $args) = $value; - return $name.'('.$this->compileValue($args).')'; - default: // assumed to be unit - $this->throwError("unknown value type: $value[0]"); - } - } - - protected function lib_pow($args) { - list($base, $exp) = $this->assertArgs($args, 2, "pow"); - return pow($this->assertNumber($base), $this->assertNumber($exp)); - } - - protected function lib_pi() { - return pi(); - } - - protected function lib_mod($args) { - list($a, $b) = $this->assertArgs($args, 2, "mod"); - return $this->assertNumber($a) % $this->assertNumber($b); - } - - protected function lib_tan($num) { - return tan($this->assertNumber($num)); - } - - protected function lib_sin($num) { - return sin($this->assertNumber($num)); - } - - protected function lib_cos($num) { - return cos($this->assertNumber($num)); - } - - protected function lib_atan($num) { - $num = atan($this->assertNumber($num)); - return array("number", $num, "rad"); - } - - protected function lib_asin($num) { - $num = asin($this->assertNumber($num)); - return array("number", $num, "rad"); - } - - protected function lib_acos($num) { - $num = acos($this->assertNumber($num)); - return array("number", $num, "rad"); - } - - protected function lib_sqrt($num) { - return sqrt($this->assertNumber($num)); - } - - protected function lib_extract($value) { - list($list, $idx) = $this->assertArgs($value, 2, "extract"); - $idx = $this->assertNumber($idx); - // 1 indexed - if ($list[0] == "list" && isset($list[2][$idx - 1])) { - return $list[2][$idx - 1]; - } - } - - protected function lib_isnumber($value) { - return $this->toBool($value[0] == "number"); - } - - protected function lib_isstring($value) { - return $this->toBool($value[0] == "string"); - } - - protected function lib_iscolor($value) { - return $this->toBool($this->coerceColor($value)); - } - - protected function lib_iskeyword($value) { - return $this->toBool($value[0] == "keyword"); - } - - protected function lib_ispixel($value) { - return $this->toBool($value[0] == "number" && $value[2] == "px"); - } - - protected function lib_ispercentage($value) { - return $this->toBool($value[0] == "number" && $value[2] == "%"); - } - - protected function lib_isem($value) { - return $this->toBool($value[0] == "number" && $value[2] == "em"); - } - - protected function lib_isrem($value) { - return $this->toBool($value[0] == "number" && $value[2] == "rem"); - } - - protected function lib_rgbahex($color) { - $color = $this->coerceColor($color); - if (is_null($color)) - $this->throwError("color expected for rgbahex"); - - return sprintf("#%02x%02x%02x%02x", - isset($color[4]) ? $color[4]*255 : 255, - $color[1],$color[2], $color[3]); - } - - protected function lib_argb($color){ - return $this->lib_rgbahex($color); - } - - /** - * Given an url, decide whether to output a regular link or the base64-encoded contents of the file - * - * @param array $value either an argument list (two strings) or a single string - * @return string formatted url(), either as a link or base64-encoded - */ - protected function lib_data_uri($value) { - $mime = ($value[0] === 'list') ? $value[2][0][2] : null; - $url = ($value[0] === 'list') ? $value[2][1][2][0] : $value[2][0]; - - $fullpath = $this->findImport($url); - - if($fullpath && ($fsize = filesize($fullpath)) !== false) { - // IE8 can't handle data uris larger than 32KB - if($fsize/1024 < 32) { - if(is_null($mime)) { - if(class_exists('finfo')) { // php 5.3+ - $finfo = new finfo(FILEINFO_MIME); - $mime = explode('; ', $finfo->file($fullpath)); - $mime = $mime[0]; - } elseif(function_exists('mime_content_type')) { // PHP 5.2 - $mime = mime_content_type($fullpath); - } - } - - if(!is_null($mime)) // fallback if the mime type is still unknown - $url = sprintf('data:%s;base64,%s', $mime, base64_encode(file_get_contents($fullpath))); - } - } - - return 'url("'.$url.'")'; - } - - // utility func to unquote a string - protected function lib_e($arg) { - switch ($arg[0]) { - case "list": - $items = $arg[2]; - if (isset($items[0])) { - return $this->lib_e($items[0]); - } - $this->throwError("unrecognised input"); - case "string": - $arg[1] = ""; - return $arg; - case "keyword": - return $arg; - default: - return array("keyword", $this->compileValue($arg)); - } - } - - protected function lib__sprintf($args) { - if ($args[0] != "list") return $args; - $values = $args[2]; - $string = array_shift($values); - $template = $this->compileValue($this->lib_e($string)); - - $i = 0; - if (preg_match_all('/%[dsa]/', $template, $m)) { - foreach ($m[0] as $match) { - $val = isset($values[$i]) ? - $this->reduce($values[$i]) : array('keyword', ''); - - // lessjs compat, renders fully expanded color, not raw color - if ($color = $this->coerceColor($val)) { - $val = $color; - } - - $i++; - $rep = $this->compileValue($this->lib_e($val)); - $template = preg_replace('/'.self::preg_quote($match).'/', - $rep, $template, 1); - } - } - - $d = $string[0] == "string" ? $string[1] : '"'; - return array("string", $d, array($template)); - } - - protected function lib_floor($arg) { - $value = $this->assertNumber($arg); - return array("number", floor($value), $arg[2]); - } - - protected function lib_ceil($arg) { - $value = $this->assertNumber($arg); - return array("number", ceil($value), $arg[2]); - } - - protected function lib_round($arg) { - if($arg[0] != "list") { - $value = $this->assertNumber($arg); - return array("number", round($value), $arg[2]); - } else { - $value = $this->assertNumber($arg[2][0]); - $precision = $this->assertNumber($arg[2][1]); - return array("number", round($value, $precision), $arg[2][0][2]); - } - } - - protected function lib_unit($arg) { - if ($arg[0] == "list") { - list($number, $newUnit) = $arg[2]; - return array("number", $this->assertNumber($number), - $this->compileValue($this->lib_e($newUnit))); - } else { - return array("number", $this->assertNumber($arg), ""); - } - } - - /** - * Helper function to get arguments for color manipulation functions. - * takes a list that contains a color like thing and a percentage - */ - public function colorArgs($args) { - if ($args[0] != 'list' || count($args[2]) < 2) { - return array(array('color', 0, 0, 0), 0); - } - list($color, $delta) = $args[2]; - $color = $this->assertColor($color); - $delta = floatval($delta[1]); - - return array($color, $delta); - } - - protected function lib_darken($args) { - list($color, $delta) = $this->colorArgs($args); - - $hsl = $this->toHSL($color); - $hsl[3] = $this->clamp($hsl[3] - $delta, 100); - return $this->toRGB($hsl); - } - - protected function lib_lighten($args) { - list($color, $delta) = $this->colorArgs($args); - - $hsl = $this->toHSL($color); - $hsl[3] = $this->clamp($hsl[3] + $delta, 100); - return $this->toRGB($hsl); - } - - protected function lib_saturate($args) { - list($color, $delta) = $this->colorArgs($args); - - $hsl = $this->toHSL($color); - $hsl[2] = $this->clamp($hsl[2] + $delta, 100); - return $this->toRGB($hsl); - } - - protected function lib_desaturate($args) { - list($color, $delta) = $this->colorArgs($args); - - $hsl = $this->toHSL($color); - $hsl[2] = $this->clamp($hsl[2] - $delta, 100); - return $this->toRGB($hsl); - } - - protected function lib_spin($args) { - list($color, $delta) = $this->colorArgs($args); - - $hsl = $this->toHSL($color); - - $hsl[1] = $hsl[1] + $delta % 360; - if ($hsl[1] < 0) $hsl[1] += 360; - - return $this->toRGB($hsl); - } - - protected function lib_fadeout($args) { - list($color, $delta) = $this->colorArgs($args); - $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) - $delta/100); - return $color; - } - - protected function lib_fadein($args) { - list($color, $delta) = $this->colorArgs($args); - $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) + $delta/100); - return $color; - } - - protected function lib_hue($color) { - $hsl = $this->toHSL($this->assertColor($color)); - return round($hsl[1]); - } - - protected function lib_saturation($color) { - $hsl = $this->toHSL($this->assertColor($color)); - return round($hsl[2]); - } - - protected function lib_lightness($color) { - $hsl = $this->toHSL($this->assertColor($color)); - return round($hsl[3]); - } - - // get the alpha of a color - // defaults to 1 for non-colors or colors without an alpha - protected function lib_alpha($value) { - if (!is_null($color = $this->coerceColor($value))) { - return isset($color[4]) ? $color[4] : 1; - } - } - - // set the alpha of the color - protected function lib_fade($args) { - list($color, $alpha) = $this->colorArgs($args); - $color[4] = $this->clamp($alpha / 100.0); - return $color; - } - - protected function lib_percentage($arg) { - $num = $this->assertNumber($arg); - return array("number", $num*100, "%"); - } - - // mixes two colors by weight - // mix(@color1, @color2, [@weight: 50%]); - // http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method - protected function lib_mix($args) { - if ($args[0] != "list" || count($args[2]) < 2) - $this->throwError("mix expects (color1, color2, weight)"); - - list($first, $second) = $args[2]; - $first = $this->assertColor($first); - $second = $this->assertColor($second); - - $first_a = $this->lib_alpha($first); - $second_a = $this->lib_alpha($second); - - if (isset($args[2][2])) { - $weight = $args[2][2][1] / 100.0; - } else { - $weight = 0.5; - } - - $w = $weight * 2 - 1; - $a = $first_a - $second_a; - - $w1 = (($w * $a == -1 ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2.0; - $w2 = 1.0 - $w1; - - $new = array('color', - $w1 * $first[1] + $w2 * $second[1], - $w1 * $first[2] + $w2 * $second[2], - $w1 * $first[3] + $w2 * $second[3], - ); - - if ($first_a != 1.0 || $second_a != 1.0) { - $new[] = $first_a * $weight + $second_a * ($weight - 1); - } - - return $this->fixColor($new); - } - - protected function lib_contrast($args) { - $darkColor = array('color', 0, 0, 0); - $lightColor = array('color', 255, 255, 255); - $threshold = 0.43; - - if ( $args[0] == 'list' ) { - $inputColor = ( isset($args[2][0]) ) ? $this->assertColor($args[2][0]) : $lightColor; - $darkColor = ( isset($args[2][1]) ) ? $this->assertColor($args[2][1]) : $darkColor; - $lightColor = ( isset($args[2][2]) ) ? $this->assertColor($args[2][2]) : $lightColor; - $threshold = ( isset($args[2][3]) ) ? $this->assertNumber($args[2][3]) : $threshold; - } - else { - $inputColor = $this->assertColor($args); - } - - $inputColor = $this->coerceColor($inputColor); - $darkColor = $this->coerceColor($darkColor); - $lightColor = $this->coerceColor($lightColor); - - //Figure out which is actually light and dark! - if ( $this->lib_luma($darkColor) > $this->lib_luma($lightColor) ) { - $t = $lightColor; - $lightColor = $darkColor; - $darkColor = $t; - } - - $inputColor_alpha = $this->lib_alpha($inputColor); - if ( ( $this->lib_luma($inputColor) * $inputColor_alpha) < $threshold) { - return $lightColor; - } - return $darkColor; - } - - protected function lib_luma($color) { - $color = $this->coerceColor($color); - return (0.2126 * $color[0] / 255) + (0.7152 * $color[1] / 255) + (0.0722 * $color[2] / 255); - } - - - public function assertColor($value, $error = "expected color value") { - $color = $this->coerceColor($value); - if (is_null($color)) $this->throwError($error); - return $color; - } - - public function assertNumber($value, $error = "expecting number") { - if ($value[0] == "number") return $value[1]; - $this->throwError($error); - } - - public function assertArgs($value, $expectedArgs, $name="") { - if ($expectedArgs == 1) { - return $value; - } else { - if ($value[0] !== "list" || $value[1] != ",") $this->throwError("expecting list"); - $values = $value[2]; - $numValues = count($values); - if ($expectedArgs != $numValues) { - if ($name) { - $name = $name . ": "; - } - - $this->throwError("${name}expecting $expectedArgs arguments, got $numValues"); - } - - return $values; - } - } - - protected function toHSL($color) { - if ($color[0] == 'hsl') return $color; - - $r = $color[1] / 255; - $g = $color[2] / 255; - $b = $color[3] / 255; - - $min = min($r, $g, $b); - $max = max($r, $g, $b); - - $L = ($min + $max) / 2; - if ($min == $max) { - $S = $H = 0; - } else { - if ($L < 0.5) - $S = ($max - $min)/($max + $min); - else - $S = ($max - $min)/(2.0 - $max - $min); - - if ($r == $max) $H = ($g - $b)/($max - $min); - elseif ($g == $max) $H = 2.0 + ($b - $r)/($max - $min); - elseif ($b == $max) $H = 4.0 + ($r - $g)/($max - $min); - - } - - $out = array('hsl', - ($H < 0 ? $H + 6 : $H)*60, - $S*100, - $L*100, - ); - - if (count($color) > 4) $out[] = $color[4]; // copy alpha - return $out; - } - - protected function toRGB_helper($comp, $temp1, $temp2) { - if ($comp < 0) $comp += 1.0; - elseif ($comp > 1) $comp -= 1.0; - - if (6 * $comp < 1) return $temp1 + ($temp2 - $temp1) * 6 * $comp; - if (2 * $comp < 1) return $temp2; - if (3 * $comp < 2) return $temp1 + ($temp2 - $temp1)*((2/3) - $comp) * 6; - - return $temp1; - } - - /** - * Converts a hsl array into a color value in rgb. - * Expects H to be in range of 0 to 360, S and L in 0 to 100 - */ - protected function toRGB($color) { - if ($color[0] == 'color') return $color; - - $H = $color[1] / 360; - $S = $color[2] / 100; - $L = $color[3] / 100; - - if ($S == 0) { - $r = $g = $b = $L; - } else { - $temp2 = $L < 0.5 ? - $L*(1.0 + $S) : - $L + $S - $L * $S; - - $temp1 = 2.0 * $L - $temp2; - - $r = $this->toRGB_helper($H + 1/3, $temp1, $temp2); - $g = $this->toRGB_helper($H, $temp1, $temp2); - $b = $this->toRGB_helper($H - 1/3, $temp1, $temp2); - } - - // $out = array('color', round($r*255), round($g*255), round($b*255)); - $out = array('color', $r*255, $g*255, $b*255); - if (count($color) > 4) $out[] = $color[4]; // copy alpha - return $out; - } - - protected function clamp($v, $max = 1, $min = 0) { - return min($max, max($min, $v)); - } - - /** - * Convert the rgb, rgba, hsl color literals of function type - * as returned by the parser into values of color type. - */ - protected function funcToColor($func) { - $fname = $func[1]; - if ($func[2][0] != 'list') return false; // need a list of arguments - $rawComponents = $func[2][2]; - - if ($fname == 'hsl' || $fname == 'hsla') { - $hsl = array('hsl'); - $i = 0; - foreach ($rawComponents as $c) { - $val = $this->reduce($c); - $val = isset($val[1]) ? floatval($val[1]) : 0; - - if ($i == 0) $clamp = 360; - elseif ($i < 3) $clamp = 100; - else $clamp = 1; - - $hsl[] = $this->clamp($val, $clamp); - $i++; - } - - while (count($hsl) < 4) $hsl[] = 0; - return $this->toRGB($hsl); - - } elseif ($fname == 'rgb' || $fname == 'rgba') { - $components = array(); - $i = 1; - foreach ($rawComponents as $c) { - $c = $this->reduce($c); - if ($i < 4) { - if ($c[0] == "number" && $c[2] == "%") { - $components[] = 255 * ($c[1] / 100); - } else { - $components[] = floatval($c[1]); - } - } elseif ($i == 4) { - if ($c[0] == "number" && $c[2] == "%") { - $components[] = 1.0 * ($c[1] / 100); - } else { - $components[] = floatval($c[1]); - } - } else break; - - $i++; - } - while (count($components) < 3) $components[] = 0; - array_unshift($components, 'color'); - return $this->fixColor($components); - } - - return false; - } - - protected function reduce($value, $forExpression = false) { - switch ($value[0]) { - case "interpolate": - $reduced = $this->reduce($value[1]); - $var = $this->compileValue($reduced); - $res = $this->reduce(array("variable", $this->vPrefix . $var)); - - if ($res[0] == "raw_color") { - $res = $this->coerceColor($res); - } - - if (empty($value[2])) $res = $this->lib_e($res); - - return $res; - case "variable": - $key = $value[1]; - if (is_array($key)) { - $key = $this->reduce($key); - $key = $this->vPrefix . $this->compileValue($this->lib_e($key)); - } - - $seen =& $this->env->seenNames; - - if (!empty($seen[$key])) { - $this->throwError("infinite loop detected: $key"); - } - - $seen[$key] = true; - $out = $this->reduce($this->get($key)); - $seen[$key] = false; - return $out; - case "list": - foreach ($value[2] as &$item) { - $item = $this->reduce($item, $forExpression); - } - return $value; - case "expression": - return $this->evaluate($value); - case "string": - foreach ($value[2] as &$part) { - if (is_array($part)) { - $strip = $part[0] == "variable"; - $part = $this->reduce($part); - if ($strip) $part = $this->lib_e($part); - } - } - return $value; - case "escape": - list(,$inner) = $value; - return $this->lib_e($this->reduce($inner)); - case "function": - $color = $this->funcToColor($value); - if ($color) return $color; - - list(, $name, $args) = $value; - if ($name == "%") $name = "_sprintf"; - - $f = isset($this->libFunctions[$name]) ? - $this->libFunctions[$name] : array($this, 'lib_'.str_replace('-', '_', $name)); - - if (is_callable($f)) { - if ($args[0] == 'list') - $args = self::compressList($args[2], $args[1]); - - $ret = call_user_func($f, $this->reduce($args, true), $this); - - if (is_null($ret)) { - return array("string", "", array( - $name, "(", $args, ")" - )); - } - - // convert to a typed value if the result is a php primitive - if (is_numeric($ret)) $ret = array('number', $ret, ""); - elseif (!is_array($ret)) $ret = array('keyword', $ret); - - return $ret; - } - - // plain function, reduce args - $value[2] = $this->reduce($value[2]); - return $value; - case "unary": - list(, $op, $exp) = $value; - $exp = $this->reduce($exp); - - if ($exp[0] == "number") { - switch ($op) { - case "+": - return $exp; - case "-": - $exp[1] *= -1; - return $exp; - } - } - return array("string", "", array($op, $exp)); - } - - if ($forExpression) { - switch ($value[0]) { - case "keyword": - if ($color = $this->coerceColor($value)) { - return $color; - } - break; - case "raw_color": - return $this->coerceColor($value); - } - } - - return $value; - } - - - // coerce a value for use in color operation - protected function coerceColor($value) { - switch($value[0]) { - case 'color': return $value; - case 'raw_color': - $c = array("color", 0, 0, 0); - $colorStr = substr($value[1], 1); - $num = hexdec($colorStr); - $width = strlen($colorStr) == 3 ? 16 : 256; - - for ($i = 3; $i > 0; $i--) { // 3 2 1 - $t = $num % $width; - $num /= $width; - - $c[$i] = $t * (256/$width) + $t * floor(16/$width); - } - - return $c; - case 'keyword': - $name = $value[1]; - if (isset(self::$cssColors[$name])) { - $rgba = explode(',', self::$cssColors[$name]); - - if(isset($rgba[3])) - return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]); - - return array('color', $rgba[0], $rgba[1], $rgba[2]); - } - return null; - } - } - - // make something string like into a string - protected function coerceString($value) { - switch ($value[0]) { - case "string": - return $value; - case "keyword": - return array("string", "", array($value[1])); - } - return null; - } - - // turn list of length 1 into value type - protected function flattenList($value) { - if ($value[0] == "list" && count($value[2]) == 1) { - return $this->flattenList($value[2][0]); - } - return $value; - } - - public function toBool($a) { - if ($a) return self::$TRUE; - else return self::$FALSE; - } - - // evaluate an expression - protected function evaluate($exp) { - list(, $op, $left, $right, $whiteBefore, $whiteAfter) = $exp; - - $left = $this->reduce($left, true); - $right = $this->reduce($right, true); - - if ($leftColor = $this->coerceColor($left)) { - $left = $leftColor; - } - - if ($rightColor = $this->coerceColor($right)) { - $right = $rightColor; - } - - $ltype = $left[0]; - $rtype = $right[0]; - - // operators that work on all types - if ($op == "and") { - return $this->toBool($left == self::$TRUE && $right == self::$TRUE); - } - - if ($op == "=") { - return $this->toBool($this->eq($left, $right) ); - } - - if ($op == "+" && !is_null($str = $this->stringConcatenate($left, $right))) { - return $str; - } - - // type based operators - $fname = "op_${ltype}_${rtype}"; - if (is_callable(array($this, $fname))) { - $out = $this->$fname($op, $left, $right); - if (!is_null($out)) return $out; - } - - // make the expression look it did before being parsed - $paddedOp = $op; - if ($whiteBefore) $paddedOp = " " . $paddedOp; - if ($whiteAfter) $paddedOp .= " "; - - return array("string", "", array($left, $paddedOp, $right)); - } - - protected function stringConcatenate($left, $right) { - if ($strLeft = $this->coerceString($left)) { - if ($right[0] == "string") { - $right[1] = ""; - } - $strLeft[2][] = $right; - return $strLeft; - } - - if ($strRight = $this->coerceString($right)) { - array_unshift($strRight[2], $left); - return $strRight; - } - } - - - // make sure a color's components don't go out of bounds - protected function fixColor($c) { - foreach (range(1, 3) as $i) { - if ($c[$i] < 0) $c[$i] = 0; - if ($c[$i] > 255) $c[$i] = 255; - } - - return $c; - } - - protected function op_number_color($op, $lft, $rgt) { - if ($op == '+' || $op == '*') { - return $this->op_color_number($op, $rgt, $lft); - } - } - - protected function op_color_number($op, $lft, $rgt) { - if ($rgt[0] == '%') $rgt[1] /= 100; - - return $this->op_color_color($op, $lft, - array_fill(1, count($lft) - 1, $rgt[1])); - } - - protected function op_color_color($op, $left, $right) { - $out = array('color'); - $max = count($left) > count($right) ? count($left) : count($right); - foreach (range(1, $max - 1) as $i) { - $lval = isset($left[$i]) ? $left[$i] : 0; - $rval = isset($right[$i]) ? $right[$i] : 0; - switch ($op) { - case '+': - $out[] = $lval + $rval; - break; - case '-': - $out[] = $lval - $rval; - break; - case '*': - $out[] = $lval * $rval; - break; - case '%': - $out[] = $lval % $rval; - break; - case '/': - if ($rval == 0) $this->throwError("evaluate error: can't divide by zero"); - $out[] = $lval / $rval; - break; - default: - $this->throwError('evaluate error: color op number failed on op '.$op); - } - } - return $this->fixColor($out); - } - - function lib_red($color){ - $color = $this->coerceColor($color); - if (is_null($color)) { - $this->throwError('color expected for red()'); - } - - return $color[1]; - } - - function lib_green($color){ - $color = $this->coerceColor($color); - if (is_null($color)) { - $this->throwError('color expected for green()'); - } - - return $color[2]; - } - - function lib_blue($color){ - $color = $this->coerceColor($color); - if (is_null($color)) { - $this->throwError('color expected for blue()'); - } - - return $color[3]; - } - - - // operator on two numbers - protected function op_number_number($op, $left, $right) { - $unit = empty($left[2]) ? $right[2] : $left[2]; - - $value = 0; - switch ($op) { - case '+': - $value = $left[1] + $right[1]; - break; - case '*': - $value = $left[1] * $right[1]; - break; - case '-': - $value = $left[1] - $right[1]; - break; - case '%': - $value = $left[1] % $right[1]; - break; - case '/': - if ($right[1] == 0) $this->throwError('parse error: divide by zero'); - $value = $left[1] / $right[1]; - break; - case '<': - return $this->toBool($left[1] < $right[1]); - case '>': - return $this->toBool($left[1] > $right[1]); - case '>=': - return $this->toBool($left[1] >= $right[1]); - case '=<': - return $this->toBool($left[1] <= $right[1]); - default: - $this->throwError('parse error: unknown number operator: '.$op); - } - - return array("number", $value, $unit); - } - - - /* environment functions */ - - protected function makeOutputBlock($type, $selectors = null) { - $b = new stdclass; - $b->lines = array(); - $b->children = array(); - $b->selectors = $selectors; - $b->type = $type; - $b->parent = $this->scope; - return $b; - } - - // the state of execution - protected function pushEnv($block = null) { - $e = new stdclass; - $e->parent = $this->env; - $e->store = array(); - $e->block = $block; - - $this->env = $e; - return $e; - } - - // pop something off the stack - protected function popEnv() { - $old = $this->env; - $this->env = $this->env->parent; - return $old; - } - - // set something in the current env - protected function set($name, $value) { - $this->env->store[$name] = $value; - } - - - // get the highest occurrence entry for a name - protected function get($name) { - $current = $this->env; - - $isArguments = $name == $this->vPrefix . 'arguments'; - while ($current) { - if ($isArguments && isset($current->arguments)) { - return array('list', ' ', $current->arguments); - } - - if (isset($current->store[$name])) - return $current->store[$name]; - else { - $current = isset($current->storeParent) ? - $current->storeParent : $current->parent; - } - } - - $this->throwError("variable $name is undefined"); - } - - // inject array of unparsed strings into environment as variables - protected function injectVariables($args) { - $this->pushEnv(); - $parser = new lessc_parser($this, __METHOD__); - foreach ($args as $name => $strValue) { - if ($name{0} != '@') $name = '@'.$name; - $parser->count = 0; - $parser->buffer = (string)$strValue; - if (!$parser->propertyValue($value)) { - throw new Exception("failed to parse passed in variable $name: $strValue"); - } - - $this->set($name, $value); - } - } - - /** - * Initialize any static state, can initialize parser for a file - * $opts isn't used yet - */ - public function __construct($fname = null) { - if ($fname !== null) { - // used for deprecated parse method - $this->_parseFile = $fname; - } - } - - public function compile($string, $name = null) { - $locale = setlocale(LC_NUMERIC, 0); - setlocale(LC_NUMERIC, "C"); - - $this->parser = $this->makeParser($name); - $root = $this->parser->parse($string); - - $this->env = null; - $this->scope = null; - - $this->formatter = $this->newFormatter(); - - if (!empty($this->registeredVars)) { - $this->injectVariables($this->registeredVars); - } - - $this->sourceParser = $this->parser; // used for error messages - $this->compileBlock($root); - - ob_start(); - $this->formatter->block($this->scope); - $out = ob_get_clean(); - setlocale(LC_NUMERIC, $locale); - return $out; - } - - public function compileFile($fname, $outFname = null) { - if (!is_readable($fname)) { - throw new Exception('load error: failed to find '.$fname); - } - - $pi = pathinfo($fname); - - $oldImport = $this->importDir; - - $this->importDir = (array)$this->importDir; - $this->importDir[] = $pi['dirname'].'/'; - - $this->addParsedFile($fname); - - $out = $this->compile(file_get_contents($fname), $fname); - - $this->importDir = $oldImport; - - if ($outFname !== null) { - return file_put_contents($outFname, $out); - } - - return $out; - } - - // compile only if changed input has changed or output doesn't exist - public function checkedCompile($in, $out) { - if (!is_file($out) || filemtime($in) > filemtime($out)) { - $this->compileFile($in, $out); - return true; - } - return false; - } - - /** - * Execute lessphp on a .less file or a lessphp cache structure - * - * The lessphp cache structure contains information about a specific - * less file having been parsed. It can be used as a hint for future - * calls to determine whether or not a rebuild is required. - * - * The cache structure contains two important keys that may be used - * externally: - * - * compiled: The final compiled CSS - * updated: The time (in seconds) the CSS was last compiled - * - * The cache structure is a plain-ol' PHP associative array and can - * be serialized and unserialized without a hitch. - * - * @param mixed $in Input - * @param bool $force Force rebuild? - * @return array lessphp cache structure - */ - public function cachedCompile($in, $force = false) { - // assume no root - $root = null; - - if (is_string($in)) { - $root = $in; - } elseif (is_array($in) and isset($in['root'])) { - if ($force or ! isset($in['files'])) { - // If we are forcing a recompile or if for some reason the - // structure does not contain any file information we should - // specify the root to trigger a rebuild. - $root = $in['root']; - } elseif (isset($in['files']) and is_array($in['files'])) { - foreach ($in['files'] as $fname => $ftime ) { - if (!file_exists($fname) or filemtime($fname) > $ftime) { - // One of the files we knew about previously has changed - // so we should look at our incoming root again. - $root = $in['root']; - break; - } - } - } - } else { - // TODO: Throw an exception? We got neither a string nor something - // that looks like a compatible lessphp cache structure. - return null; - } - - if ($root !== null) { - // If we have a root value which means we should rebuild. - $out = array(); - $out['root'] = $root; - $out['compiled'] = $this->compileFile($root); - $out['files'] = $this->allParsedFiles(); - $out['updated'] = time(); - return $out; - } else { - // No changes, pass back the structure - // we were given initially. - return $in; - } - - } - - // parse and compile buffer - // This is deprecated - public function parse($str = null, $initialVariables = null) { - if (is_array($str)) { - $initialVariables = $str; - $str = null; - } - - $oldVars = $this->registeredVars; - if ($initialVariables !== null) { - $this->setVariables($initialVariables); - } - - if ($str == null) { - if (empty($this->_parseFile)) { - throw new exception("nothing to parse"); - } - - $out = $this->compileFile($this->_parseFile); - } else { - $out = $this->compile($str); - } - - $this->registeredVars = $oldVars; - return $out; - } - - protected function makeParser($name) { - $parser = new lessc_parser($this, $name); - $parser->writeComments = $this->preserveComments; - - return $parser; - } - - public function setFormatter($name) { - $this->formatterName = $name; - } - - protected function newFormatter() { - $className = "lessc_formatter_lessjs"; - if (!empty($this->formatterName)) { - if (!is_string($this->formatterName)) - return $this->formatterName; - $className = "lessc_formatter_$this->formatterName"; - } - - return new $className; - } - - public function setPreserveComments($preserve) { - $this->preserveComments = $preserve; - } - - public function registerFunction($name, $func) { - $this->libFunctions[$name] = $func; - } - - public function unregisterFunction($name) { - unset($this->libFunctions[$name]); - } - - public function setVariables($variables) { - $this->registeredVars = array_merge($this->registeredVars, $variables); - } - - public function unsetVariable($name) { - unset($this->registeredVars[$name]); - } - - public function setImportDir($dirs) { - $this->importDir = (array)$dirs; - } - - public function addImportDir($dir) { - $this->importDir = (array)$this->importDir; - $this->importDir[] = $dir; - } - - public function allParsedFiles() { - return $this->allParsedFiles; - } - - public function addParsedFile($file) { - $this->allParsedFiles[realpath($file)] = filemtime($file); - } - - /** - * Uses the current value of $this->count to show line and line number - */ - public function throwError($msg = null) { - if ($this->sourceLoc >= 0) { - $this->sourceParser->throwError($msg, $this->sourceLoc); - } - throw new exception($msg); - } - - // compile file $in to file $out if $in is newer than $out - // returns true when it compiles, false otherwise - public static function ccompile($in, $out, $less = null) { - if ($less === null) { - $less = new self; - } - return $less->checkedCompile($in, $out); - } - - public static function cexecute($in, $force = false, $less = null) { - if ($less === null) { - $less = new self; - } - return $less->cachedCompile($in, $force); - } - - static protected $cssColors = array( - 'aliceblue' => '240,248,255', - 'antiquewhite' => '250,235,215', - 'aqua' => '0,255,255', - 'aquamarine' => '127,255,212', - 'azure' => '240,255,255', - 'beige' => '245,245,220', - 'bisque' => '255,228,196', - 'black' => '0,0,0', - 'blanchedalmond' => '255,235,205', - 'blue' => '0,0,255', - 'blueviolet' => '138,43,226', - 'brown' => '165,42,42', - 'burlywood' => '222,184,135', - 'cadetblue' => '95,158,160', - 'chartreuse' => '127,255,0', - 'chocolate' => '210,105,30', - 'coral' => '255,127,80', - 'cornflowerblue' => '100,149,237', - 'cornsilk' => '255,248,220', - 'crimson' => '220,20,60', - 'cyan' => '0,255,255', - 'darkblue' => '0,0,139', - 'darkcyan' => '0,139,139', - 'darkgoldenrod' => '184,134,11', - 'darkgray' => '169,169,169', - 'darkgreen' => '0,100,0', - 'darkgrey' => '169,169,169', - 'darkkhaki' => '189,183,107', - 'darkmagenta' => '139,0,139', - 'darkolivegreen' => '85,107,47', - 'darkorange' => '255,140,0', - 'darkorchid' => '153,50,204', - 'darkred' => '139,0,0', - 'darksalmon' => '233,150,122', - 'darkseagreen' => '143,188,143', - 'darkslateblue' => '72,61,139', - 'darkslategray' => '47,79,79', - 'darkslategrey' => '47,79,79', - 'darkturquoise' => '0,206,209', - 'darkviolet' => '148,0,211', - 'deeppink' => '255,20,147', - 'deepskyblue' => '0,191,255', - 'dimgray' => '105,105,105', - 'dimgrey' => '105,105,105', - 'dodgerblue' => '30,144,255', - 'firebrick' => '178,34,34', - 'floralwhite' => '255,250,240', - 'forestgreen' => '34,139,34', - 'fuchsia' => '255,0,255', - 'gainsboro' => '220,220,220', - 'ghostwhite' => '248,248,255', - 'gold' => '255,215,0', - 'goldenrod' => '218,165,32', - 'gray' => '128,128,128', - 'green' => '0,128,0', - 'greenyellow' => '173,255,47', - 'grey' => '128,128,128', - 'honeydew' => '240,255,240', - 'hotpink' => '255,105,180', - 'indianred' => '205,92,92', - 'indigo' => '75,0,130', - 'ivory' => '255,255,240', - 'khaki' => '240,230,140', - 'lavender' => '230,230,250', - 'lavenderblush' => '255,240,245', - 'lawngreen' => '124,252,0', - 'lemonchiffon' => '255,250,205', - 'lightblue' => '173,216,230', - 'lightcoral' => '240,128,128', - 'lightcyan' => '224,255,255', - 'lightgoldenrodyellow' => '250,250,210', - 'lightgray' => '211,211,211', - 'lightgreen' => '144,238,144', - 'lightgrey' => '211,211,211', - 'lightpink' => '255,182,193', - 'lightsalmon' => '255,160,122', - 'lightseagreen' => '32,178,170', - 'lightskyblue' => '135,206,250', - 'lightslategray' => '119,136,153', - 'lightslategrey' => '119,136,153', - 'lightsteelblue' => '176,196,222', - 'lightyellow' => '255,255,224', - 'lime' => '0,255,0', - 'limegreen' => '50,205,50', - 'linen' => '250,240,230', - 'magenta' => '255,0,255', - 'maroon' => '128,0,0', - 'mediumaquamarine' => '102,205,170', - 'mediumblue' => '0,0,205', - 'mediumorchid' => '186,85,211', - 'mediumpurple' => '147,112,219', - 'mediumseagreen' => '60,179,113', - 'mediumslateblue' => '123,104,238', - 'mediumspringgreen' => '0,250,154', - 'mediumturquoise' => '72,209,204', - 'mediumvioletred' => '199,21,133', - 'midnightblue' => '25,25,112', - 'mintcream' => '245,255,250', - 'mistyrose' => '255,228,225', - 'moccasin' => '255,228,181', - 'navajowhite' => '255,222,173', - 'navy' => '0,0,128', - 'oldlace' => '253,245,230', - 'olive' => '128,128,0', - 'olivedrab' => '107,142,35', - 'orange' => '255,165,0', - 'orangered' => '255,69,0', - 'orchid' => '218,112,214', - 'palegoldenrod' => '238,232,170', - 'palegreen' => '152,251,152', - 'paleturquoise' => '175,238,238', - 'palevioletred' => '219,112,147', - 'papayawhip' => '255,239,213', - 'peachpuff' => '255,218,185', - 'peru' => '205,133,63', - 'pink' => '255,192,203', - 'plum' => '221,160,221', - 'powderblue' => '176,224,230', - 'purple' => '128,0,128', - 'red' => '255,0,0', - 'rosybrown' => '188,143,143', - 'royalblue' => '65,105,225', - 'saddlebrown' => '139,69,19', - 'salmon' => '250,128,114', - 'sandybrown' => '244,164,96', - 'seagreen' => '46,139,87', - 'seashell' => '255,245,238', - 'sienna' => '160,82,45', - 'silver' => '192,192,192', - 'skyblue' => '135,206,235', - 'slateblue' => '106,90,205', - 'slategray' => '112,128,144', - 'slategrey' => '112,128,144', - 'snow' => '255,250,250', - 'springgreen' => '0,255,127', - 'steelblue' => '70,130,180', - 'tan' => '210,180,140', - 'teal' => '0,128,128', - 'thistle' => '216,191,216', - 'tomato' => '255,99,71', - 'transparent' => '0,0,0,0', - 'turquoise' => '64,224,208', - 'violet' => '238,130,238', - 'wheat' => '245,222,179', - 'white' => '255,255,255', - 'whitesmoke' => '245,245,245', - 'yellow' => '255,255,0', - 'yellowgreen' => '154,205,50' - ); -} - -// responsible for taking a string of LESS code and converting it into a -// syntax tree -class lessc_parser { - static protected $nextBlockId = 0; // used to uniquely identify blocks - - static protected $precedence = array( - '=<' => 0, - '>=' => 0, - '=' => 0, - '<' => 0, - '>' => 0, - - '+' => 1, - '-' => 1, - '*' => 2, - '/' => 2, - '%' => 2, - ); - - static protected $whitePattern; - static protected $commentMulti; - - static protected $commentSingle = "//"; - static protected $commentMultiLeft = "/*"; - static protected $commentMultiRight = "*/"; - - // regex string to match any of the operators - static protected $operatorString; - - // these properties will supress division unless it's inside parenthases - static protected $supressDivisionProps = - array('/border-radius$/i', '/^font$/i'); - - protected $blockDirectives = array("font-face", "keyframes", "page", "-moz-document", "viewport", "-moz-viewport", "-o-viewport", "-ms-viewport"); - protected $lineDirectives = array("charset"); - - /** - * if we are in parens we can be more liberal with whitespace around - * operators because it must evaluate to a single value and thus is less - * ambiguous. - * - * Consider: - * property1: 10 -5; // is two numbers, 10 and -5 - * property2: (10 -5); // should evaluate to 5 - */ - protected $inParens = false; - - // caches preg escaped literals - static protected $literalCache = array(); - - public function __construct($lessc, $sourceName = null) { - $this->eatWhiteDefault = true; - // reference to less needed for vPrefix, mPrefix, and parentSelector - $this->lessc = $lessc; - - $this->sourceName = $sourceName; // name used for error messages - - $this->writeComments = false; - - if (!self::$operatorString) { - self::$operatorString = - '('.implode('|', array_map(array('lessc', 'preg_quote'), - array_keys(self::$precedence))).')'; - - $commentSingle = lessc::preg_quote(self::$commentSingle); - $commentMultiLeft = lessc::preg_quote(self::$commentMultiLeft); - $commentMultiRight = lessc::preg_quote(self::$commentMultiRight); - - self::$commentMulti = $commentMultiLeft.'.*?'.$commentMultiRight; - self::$whitePattern = '/'.$commentSingle.'[^\n]*\s*|('.self::$commentMulti.')\s*|\s+/Ais'; - } - } - - public function parse($buffer) { - $this->count = 0; - $this->line = 1; - - $this->env = null; // block stack - $this->buffer = $this->writeComments ? $buffer : $this->removeComments($buffer); - $this->pushSpecialBlock("root"); - $this->eatWhiteDefault = true; - $this->seenComments = array(); - - // trim whitespace on head - // if (preg_match('/^\s+/', $this->buffer, $m)) { - // $this->line += substr_count($m[0], "\n"); - // $this->buffer = ltrim($this->buffer); - // } - $this->whitespace(); - - // parse the entire file - while (false !== $this->parseChunk()); - - if ($this->count != strlen($this->buffer)) - $this->throwError(); - - // TODO report where the block was opened - if ( !property_exists($this->env, 'parent') || !is_null($this->env->parent) ) - throw new exception('parse error: unclosed block'); - - return $this->env; - } - - /** - * Parse a single chunk off the head of the buffer and append it to the - * current parse environment. - * Returns false when the buffer is empty, or when there is an error. - * - * This function is called repeatedly until the entire document is - * parsed. - * - * This parser is most similar to a recursive descent parser. Single - * functions represent discrete grammatical rules for the language, and - * they are able to capture the text that represents those rules. - * - * Consider the function lessc::keyword(). (all parse functions are - * structured the same) - * - * The function takes a single reference argument. When calling the - * function it will attempt to match a keyword on the head of the buffer. - * If it is successful, it will place the keyword in the referenced - * argument, advance the position in the buffer, and return true. If it - * fails then it won't advance the buffer and it will return false. - * - * All of these parse functions are powered by lessc::match(), which behaves - * the same way, but takes a literal regular expression. Sometimes it is - * more convenient to use match instead of creating a new function. - * - * Because of the format of the functions, to parse an entire string of - * grammatical rules, you can chain them together using &&. - * - * But, if some of the rules in the chain succeed before one fails, then - * the buffer position will be left at an invalid state. In order to - * avoid this, lessc::seek() is used to remember and set buffer positions. - * - * Before parsing a chain, use $s = $this->seek() to remember the current - * position into $s. Then if a chain fails, use $this->seek($s) to - * go back where we started. - */ - protected function parseChunk() { - if (empty($this->buffer)) return false; - $s = $this->seek(); - - if ($this->whitespace()) { - return true; - } - - // setting a property - if ($this->keyword($key) && $this->assign() && - $this->propertyValue($value, $key) && $this->end()) - { - $this->append(array('assign', $key, $value), $s); - return true; - } else { - $this->seek($s); - } - - - // look for special css blocks - if ($this->literal('@', false)) { - $this->count--; - - // media - if ($this->literal('@media')) { - if (($this->mediaQueryList($mediaQueries) || true) - && $this->literal('{')) - { - $media = $this->pushSpecialBlock("media"); - $media->queries = is_null($mediaQueries) ? array() : $mediaQueries; - return true; - } else { - $this->seek($s); - return false; - } - } - - if ($this->literal("@", false) && $this->keyword($dirName)) { - if ($this->isDirective($dirName, $this->blockDirectives)) { - if (($this->openString("{", $dirValue, null, array(";")) || true) && - $this->literal("{")) - { - $dir = $this->pushSpecialBlock("directive"); - $dir->name = $dirName; - if (isset($dirValue)) $dir->value = $dirValue; - return true; - } - } elseif ($this->isDirective($dirName, $this->lineDirectives)) { - if ($this->propertyValue($dirValue) && $this->end()) { - $this->append(array("directive", $dirName, $dirValue)); - return true; - } - } - } - - $this->seek($s); - } - - // setting a variable - if ($this->variable($var) && $this->assign() && - $this->propertyValue($value) && $this->end()) - { - $this->append(array('assign', $var, $value), $s); - return true; - } else { - $this->seek($s); - } - - if ($this->import($importValue)) { - $this->append($importValue, $s); - return true; - } - - // opening parametric mixin - if ($this->tag($tag, true) && $this->argumentDef($args, $isVararg) && - ($this->guards($guards) || true) && - $this->literal('{')) - { - $block = $this->pushBlock($this->fixTags(array($tag))); - $block->args = $args; - $block->isVararg = $isVararg; - if (!empty($guards)) $block->guards = $guards; - return true; - } else { - $this->seek($s); - } - - // opening a simple block - if ($this->tags($tags) && $this->literal('{', false)) { - $tags = $this->fixTags($tags); - $this->pushBlock($tags); - return true; - } else { - $this->seek($s); - } - - // closing a block - if ($this->literal('}', false)) { - try { - $block = $this->pop(); - } catch (exception $e) { - $this->seek($s); - $this->throwError($e->getMessage()); - } - - $hidden = false; - if (is_null($block->type)) { - $hidden = true; - if (!isset($block->args)) { - foreach ($block->tags as $tag) { - if (!is_string($tag) || $tag{0} != $this->lessc->mPrefix) { - $hidden = false; - break; - } - } - } - - foreach ($block->tags as $tag) { - if (is_string($tag)) { - $this->env->children[$tag][] = $block; - } - } - } - - if (!$hidden) { - $this->append(array('block', $block), $s); - } - - // this is done here so comments aren't bundled into he block that - // was just closed - $this->whitespace(); - return true; - } - - // mixin - if ($this->mixinTags($tags) && - ($this->argumentDef($argv, $isVararg) || true) && - ($this->keyword($suffix) || true) && $this->end()) - { - $tags = $this->fixTags($tags); - $this->append(array('mixin', $tags, $argv, $suffix), $s); - return true; - } else { - $this->seek($s); - } - - // spare ; - if ($this->literal(';')) return true; - - return false; // got nothing, throw error - } - - protected function isDirective($dirname, $directives) { - // TODO: cache pattern in parser - $pattern = implode("|", - array_map(array("lessc", "preg_quote"), $directives)); - $pattern = '/^(-[a-z-]+-)?(' . $pattern . ')$/i'; - - return preg_match($pattern, $dirname); - } - - protected function fixTags($tags) { - // move @ tags out of variable namespace - foreach ($tags as &$tag) { - if ($tag{0} == $this->lessc->vPrefix) - $tag[0] = $this->lessc->mPrefix; - } - return $tags; - } - - // a list of expressions - protected function expressionList(&$exps) { - $values = array(); - - while ($this->expression($exp)) { - $values[] = $exp; - } - - if (count($values) == 0) return false; - - $exps = lessc::compressList($values, ' '); - return true; - } - - /** - * Attempt to consume an expression. - * @link http://en.wikipedia.org/wiki/Operator-precedence_parser#Pseudo-code - */ - protected function expression(&$out) { - if ($this->value($lhs)) { - $out = $this->expHelper($lhs, 0); - - // look for / shorthand - if (!empty($this->env->supressedDivision)) { - unset($this->env->supressedDivision); - $s = $this->seek(); - if ($this->literal("/") && $this->value($rhs)) { - $out = array("list", "", - array($out, array("keyword", "/"), $rhs)); - } else { - $this->seek($s); - } - } - - return true; - } - return false; - } - - /** - * recursively parse infix equation with $lhs at precedence $minP - */ - protected function expHelper($lhs, $minP) { - $this->inExp = true; - $ss = $this->seek(); - - while (true) { - $whiteBefore = isset($this->buffer[$this->count - 1]) && - ctype_space($this->buffer[$this->count - 1]); - - // If there is whitespace before the operator, then we require - // whitespace after the operator for it to be an expression - $needWhite = $whiteBefore && !$this->inParens; - - if ($this->match(self::$operatorString.($needWhite ? '\s' : ''), $m) && self::$precedence[$m[1]] >= $minP) { - if (!$this->inParens && isset($this->env->currentProperty) && $m[1] == "/" && empty($this->env->supressedDivision)) { - foreach (self::$supressDivisionProps as $pattern) { - if (preg_match($pattern, $this->env->currentProperty)) { - $this->env->supressedDivision = true; - break 2; - } - } - } - - - $whiteAfter = isset($this->buffer[$this->count - 1]) && - ctype_space($this->buffer[$this->count - 1]); - - if (!$this->value($rhs)) break; - - // peek for next operator to see what to do with rhs - if ($this->peek(self::$operatorString, $next) && self::$precedence[$next[1]] > self::$precedence[$m[1]]) { - $rhs = $this->expHelper($rhs, self::$precedence[$next[1]]); - } - - $lhs = array('expression', $m[1], $lhs, $rhs, $whiteBefore, $whiteAfter); - $ss = $this->seek(); - - continue; - } - - break; - } - - $this->seek($ss); - - return $lhs; - } - - // consume a list of values for a property - public function propertyValue(&$value, $keyName = null) { - $values = array(); - - if ($keyName !== null) $this->env->currentProperty = $keyName; - - $s = null; - while ($this->expressionList($v)) { - $values[] = $v; - $s = $this->seek(); - if (!$this->literal(',')) break; - } - - if ($s) $this->seek($s); - - if ($keyName !== null) unset($this->env->currentProperty); - - if (count($values) == 0) return false; - - $value = lessc::compressList($values, ', '); - return true; - } - - protected function parenValue(&$out) { - $s = $this->seek(); - - // speed shortcut - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "(") { - return false; - } - - $inParens = $this->inParens; - if ($this->literal("(") && - ($this->inParens = true) && $this->expression($exp) && - $this->literal(")")) - { - $out = $exp; - $this->inParens = $inParens; - return true; - } else { - $this->inParens = $inParens; - $this->seek($s); - } - - return false; - } - - // a single value - protected function value(&$value) { - $s = $this->seek(); - - // speed shortcut - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "-") { - // negation - if ($this->literal("-", false) && - (($this->variable($inner) && $inner = array("variable", $inner)) || - $this->unit($inner) || - $this->parenValue($inner))) - { - $value = array("unary", "-", $inner); - return true; - } else { - $this->seek($s); - } - } - - if ($this->parenValue($value)) return true; - if ($this->unit($value)) return true; - if ($this->color($value)) return true; - if ($this->func($value)) return true; - if ($this->string($value)) return true; - - if ($this->keyword($word)) { - $value = array('keyword', $word); - return true; - } - - // try a variable - if ($this->variable($var)) { - $value = array('variable', $var); - return true; - } - - // unquote string (should this work on any type? - if ($this->literal("~") && $this->string($str)) { - $value = array("escape", $str); - return true; - } else { - $this->seek($s); - } - - // css hack: \0 - if ($this->literal('\\') && $this->match('([0-9]+)', $m)) { - $value = array('keyword', '\\'.$m[1]); - return true; - } else { - $this->seek($s); - } - - return false; - } - - // an import statement - protected function import(&$out) { - if (!$this->literal('@import')) return false; - - // @import "something.css" media; - // @import url("something.css") media; - // @import url(something.css) media; - - if ($this->propertyValue($value)) { - $out = array("import", $value); - return true; - } - } - - protected function mediaQueryList(&$out) { - if ($this->genericList($list, "mediaQuery", ",", false)) { - $out = $list[2]; - return true; - } - return false; - } - - protected function mediaQuery(&$out) { - $s = $this->seek(); - - $expressions = null; - $parts = array(); - - if (($this->literal("only") && ($only = true) || $this->literal("not") && ($not = true) || true) && $this->keyword($mediaType)) { - $prop = array("mediaType"); - if (isset($only)) $prop[] = "only"; - if (isset($not)) $prop[] = "not"; - $prop[] = $mediaType; - $parts[] = $prop; - } else { - $this->seek($s); - } - - - if (!empty($mediaType) && !$this->literal("and")) { - // ~ - } else { - $this->genericList($expressions, "mediaExpression", "and", false); - if (is_array($expressions)) $parts = array_merge($parts, $expressions[2]); - } - - if (count($parts) == 0) { - $this->seek($s); - return false; - } - - $out = $parts; - return true; - } - - protected function mediaExpression(&$out) { - $s = $this->seek(); - $value = null; - if ($this->literal("(") && - $this->keyword($feature) && - ($this->literal(":") && $this->expression($value) || true) && - $this->literal(")")) - { - $out = array("mediaExp", $feature); - if ($value) $out[] = $value; - return true; - } elseif ($this->variable($variable)) { - $out = array('variable', $variable); - return true; - } - - $this->seek($s); - return false; - } - - // an unbounded string stopped by $end - protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null) { - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - - $stop = array("'", '"', "@{", $end); - $stop = array_map(array("lessc", "preg_quote"), $stop); - // $stop[] = self::$commentMulti; - - if (!is_null($rejectStrs)) { - $stop = array_merge($stop, $rejectStrs); - } - - $patt = '(.*?)('.implode("|", $stop).')'; - - $nestingLevel = 0; - - $content = array(); - while ($this->match($patt, $m, false)) { - if (!empty($m[1])) { - $content[] = $m[1]; - if ($nestingOpen) { - $nestingLevel += substr_count($m[1], $nestingOpen); - } - } - - $tok = $m[2]; - - $this->count-= strlen($tok); - if ($tok == $end) { - if ($nestingLevel == 0) { - break; - } else { - $nestingLevel--; - } - } - - if (($tok == "'" || $tok == '"') && $this->string($str)) { - $content[] = $str; - continue; - } - - if ($tok == "@{" && $this->interpolation($inter)) { - $content[] = $inter; - continue; - } - - if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) { - break; - } - - $content[] = $tok; - $this->count+= strlen($tok); - } - - $this->eatWhiteDefault = $oldWhite; - - if (count($content) == 0) return false; - - // trim the end - if (is_string(end($content))) { - $content[count($content) - 1] = rtrim(end($content)); - } - - $out = array("string", "", $content); - return true; - } - - protected function string(&$out) { - $s = $this->seek(); - if ($this->literal('"', false)) { - $delim = '"'; - } elseif ($this->literal("'", false)) { - $delim = "'"; - } else { - return false; - } - - $content = array(); - - // look for either ending delim , escape, or string interpolation - $patt = '([^\n]*?)(@\{|\\\\|' . - lessc::preg_quote($delim).')'; - - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - - while ($this->match($patt, $m, false)) { - $content[] = $m[1]; - if ($m[2] == "@{") { - $this->count -= strlen($m[2]); - if ($this->interpolation($inter, false)) { - $content[] = $inter; - } else { - $this->count += strlen($m[2]); - $content[] = "@{"; // ignore it - } - } elseif ($m[2] == '\\') { - $content[] = $m[2]; - if ($this->literal($delim, false)) { - $content[] = $delim; - } - } else { - $this->count -= strlen($delim); - break; // delim - } - } - - $this->eatWhiteDefault = $oldWhite; - - if ($this->literal($delim)) { - $out = array("string", $delim, $content); - return true; - } - - $this->seek($s); - return false; - } - - protected function interpolation(&$out) { - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = true; - - $s = $this->seek(); - if ($this->literal("@{") && - $this->openString("}", $interp, null, array("'", '"', ";")) && - $this->literal("}", false)) - { - $out = array("interpolate", $interp); - $this->eatWhiteDefault = $oldWhite; - if ($this->eatWhiteDefault) $this->whitespace(); - return true; - } - - $this->eatWhiteDefault = $oldWhite; - $this->seek($s); - return false; - } - - protected function unit(&$unit) { - // speed shortcut - if (isset($this->buffer[$this->count])) { - $char = $this->buffer[$this->count]; - if (!ctype_digit($char) && $char != ".") return false; - } - - if ($this->match('([0-9]+(?:\.[0-9]*)?|\.[0-9]+)([%a-zA-Z]+)?', $m)) { - $unit = array("number", $m[1], empty($m[2]) ? "" : $m[2]); - return true; - } - return false; - } - - // a # color - protected function color(&$out) { - if ($this->match('(#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3}))', $m)) { - if (strlen($m[1]) > 7) { - $out = array("string", "", array($m[1])); - } else { - $out = array("raw_color", $m[1]); - } - return true; - } - - return false; - } - - // consume an argument definition list surrounded by () - // each argument is a variable name with optional value - // or at the end a ... or a variable named followed by ... - // arguments are separated by , unless a ; is in the list, then ; is the - // delimiter. - protected function argumentDef(&$args, &$isVararg) { - $s = $this->seek(); - if (!$this->literal('(')) return false; - - $values = array(); - $delim = ","; - $method = "expressionList"; - - $isVararg = false; - while (true) { - if ($this->literal("...")) { - $isVararg = true; - break; - } - - if ($this->$method($value)) { - if ($value[0] == "variable") { - $arg = array("arg", $value[1]); - $ss = $this->seek(); - - if ($this->assign() && $this->$method($rhs)) { - $arg[] = $rhs; - } else { - $this->seek($ss); - if ($this->literal("...")) { - $arg[0] = "rest"; - $isVararg = true; - } - } - - $values[] = $arg; - if ($isVararg) break; - continue; - } else { - $values[] = array("lit", $value); - } - } - - - if (!$this->literal($delim)) { - if ($delim == "," && $this->literal(";")) { - // found new delim, convert existing args - $delim = ";"; - $method = "propertyValue"; - - // transform arg list - if (isset($values[1])) { // 2 items - $newList = array(); - foreach ($values as $i => $arg) { - switch($arg[0]) { - case "arg": - if ($i) { - $this->throwError("Cannot mix ; and , as delimiter types"); - } - $newList[] = $arg[2]; - break; - case "lit": - $newList[] = $arg[1]; - break; - case "rest": - $this->throwError("Unexpected rest before semicolon"); - } - } - - $newList = array("list", ", ", $newList); - - switch ($values[0][0]) { - case "arg": - $newArg = array("arg", $values[0][1], $newList); - break; - case "lit": - $newArg = array("lit", $newList); - break; - } - - } elseif ($values) { // 1 item - $newArg = $values[0]; - } - - if ($newArg) { - $values = array($newArg); - } - } else { - break; - } - } - } - - if (!$this->literal(')')) { - $this->seek($s); - return false; - } - - $args = $values; - - return true; - } - - // consume a list of tags - // this accepts a hanging delimiter - protected function tags(&$tags, $simple = false, $delim = ',') { - $tags = array(); - while ($this->tag($tt, $simple)) { - $tags[] = $tt; - if (!$this->literal($delim)) break; - } - if (count($tags) == 0) return false; - - return true; - } - - // list of tags of specifying mixin path - // optionally separated by > (lazy, accepts extra >) - protected function mixinTags(&$tags) { - $tags = array(); - while ($this->tag($tt, true)) { - $tags[] = $tt; - $this->literal(">"); - } - - if (count($tags) == 0) return false; - - return true; - } - - // a bracketed value (contained within in a tag definition) - protected function tagBracket(&$parts, &$hasExpression) { - // speed shortcut - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") { - return false; - } - - $s = $this->seek(); - - $hasInterpolation = false; - - if ($this->literal("[", false)) { - $attrParts = array("["); - // keyword, string, operator - while (true) { - if ($this->literal("]", false)) { - $this->count--; - break; // get out early - } - - if ($this->match('\s+', $m)) { - $attrParts[] = " "; - continue; - } - if ($this->string($str)) { - // escape parent selector, (yuck) - foreach ($str[2] as &$chunk) { - $chunk = str_replace($this->lessc->parentSelector, "$&$", $chunk); - } - - $attrParts[] = $str; - $hasInterpolation = true; - continue; - } - - if ($this->keyword($word)) { - $attrParts[] = $word; - continue; - } - - if ($this->interpolation($inter, false)) { - $attrParts[] = $inter; - $hasInterpolation = true; - continue; - } - - // operator, handles attr namespace too - if ($this->match('[|-~\$\*\^=]+', $m)) { - $attrParts[] = $m[0]; - continue; - } - - break; - } - - if ($this->literal("]", false)) { - $attrParts[] = "]"; - foreach ($attrParts as $part) { - $parts[] = $part; - } - $hasExpression = $hasExpression || $hasInterpolation; - return true; - } - $this->seek($s); - } - - $this->seek($s); - return false; - } - - // a space separated list of selectors - protected function tag(&$tag, $simple = false) { - if ($simple) - $chars = '^@,:;{}\][>\(\) "\''; - else - $chars = '^@,;{}["\''; - - $s = $this->seek(); - - $hasExpression = false; - $parts = array(); - while ($this->tagBracket($parts, $hasExpression)); - - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - - while (true) { - if ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) { - $parts[] = $m[1]; - if ($simple) break; - - while ($this->tagBracket($parts, $hasExpression)); - continue; - } - - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") { - if ($this->interpolation($interp)) { - $hasExpression = true; - $interp[2] = true; // don't unescape - $parts[] = $interp; - continue; - } - - if ($this->literal("@")) { - $parts[] = "@"; - continue; - } - } - - if ($this->unit($unit)) { // for keyframes - $parts[] = $unit[1]; - $parts[] = $unit[2]; - continue; - } - - break; - } - - $this->eatWhiteDefault = $oldWhite; - if (!$parts) { - $this->seek($s); - return false; - } - - if ($hasExpression) { - $tag = array("exp", array("string", "", $parts)); - } else { - $tag = trim(implode($parts)); - } - - $this->whitespace(); - return true; - } - - // a css function - protected function func(&$func) { - $s = $this->seek(); - - if ($this->match('(%|[\w\-_][\w\-_:\.]+|[\w_])', $m) && $this->literal('(')) { - $fname = $m[1]; - - $sPreArgs = $this->seek(); - - $args = array(); - while (true) { - $ss = $this->seek(); - // this ugly nonsense is for ie filter properties - if ($this->keyword($name) && $this->literal('=') && $this->expressionList($value)) { - $args[] = array("string", "", array($name, "=", $value)); - } else { - $this->seek($ss); - if ($this->expressionList($value)) { - $args[] = $value; - } - } - - if (!$this->literal(',')) break; - } - $args = array('list', ',', $args); - - if ($this->literal(')')) { - $func = array('function', $fname, $args); - return true; - } elseif ($fname == 'url') { - // couldn't parse and in url? treat as string - $this->seek($sPreArgs); - if ($this->openString(")", $string) && $this->literal(")")) { - $func = array('function', $fname, $string); - return true; - } - } - } - - $this->seek($s); - return false; - } - - // consume a less variable - protected function variable(&$name) { - $s = $this->seek(); - if ($this->literal($this->lessc->vPrefix, false) && - ($this->variable($sub) || $this->keyword($name))) - { - if (!empty($sub)) { - $name = array('variable', $sub); - } else { - $name = $this->lessc->vPrefix.$name; - } - return true; - } - - $name = null; - $this->seek($s); - return false; - } - - /** - * Consume an assignment operator - * Can optionally take a name that will be set to the current property name - */ - protected function assign($name = null) { - if ($name) $this->currentProperty = $name; - return $this->literal(':') || $this->literal('='); - } - - // consume a keyword - protected function keyword(&$word) { - if ($this->match('([\w_\-\*!"][\w\-_"]*)', $m)) { - $word = $m[1]; - return true; - } - return false; - } - - // consume an end of statement delimiter - protected function end() { - if ($this->literal(';', false)) { - return true; - } elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') { - // if there is end of file or a closing block next then we don't need a ; - return true; - } - return false; - } - - protected function guards(&$guards) { - $s = $this->seek(); - - if (!$this->literal("when")) { - $this->seek($s); - return false; - } - - $guards = array(); - - while ($this->guardGroup($g)) { - $guards[] = $g; - if (!$this->literal(",")) break; - } - - if (count($guards) == 0) { - $guards = null; - $this->seek($s); - return false; - } - - return true; - } - - // a bunch of guards that are and'd together - // TODO rename to guardGroup - protected function guardGroup(&$guardGroup) { - $s = $this->seek(); - $guardGroup = array(); - while ($this->guard($guard)) { - $guardGroup[] = $guard; - if (!$this->literal("and")) break; - } - - if (count($guardGroup) == 0) { - $guardGroup = null; - $this->seek($s); - return false; - } - - return true; - } - - protected function guard(&$guard) { - $s = $this->seek(); - $negate = $this->literal("not"); - - if ($this->literal("(") && $this->expression($exp) && $this->literal(")")) { - $guard = $exp; - if ($negate) $guard = array("negate", $guard); - return true; - } - - $this->seek($s); - return false; - } - - /* raw parsing functions */ - - protected function literal($what, $eatWhitespace = null) { - if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault; - - // shortcut on single letter - if (!isset($what[1]) && isset($this->buffer[$this->count])) { - if ($this->buffer[$this->count] == $what) { - if (!$eatWhitespace) { - $this->count++; - return true; - } - // goes below... - } else { - return false; - } - } - - if (!isset(self::$literalCache[$what])) { - self::$literalCache[$what] = lessc::preg_quote($what); - } - - return $this->match(self::$literalCache[$what], $m, $eatWhitespace); - } - - protected function genericList(&$out, $parseItem, $delim="", $flatten=true) { - $s = $this->seek(); - $items = array(); - while ($this->$parseItem($value)) { - $items[] = $value; - if ($delim) { - if (!$this->literal($delim)) break; - } - } - - if (count($items) == 0) { - $this->seek($s); - return false; - } - - if ($flatten && count($items) == 1) { - $out = $items[0]; - } else { - $out = array("list", $delim, $items); - } - - return true; - } - - - // advance counter to next occurrence of $what - // $until - don't include $what in advance - // $allowNewline, if string, will be used as valid char set - protected function to($what, &$out, $until = false, $allowNewline = false) { - if (is_string($allowNewline)) { - $validChars = $allowNewline; - } else { - $validChars = $allowNewline ? "." : "[^\n]"; - } - if (!$this->match('('.$validChars.'*?)'.lessc::preg_quote($what), $m, !$until)) return false; - if ($until) $this->count -= strlen($what); // give back $what - $out = $m[1]; - return true; - } - - // try to match something on head of buffer - protected function match($regex, &$out, $eatWhitespace = null) { - if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault; - - $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Ais'; - if (preg_match($r, $this->buffer, $out, null, $this->count)) { - $this->count += strlen($out[0]); - if ($eatWhitespace && $this->writeComments) $this->whitespace(); - return true; - } - return false; - } - - // match some whitespace - protected function whitespace() { - if ($this->writeComments) { - $gotWhite = false; - while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) { - if (isset($m[1]) && empty($this->seenComments[$this->count])) { - $this->append(array("comment", $m[1])); - $this->seenComments[$this->count] = true; - } - $this->count += strlen($m[0]); - $gotWhite = true; - } - return $gotWhite; - } else { - $this->match("", $m); - return strlen($m[0]) > 0; - } - } - - // match something without consuming it - protected function peek($regex, &$out = null, $from=null) { - if (is_null($from)) $from = $this->count; - $r = '/'.$regex.'/Ais'; - $result = preg_match($r, $this->buffer, $out, null, $from); - - return $result; - } - - // seek to a spot in the buffer or return where we are on no argument - protected function seek($where = null) { - if ($where === null) return $this->count; - else $this->count = $where; - return true; - } - - /* misc functions */ - - public function throwError($msg = "parse error", $count = null) { - $count = is_null($count) ? $this->count : $count; - - $line = $this->line + - substr_count(substr($this->buffer, 0, $count), "\n"); - - if (!empty($this->sourceName)) { - $loc = "$this->sourceName on line $line"; - } else { - $loc = "line: $line"; - } - - // TODO this depends on $this->count - if ($this->peek("(.*?)(\n|$)", $m, $count)) { - throw new exception("$msg: failed at `$m[1]` $loc"); - } else { - throw new exception("$msg: $loc"); - } - } - - protected function pushBlock($selectors=null, $type=null) { - $b = new stdclass; - $b->parent = $this->env; - - $b->type = $type; - $b->id = self::$nextBlockId++; - - $b->isVararg = false; // TODO: kill me from here - $b->tags = $selectors; - - $b->props = array(); - $b->children = array(); - - $this->env = $b; - return $b; - } - - // push a block that doesn't multiply tags - protected function pushSpecialBlock($type) { - return $this->pushBlock(null, $type); - } - - // append a property to the current block - protected function append($prop, $pos = null) { - if ($pos !== null) $prop[-1] = $pos; - $this->env->props[] = $prop; - } - - // pop something off the stack - protected function pop() { - $old = $this->env; - $this->env = $this->env->parent; - return $old; - } - - // remove comments from $text - // todo: make it work for all functions, not just url - protected function removeComments($text) { - $look = array( - 'url(', '//', '/*', '"', "'" - ); - - $out = ''; - $min = null; - while (true) { - // find the next item - foreach ($look as $token) { - $pos = strpos($text, $token); - if ($pos !== false) { - if (!isset($min) || $pos < $min[1]) $min = array($token, $pos); - } - } - - if (is_null($min)) break; - - $count = $min[1]; - $skip = 0; - $newlines = 0; - switch ($min[0]) { - case 'url(': - if (preg_match('/url\(.*?\)/', $text, $m, 0, $count)) - $count += strlen($m[0]) - strlen($min[0]); - break; - case '"': - case "'": - if (preg_match('/'.$min[0].'.*?(?indentLevel = 0; - } - - public function indentStr($n = 0) { - return str_repeat($this->indentChar, max($this->indentLevel + $n, 0)); - } - - public function property($name, $value) { - return $name . $this->assignSeparator . $value . ";"; - } - - protected function isEmpty($block) { - if (empty($block->lines)) { - foreach ($block->children as $child) { - if (!$this->isEmpty($child)) return false; - } - - return true; - } - return false; - } - - public function block($block) { - if ($this->isEmpty($block)) return; - - $inner = $pre = $this->indentStr(); - - $isSingle = !$this->disableSingle && - is_null($block->type) && count($block->lines) == 1; - - if (!empty($block->selectors)) { - $this->indentLevel++; - - if ($this->breakSelectors) { - $selectorSeparator = $this->selectorSeparator . $this->break . $pre; - } else { - $selectorSeparator = $this->selectorSeparator; - } - - echo $pre . - implode($selectorSeparator, $block->selectors); - if ($isSingle) { - echo $this->openSingle; - $inner = ""; - } else { - echo $this->open . $this->break; - $inner = $this->indentStr(); - } - - } - - if (!empty($block->lines)) { - $glue = $this->break.$inner; - echo $inner . implode($glue, $block->lines); - if (!$isSingle && !empty($block->children)) { - echo $this->break; - } - } - - foreach ($block->children as $child) { - $this->block($child); - } - - if (!empty($block->selectors)) { - if (!$isSingle && empty($block->children)) echo $this->break; - - if ($isSingle) { - echo $this->closeSingle . $this->break; - } else { - echo $pre . $this->close . $this->break; - } - - $this->indentLevel--; - } - } -} - -class lessc_formatter_compressed extends lessc_formatter_classic { - public $disableSingle = true; - public $open = "{"; - public $selectorSeparator = ","; - public $assignSeparator = ":"; - public $break = ""; - public $compressColors = true; - - public function indentStr($n = 0) { - return ""; - } -} - -class lessc_formatter_lessjs extends lessc_formatter_classic { - public $disableSingle = true; - public $breakSelectors = true; - public $assignSeparator = ": "; - public $selectorSeparator = ","; -} - - diff --git a/vendor/leafo/lessphp/lessify b/vendor/leafo/lessphp/lessify deleted file mode 100644 index becc5388..00000000 --- a/vendor/leafo/lessphp/lessify +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/php -parse(); -} catch (exception $e) { - exit("Fatal error: ".$e->getMessage()."\n"); -} - - diff --git a/vendor/leafo/lessphp/lessify.inc.php b/vendor/leafo/lessphp/lessify.inc.php deleted file mode 100644 index 91c14423..00000000 --- a/vendor/leafo/lessphp/lessify.inc.php +++ /dev/null @@ -1,447 +0,0 @@ - - * - * WARNING: THIS DOES NOT WORK ANYMORE. NEEDS TO BE UPDATED FOR - * LATEST VERSION OF LESSPHP. - * - */ - -require "lessc.inc.php"; - -// -// check if the merge during mixin is overwriting values. should or should it not? -// - -// -// 1. split apart class tags -// - -class easyparse { - var $buffer; - var $count; - - function __construct($str) { - $this->count = 0; - $this->buffer = trim($str); - } - - function seek($where = null) { - if ($where === null) return $this->count; - else $this->count = $where; - return true; - } - - function preg_quote($what) { - return preg_quote($what, '/'); - } - - function match($regex, &$out, $eatWhitespace = true) { - $r = '/'.$regex.($eatWhitespace ? '\s*' : '').'/Ais'; - if (preg_match($r, $this->buffer, $out, null, $this->count)) { - $this->count += strlen($out[0]); - return true; - } - return false; - } - - function literal($what, $eatWhitespace = true) { - // this is here mainly prevent notice from { } string accessor - if ($this->count >= strlen($this->buffer)) return false; - - // shortcut on single letter - if (!$eatWhitespace and strlen($what) == 1) { - if ($this->buffer{$this->count} == $what) { - $this->count++; - return true; - } - else return false; - } - - return $this->match($this->preg_quote($what), $m, $eatWhitespace); - } - -} - -class tagparse extends easyparse { - static private $combinators = null; - static private $match_opts = null; - - function parse() { - if (empty(self::$combinators)) { - self::$combinators = '('.implode('|', array_map(array($this, 'preg_quote'), - array('+', '>', '~'))).')'; - self::$match_opts = '('.implode('|', array_map(array($this, 'preg_quote'), - array('=', '~=', '|=', '$=', '*='))).')'; - } - - // crush whitespace - $this->buffer = preg_replace('/\s+/', ' ', $this->buffer).' '; - - $tags = array(); - while ($this->tag($t)) $tags[] = $t; - - return $tags; - } - - static function compileString($string) { - list(, $delim, $str) = $string; - $str = str_replace($delim, "\\".$delim, $str); - $str = str_replace("\n", "\\\n", $str); - return $delim.$str.$delim; - } - - static function compilePaths($paths) { - return implode(', ', array_map(array('self', 'compilePath'), $paths)); - } - - // array of tags - static function compilePath($path) { - return implode(' ', array_map(array('self', 'compileTag'), $path)); - } - - - static function compileTag($tag) { - ob_start(); - if (isset($tag['comb'])) echo $tag['comb']." "; - if (isset($tag['front'])) echo $tag['front']; - if (isset($tag['attr'])) { - echo '['.$tag['attr']; - if (isset($tag['op'])) { - echo $tag['op'].$tag['op_value']; - } - echo ']'; - } - return ob_get_clean(); - } - - function string(&$out) { - $s = $this->seek(); - - if ($this->literal('"')) { - $delim = '"'; - } elseif ($this->literal("'")) { - $delim = "'"; - } else { - return false; - } - - while (true) { - // step through letters looking for either end or escape - $buff = ""; - $escapeNext = false; - $finished = false; - for ($i = $this->count; $i < strlen($this->buffer); $i++) { - $char = $this->buffer[$i]; - switch ($char) { - case $delim: - if ($escapeNext) { - $buff .= $char; - $escapeNext = false; - break; - } - $finished = true; - break 2; - case "\\": - if ($escapeNext) { - $buff .= $char; - $escapeNext = false; - } else { - $escapeNext = true; - } - break; - case "\n": - if (!$escapeNext) { - break 3; - } - - $buff .= $char; - $escapeNext = false; - break; - default: - if ($escapeNext) { - $buff .= "\\"; - $escapeNext = false; - } - $buff .= $char; - } - } - if (!$finished) break; - $out = array('string', $delim, $buff); - $this->seek($i+1); - return true; - } - - $this->seek($s); - return false; - } - - function tag(&$out) { - $s = $this->seek(); - $tag = array(); - if ($this->combinator($op)) $tag['comb'] = $op; - - if (!$this->match('(.*?)( |$|\[|'.self::$combinators.')', $match)) { - $this->seek($s); - return false; - } - - if (!empty($match[3])) { - // give back combinator - $this->count-=strlen($match[3]); - } - - if (!empty($match[1])) $tag['front'] = $match[1]; - - if ($match[2] == '[') { - if ($this->ident($i)) { - $tag['attr'] = $i; - - if ($this->match(self::$match_opts, $m) && $this->value($v)) { - $tag['op'] = $m[1]; - $tag['op_value'] = $v; - } - - if ($this->literal(']')) { - $out = $tag; - return true; - } - } - } elseif (isset($tag['front'])) { - $out = $tag; - return true; - } - - $this->seek($s); - return false; - } - - function ident(&$out) { - // [-]?{nmstart}{nmchar}* - // nmstart: [_a-z]|{nonascii}|{escape} - // nmchar: [_a-z0-9-]|{nonascii}|{escape} - if ($this->match('(-?[_a-z][_\w]*)', $m)) { - $out = $m[1]; - return true; - } - return false; - } - - function value(&$out) { - if ($this->string($str)) { - $out = $this->compileString($str); - return true; - } elseif ($this->ident($id)) { - $out = $id; - return true; - } - return false; - } - - - function combinator(&$op) { - if ($this->match(self::$combinators, $m)) { - $op = $m[1]; - return true; - } - return false; - } -} - -class nodecounter { - var $count = 0; - var $children = array(); - - var $name; - var $child_blocks; - var $the_block; - - function __construct($name) { - $this->name = $name; - } - - function dump($stack = null) { - if (is_null($stack)) $stack = array(); - $stack[] = $this->getName(); - echo implode(' -> ', $stack)." ($this->count)\n"; - foreach ($this->children as $child) { - $child->dump($stack); - } - } - - static function compileProperties($c, $block) { - foreach($block as $name => $value) { - if ($c->isProperty($name, $value)) { - echo $c->compileProperty($name, $value)."\n"; - } - } - } - - function compile($c, $path = null) { - if (is_null($path)) $path = array(); - $path[] = $this->name; - - $isVisible = !is_null($this->the_block) || !is_null($this->child_blocks); - - if ($isVisible) { - echo $c->indent(implode(' ', $path).' {'); - $c->indentLevel++; - $path = array(); - - if ($this->the_block) { - $this->compileProperties($c, $this->the_block); - } - - if ($this->child_blocks) { - foreach ($this->child_blocks as $block) { - echo $c->indent(tagparse::compilePaths($block['__tags']).' {'); - $c->indentLevel++; - $this->compileProperties($c, $block); - $c->indentLevel--; - echo $c->indent('}'); - } - } - } - - // compile child nodes - foreach($this->children as $node) { - $node->compile($c, $path); - } - - if ($isVisible) { - $c->indentLevel--; - echo $c->indent('}'); - } - - } - - function getName() { - if (is_null($this->name)) return "[root]"; - else return $this->name; - } - - function getNode($name) { - if (!isset($this->children[$name])) { - $this->children[$name] = new nodecounter($name); - } - - return $this->children[$name]; - } - - function findNode($path) { - $current = $this; - for ($i = 0; $i < count($path); $i++) { - $t = tagparse::compileTag($path[$i]); - $current = $current->getNode($t); - } - - return $current; - } - - function addBlock($path, $block) { - $node = $this->findNode($path); - if (!is_null($node->the_block)) throw new exception("can this happen?"); - - unset($block['__tags']); - $node->the_block = $block; - } - - function addToNode($path, $block) { - $node = $this->findNode($path); - $node->child_blocks[] = $block; - } -} - -/** - * create a less file from a css file by combining blocks where appropriate - */ -class lessify extends lessc { - public function dump() { - print_r($this->env); - } - - public function parse($str = null) { - $this->prepareParser($str ? $str : $this->buffer); - while (false !== $this->parseChunk()); - - $root = new nodecounter(null); - - // attempt to preserve some of the block order - $order = array(); - - $visitedTags = array(); - foreach (end($this->env) as $name => $block) { - if (!$this->isBlock($name, $block)) continue; - if (isset($visitedTags[$name])) continue; - - foreach ($block['__tags'] as $t) { - $visitedTags[$t] = true; - } - - // skip those with more than 1 - if (count($block['__tags']) == 1) { - $p = new tagparse(end($block['__tags'])); - $path = $p->parse(); - $root->addBlock($path, $block); - $order[] = array('compressed', $path, $block); - continue; - } else { - $common = null; - $paths = array(); - foreach ($block['__tags'] as $rawtag) { - $p = new tagparse($rawtag); - $paths[] = $path = $p->parse(); - if (is_null($common)) $common = $path; - else { - $new_common = array(); - foreach ($path as $tag) { - $head = array_shift($common); - if ($tag == $head) { - $new_common[] = $head; - } else break; - } - $common = $new_common; - if (empty($common)) { - // nothing in common - break; - } - } - } - - if (!empty($common)) { - $new_paths = array(); - foreach ($paths as $p) $new_paths[] = array_slice($p, count($common)); - $block['__tags'] = $new_paths; - $root->addToNode($common, $block); - $order[] = array('compressed', $common, $block); - continue; - } - - } - - $order[] = array('none', $block['__tags'], $block); - } - - - $compressed = $root->children; - foreach ($order as $item) { - list($type, $tags, $block) = $item; - if ($type == 'compressed') { - $top = tagparse::compileTag(reset($tags)); - if (isset($compressed[$top])) { - $compressed[$top]->compile($this); - unset($compressed[$top]); - } - } else { - echo $this->indent(implode(', ', $tags).' {'); - $this->indentLevel++; - nodecounter::compileProperties($this, $block); - $this->indentLevel--; - echo $this->indent('}'); - } - } - } -} diff --git a/vendor/leafo/lessphp/package.sh b/vendor/leafo/lessphp/package.sh deleted file mode 100644 index f0888f12..00000000 --- a/vendor/leafo/lessphp/package.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -# creates tar.gz for current version - -VERSION=`./plessc -v | sed -n 's/^v\(.*\)$/\1/p'` -OUT_DIR="tmp/lessphp" -TMP=`dirname $OUT_DIR` - -mkdir -p $OUT_DIR -tar -c `git ls-files` | tar -C $OUT_DIR -x - -rm $OUT_DIR/.gitignore -rm $OUT_DIR/package.sh -rm $OUT_DIR/lessify -rm $OUT_DIR/lessify.inc.php - -OUT_NAME="lessphp-$VERSION.tar.gz" -tar -czf $OUT_NAME -C $TMP lessphp/ -echo "Wrote $OUT_NAME" - -rm -r $TMP - - -echo -echo "Don't forget to" -echo "* Update the version in lessc.inc.php (two places)" -echo "* Update the version in the README.md" -echo "* Update the version in docs.md (two places)" -echo "* Update the version in LICENSE" -echo "* Update @current_version in site.moon" -echo "* Add entry to feed.moon for changelog" -echo "* Update the -New- area on homepage with date and features" -echo - - diff --git a/vendor/leafo/lessphp/plessc b/vendor/leafo/lessphp/plessc deleted file mode 100644 index 1871dc77..00000000 --- a/vendor/leafo/lessphp/plessc +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/env php -, 2013 - -$exe = array_shift($argv); // remove filename - -$HELP = << 0 && preg_match('/^-([-hvrwncXT]$|[f]=)/', $argv[0])) { - array_shift($argv); -} - -function has() { - global $opts; - foreach (func_get_args() as $arg) { - if (isset($opts[$arg])) return true; - } - return false; -} - -if (has("h", "help")) { - exit($HELP); -} - -error_reporting(E_ALL); -$path = realpath(dirname(__FILE__)).'/'; - -require $path."lessc.inc.php"; - -$VERSION = lessc::$VERSION; - -$fa = "Fatal Error: "; -function err($msg) { - fwrite(STDERR, $msg."\n"); -} - -if (php_sapi_name() != "cli") { - err($fa.$argv[0]." must be run in the command line."); - exit(1); -} - -function make_less($fname = null) { - global $opts; - $l = new lessc($fname); - - if (has("f")) { - $format = $opts["f"]; - if ($format != "default") $l->setFormatter($format); - } - - if (has("c")) { - $l->setPreserveComments(true); - } - - return $l; -} - -function process($data, $import = null) { - global $fa; - - $l = make_less(); - if ($import) $l->importDir = $import; - - try { - echo $l->parse($data); - exit(0); - } catch (exception $ex) { - err($fa."\n".str_repeat('=', 20)."\n". - $ex->getMessage()); - exit(1); - } -} - -if (has("v")) { - exit($VERSION."\n"); -} - -if (has("r")) { - if (!empty($argv)) { - $data = $argv[0]; - } else { - $data = ""; - while (!feof(STDIN)) { - $data .= fread(STDIN, 8192); - } - } - exit(process($data)); -} - -if (has("w")) { - // need two files - if (!is_file($in = array_shift($argv)) || - null == $out = array_shift($argv)) - { - err($fa.$exe." -w infile outfile"); - exit(1); - } - - echo "Watching ".$in. - (has("n") ? ' with notifications' : ''). - ", press Ctrl + c to exit.\n"; - - $cache = $in; - $last_action = 0; - while (true) { - clearstatcache(); - - // check if anything has changed since last fail - $updated = false; - if (is_array($cache)) { - foreach ($cache['files'] as $fname=>$_) { - if (filemtime($fname) > $last_action) { - $updated = true; - break; - } - } - } else $updated = true; - - // try to compile it - if ($updated) { - $last_action = time(); - - try { - $cache = lessc::cexecute($cache); - echo "Writing updated file: ".$out."\n"; - if (!file_put_contents($out, $cache['compiled'])) { - err($fa."Could not write to file ".$out); - exit(1); - } - } catch (exception $ex) { - echo "\nFatal Error:\n".str_repeat('=', 20)."\n". - $ex->getMessage()."\n\n"; - - if (has("n")) { - `notify-send -u critical "compile failed" "{$ex->getMessage()}"`; - } - } - } - - sleep(1); - } - exit(0); -} - -if (!$fname = array_shift($argv)) { - echo $HELP; - exit(1); -} - -function dumpValue($node, $depth = 0) { - if (is_object($node)) { - $indent = str_repeat(" ", $depth); - $out = array(); - foreach ($node->props as $prop) { - $out[] = $indent . dumpValue($prop, $depth + 1); - } - $out = implode("\n", $out); - if (!empty($node->tags)) { - $out = "+ ".implode(", ", $node->tags)."\n".$out; - } - return $out; - } elseif (is_array($node)) { - if (empty($node)) return "[]"; - $type = $node[0]; - if ($type == "block") - return dumpValue($node[1], $depth); - - $out = array(); - foreach ($node as $value) { - $out[] = dumpValue($value, $depth); - } - return "{ ".implode(", ", $out)." }"; - } else { - if (is_string($node) && preg_match("/[\s,]/", $node)) { - return '"'.$node.'"'; - } - return $node; // normal value - } -} - - -function stripValue($o, $toStrip) { - if (is_array($o) || is_object($o)) { - $isObject = is_object($o); - $o = (array)$o; - foreach ($toStrip as $removeKey) { - if (!empty($o[$removeKey])) { - $o[$removeKey] = "*stripped*"; - } - } - - foreach ($o as $k => $v) { - $o[$k] = stripValue($v, $toStrip); - } - - if ($isObject) { - $o = (object)$o; - } - } - - return $o; -} - -function dumpWithoutParent($o, $alsoStrip=array()) { - $toStrip = array_merge(array("parent"), $alsoStrip); - print_r(stripValue($o, $toStrip)); -} - -try { - $less = make_less($fname); - if (has("T", "X")) { - $parser = new lessc_parser($less, $fname); - $tree = $parser->parse(file_get_contents($fname)); - if (has("X")) - $out = print_r($tree, 1); - else - $out = dumpValue($tree)."\n"; - } else { - $out = $less->parse(); - } - - if (!$fout = array_shift($argv)) { - echo $out; - } else { - file_put_contents($fout, $out); - } - -} catch (exception $ex) { - err($fa.$ex->getMessage()); - exit(1); -} - -?> diff --git a/vendor/leafo/lessphp/tests/ApiTest.php b/vendor/leafo/lessphp/tests/ApiTest.php deleted file mode 100644 index fe1bbffa..00000000 --- a/vendor/leafo/lessphp/tests/ApiTest.php +++ /dev/null @@ -1,196 +0,0 @@ -less = new lessc(); - $this->less->importDir = array(__DIR__ . "/inputs/test-imports"); - } - - public function testPreserveComments() { - $input = <<assertEquals($this->compile($input), trim($outputWithoutComments)); - $this->less->setPreserveComments(true); - $this->assertEquals($this->compile($input), trim($outputWithComments)); - } - - public function testOldInterface() { - $this->less = new lessc(__DIR__ . "/inputs/hi.less"); - $out = $this->less->parse(array("hello" => "10px")); - $this->assertEquals(trim($out), trim(' -div:before { - content: "hi!"; -}')); - - } - - public function testInjectVars() { - $out = $this->less->parse(".magic { color: @color; width: @base - 200; }", - array( - 'color' => 'red', - 'base' => '960px' - )); - - $this->assertEquals(trim($out), trim(" -.magic { - color: red; - width: 760px; -}")); - - } - - public function testDisableImport() { - $this->less->importDisabled = true; - $this->assertEquals( - "/* import disabled */", - $this->compile("@import 'file3';")); - } - - public function testUserFunction() { - $this->less->registerFunction("add-two", function($list) { - list($a, $b) = $list[2]; - return $a[1] + $b[1]; - }); - - $this->assertEquals( - $this->compile("result: add-two(10, 20);"), - "result: 30;"); - - return $this->less; - } - - /** - * @depends testUserFunction - */ - public function testUnregisterFunction($less) { - $less->unregisterFunction("add-two"); - - $this->assertEquals( - $this->compile("result: add-two(10, 20);"), - "result: add-two(10,20);"); - } - - - - public function testFormatters() { - $src = " - div, pre { - color: blue; - span, .big, hello.world { - height: 20px; - color:#ffffff + #000; - } - }"; - - $this->less->setFormatter("compressed"); - $this->assertEquals( - $this->compile($src), "div,pre{color:blue;}div span,div .big,div hello.world,pre span,pre .big,pre hello.world{height:20px;color:#fff;}"); - - // TODO: fix the output order of tags - $this->less->setFormatter("lessjs"); - $this->assertEquals( - $this->compile($src), -"div, -pre { - color: blue; -} -div span, -div .big, -div hello.world, -pre span, -pre .big, -pre hello.world { - height: 20px; - color: #ffffff; -}"); - - $this->less->setFormatter("classic"); - $this->assertEquals( - $this->compile($src), -trim("div, pre { color:blue; } -div span, div .big, div hello.world, pre span, pre .big, pre hello.world { - height:20px; - color:#ffffff; -} -")); - - } - - public function compile($str) { - return trim($this->less->parse($str)); - } - -} diff --git a/vendor/leafo/lessphp/tests/ErrorHandlingTest.php b/vendor/leafo/lessphp/tests/ErrorHandlingTest.php deleted file mode 100644 index de02f065..00000000 --- a/vendor/leafo/lessphp/tests/ErrorHandlingTest.php +++ /dev/null @@ -1,81 +0,0 @@ -less = new lessc(); - } - - public function compile() { - $source = join("\n", func_get_args()); - return $this->less->compile($source); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage .parametric-mixin is undefined - */ - public function testRequiredParametersMissing() { - $this->compile( - '.parametric-mixin (@a, @b) { a: @a; b: @b; }', - '.selector { .parametric-mixin(12px); }' - ); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage .parametric-mixin is undefined - */ - public function testTooManyParameters() { - $this->compile( - '.parametric-mixin (@a, @b) { a: @a; b: @b; }', - '.selector { .parametric-mixin(12px, 13px, 14px); }' - ); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage unrecognised input - */ - public function testRequiredArgumentsMissing() { - $this->compile('.selector { rule: e(); }'); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage variable @missing is undefined - */ - public function testVariableMissing() { - $this->compile('.selector { rule: @missing; }'); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage .missing-mixin is undefined - */ - public function testMixinMissing() { - $this->compile('.selector { .missing-mixin; }'); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage .flipped is undefined - */ - public function testGuardUnmatchedValue() { - $this->compile( - '.flipped(@x) when (@x =< 10) { rule: value; }', - '.selector { .flipped(12); }' - ); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage .colors-only is undefined - */ - public function testGuardUnmatchedType() { - $this->compile( - '.colors-only(@x) when (iscolor(@x)) { rule: value; }', - '.selector { .colors-only("string value"); }' - ); - } -} diff --git a/vendor/leafo/lessphp/tests/InputTest.php b/vendor/leafo/lessphp/tests/InputTest.php deleted file mode 100644 index 32db95bc..00000000 --- a/vendor/leafo/lessphp/tests/InputTest.php +++ /dev/null @@ -1,89 +0,0 @@ - "outputs", - "inputs_lessjs" => "outputs_lessjs", - ); - - public function setUp() { - $this->less = new lessc(); - $this->less->importDir = array_map(function($path) { - return __DIR__ . "/" . $path; - }, self::$importDirs); - } - - /** - * @dataProvider fileNameProvider - */ - public function testInputFile($inFname) { - if ($pattern = getenv("BUILD")) { - return $this->buildInput($inFname); - } - - $outFname = self::outputNameFor($inFname); - - if (!is_readable($outFname)) { - $this->fail("$outFname is missing, ". - "consider building tests with BUILD=true"); - } - - $input = file_get_contents($inFname); - $output = file_get_contents($outFname); - - $this->assertEquals($output, $this->less->parse($input)); - } - - public function fileNameProvider() { - return array_map(function($a) { return array($a); }, - self::findInputNames()); - } - - // only run when env is set - public function buildInput($inFname) { - $css = $this->less->parse(file_get_contents($inFname)); - file_put_contents(self::outputNameFor($inFname), $css); - } - - static public function findInputNames($pattern="*.less") { - $files = array(); - foreach (self::$testDirs as $inputDir => $outputDir) { - $files = array_merge($files, glob(__DIR__ . "/" . $inputDir . "/" . $pattern)); - } - - return array_filter($files, "is_file"); - } - - static public function outputNameFor($input) { - $front = _quote(__DIR__ . "/"); - $out = preg_replace("/^$front/", "", $input); - - foreach (self::$testDirs as $inputDir => $outputDir) { - $in = _quote($inputDir . "/"); - $rewritten = preg_replace("/$in/", $outputDir . "/", $out); - if ($rewritten != $out) { - $out = $rewritten; - break; - } - } - - $out = preg_replace("/.less$/", ".css", $out); - - return __DIR__ . "/" . $out; - } -} - diff --git a/vendor/leafo/lessphp/tests/README.md b/vendor/leafo/lessphp/tests/README.md deleted file mode 100644 index 85a75c05..00000000 --- a/vendor/leafo/lessphp/tests/README.md +++ /dev/null @@ -1,24 +0,0 @@ -lessphp uses [phpunit](https://github.com/sebastianbergmann/phpunit/) for its tests - -* `InputTest.php` iterates through all the less files in `inputs/`, compiles - them, then compares the result with the respective file in `outputs/`. - -* `ApiTest.php` tests the behavior of lessphp's public API methods. - -* `ErrorHandlingTest.php` tests that lessphp throws appropriate errors when - given invalid LESS as input. - -From the root you can run `make` to run all the tests. - -## lessjs tests - -Tests found in `inputs_lessjs` are extracted directly from -[less.js](https://github.com/less/less.js). The following license applies to -those tests: https://github.com/less/less.js/blob/master/LICENSE - -## bootstrap.sh - -Clones twitter bootsrap, compiles it with lessc and lessphp, cleans up results -with sort.php, and outputs diff. To run it, you need to have git and lessc -installed. - diff --git a/vendor/leafo/lessphp/tests/bootstrap.sh b/vendor/leafo/lessphp/tests/bootstrap.sh deleted file mode 100644 index 18a90e87..00000000 --- a/vendor/leafo/lessphp/tests/bootstrap.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -echo "This script clones Twitter Bootstrap, compiles it with lessc and lessphp," -echo "cleans up results with sort.php, and outputs diff. To run it, you need to" -echo "have git and lessc installed." -echo "" - -if [ -z "$input" ]; then - input="bootstrap/less/bootstrap.less" -fi -dest=$(basename "$input") -dest="${dest%.*}" - -if [ -z "$@" ]; then - diff_tool="diff -b -u -t -B" -else - diff_tool=$@ -fi - -mkdir -p tmp - -if [ ! -d 'bootstrap/' ]; then - echo ">> Cloning bootstrap to bootstrap/" - git clone https://github.com/twbs/bootstrap -fi - -echo ">> lessc compilation ($input)" -lessc "$input" "tmp/$dest.lessc.css" - -echo ">> lessphp compilation ($input)" -../plessc "$input" "tmp/$dest.lessphp.css" -echo ">> Cleanup and convert" - -php sort.php "tmp/$dest.lessc.css" > "tmp/$dest.lessc.clean.css" -php sort.php "tmp/$dest.lessphp.css" > "tmp/$dest.lessphp.clean.css" - -echo ">> Doing diff" -$diff_tool "tmp/$dest.lessc.clean.css" "tmp/$dest.lessphp.clean.css" diff --git a/vendor/leafo/lessphp/tests/inputs/accessors.less.disable b/vendor/leafo/lessphp/tests/inputs/accessors.less.disable deleted file mode 100644 index 2990faab..00000000 --- a/vendor/leafo/lessphp/tests/inputs/accessors.less.disable +++ /dev/null @@ -1,36 +0,0 @@ -/* accessors */ - -#defaults { - @width: 960px; - @color: black; - .something { - @space: 10px; - @hello { - color: green; - } - } -} - -.article { color: #294366; } - -.comment { - width: #defaults[@width]; - color: .article['color']; - padding: #defaults > .something[@space]; -} - -.wow { - height: .comment['width']; - background-color: .comment['color']; - color: #defaults > .something > @hello['color']; - - padding: #defaults > non-existant['padding']; - margin: #defaults > .something['non-existant']; -} - -.mix { - #defaults; - font-size: .something[@space]; -} - - diff --git a/vendor/leafo/lessphp/tests/inputs/arity.less b/vendor/leafo/lessphp/tests/inputs/arity.less deleted file mode 100644 index 9998fd4a..00000000 --- a/vendor/leafo/lessphp/tests/inputs/arity.less +++ /dev/null @@ -1,77 +0,0 @@ - -// simple arity - -.hello(@a) { - hello: one; -} - -.hello(@a, @b) { - hello: two; -} - -.hello(@a, @b, @c) { - hello: three; -} - - -.world(@a, @b, @c) { - world: three; -} - -.world(@a, @b) { - world: two; -} - -.world(@a) { - world: one; -} - -.one { - .hello(1); - .world(1); -} - -.two { - .hello(1, 1); - .world(1, 1); -} - -.three { - .hello(1, 1, 1); - .world(1, 1, 1); -} - - -// arity with default values - -.foo(@a, @b: cool) { - foo: two @b; -} - -.foo(@a, @b: cool, @c: yeah) { - foo: three @b @c; -} - - -.baz(@a, @b, @c: yeah) { - baz: three @c; -} - -.baz(@a, @b: cool) { - baz: two @b; -} - - -.multi-foo { - .foo(1); - .foo(1, 1); - .foo(1,1,1); -} - -.multi-baz { - .baz(1); - .baz(1, 1); - .baz(1,1,1); -} - - diff --git a/vendor/leafo/lessphp/tests/inputs/attributes.less b/vendor/leafo/lessphp/tests/inputs/attributes.less deleted file mode 100644 index 7ede4fc4..00000000 --- a/vendor/leafo/lessphp/tests/inputs/attributes.less +++ /dev/null @@ -1,41 +0,0 @@ -* { color: blue; } -E { color: blue; } -E[foo] { color: blue; } -[foo] { color: blue; } -[foo] .helloWorld { color: blue; } -[foo].helloWorld { color: blue; } -E[foo="barbar"] { color: blue; } -E[foo~="hello#$@%@$#^"] { color: blue; } -E[foo^="color: green;"] { color: blue; } -E[foo$="239023"] { color: blue; } -E[foo*="29302"] { color: blue; } -E[foo|="239032"] { color: blue; } -E:root { color: blue; } - -E:nth-child(odd) { color: blue; } -E:nth-child(2n+1) { color: blue; } -E:nth-child(5) { color: blue; } -E:nth-last-child(-n+2) { color: blue; } -E:nth-of-type(2n) { color: blue; } -E:nth-last-of-type(n) { color: blue; } - -E:first-child { color: blue; } -E:last-child { color: blue; } -E:first-of-type { color: blue; } -E:last-of-type { color: blue; } -E:only-child { color: blue; } -E:only-of-type { color: blue; } -E:empty { color: blue; } - -E:lang(en) { color: blue; } -E::first-line { color: blue; } -E::before { color: blue; } - -E#id { color: blue; } -E:not(:link) { color: blue; } - -E F { color: blue; } -E > F { color: blue; } -E + F { color: blue; } -E ~ F { color: blue; } - diff --git a/vendor/leafo/lessphp/tests/inputs/builtins.less b/vendor/leafo/lessphp/tests/inputs/builtins.less deleted file mode 100644 index f9301e04..00000000 --- a/vendor/leafo/lessphp/tests/inputs/builtins.less +++ /dev/null @@ -1,96 +0,0 @@ -// builtin - -@something: "hello world"; -@color: #112233; -@color2: rgba(44,55,66, .6); - -body { - color: @something; - - @num: 7 / 6; - num-basic: @num + 4; - num-floor: floor(@num) + 4px; - num-ceil: ceil(@num) + 4px; - - @num2: 2 / 3; - num2: @num2; - num2-round: round(@num2); - num2-floor: floor(@num2); - num2-ceil: ceil(@num2); - - round-lit: round(10px / 3); - - rgba1: rgbahex(@color); - rgba2: rgbahex(@color2); - argb: argb(@color2); -} - - -format { - @r: 32; - format: %("rgb(%d, %d, %d)", @r, 128, 64); - format-string: %("hello %s", "world"); - format-multiple: %("hello %s %d", "earth", 2); - format-url-encode: %('red is %A', #ff0000); - eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64)); -} - - -#functions { - str1: isstring("hello"); - str2: isstring(one, two); - - num1: isnumber(2323px); - num2: isnumber(2323); - num3: isnumber(4/5); - num4: isnumber("hello"); - - col1: iscolor(red); - col2: iscolor(hello); - col3: iscolor(rgba(0,0,0,0.3)); - col4: iscolor(#fff); - - key1: iskeyword(hello); - key2: iskeyword(3D); - - px1: ispixel(10px); - px2: ispixel(10); - - per1: ispercentage(10%); - per2: ispercentage(10); - - em1: isem(10em); - em2: isem(10); - - ex1: extract(1 2 3 4, 2); - ex2: extract(1 2, 1); - ex3: extract(1, 1); - - @list: 1,2,3,4; - - ex4: extract(@list, 2); - - pow: pow(2,4); - pi: pi(); - mod: mod(14,10); - - tan: tan(1); - cos: cos(1); - sin: sin(1); - - atan: atan(1); - acos: acos(1); - asin: asin(1); - - sqrt: sqrt(8); -} - - -#unit { - @unit: "em"; - unit-lit: unit(10px); - unit-arg: unit(10px, "s"); - unit-arg2: unit(10px, @unit); - unit-math: unit(0.07407s) * 100%; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/colors.less b/vendor/leafo/lessphp/tests/inputs/colors.less deleted file mode 100644 index 7fd47a3c..00000000 --- a/vendor/leafo/lessphp/tests/inputs/colors.less +++ /dev/null @@ -1,154 +0,0 @@ - -body { - color:rgb(red(#f00), red(#0F0), red(#00f)); - color:rgb(red(#f00), green(#0F0), blue(#00f)); - color:rgb(red(#0ff), green(#f0f), blue(#ff0)); - - color: hsl(34, 50%, 40%); - color: hsla(34, 50%, 40%, 0.3); - - lighten1: lighten(#efefef, 10%); - lighten2: lighten(rgb(23, 53, 231), 22%); - lighten3: lighten(rgba(212, 103, 88, 0.5), 10%); - - darken1: darken(#efefef, 10%); - darken2: darken(rgb(23, 53, 231), 22%); - darken3: darken(rgba(23, 53, 231, 0.5), 10%); - - saturate1: saturate(#efefef, 10%); - saturate2: saturate(rgb(23, 53, 231), 22%); - saturate3: saturate(rgba(23, 53, 231, 0.5), 10%); - - desaturate1: desaturate(#efefef, 10%); - desaturate2: desaturate(rgb(23, 53, 231), 22%); - desaturate3: desaturate(rgba(23, 53, 231, 0.5), 10%); - - spin1: spin(#efefef, 12); - spin2: spin(rgb(23, 53, 231), 15); - spin3: spin(rgba(23, 53, 231, 0.5), 19); - - spin2: spin(#efefef, -12); - spin3: spin(rgb(23, 53, 231), -15); - spin4: spin(rgba(23, 53, 231, 0.5), -19); - - one1: fadein(#abcdef, 10%); - one2: fadeout(#abcdef, -10%); - - two1: fadeout(#029f23, 10%); - two2: fadein(#029f23, -10%); - - - three1: fadein(rgba(1,2,3, 0.5), 10%); - three2: fadeout(rgba(1,2,3, 0.5), -10%); - - four1: fadeout(rgba(1,2,3, 0), 10%); - four2: fadein(rgba(1,2,3, 0), -10%); - - hue: hue(rgb(34,20,40)); - sat: saturation(rgb(34,20,40)); - lit: lightness(rgb(34,20,40)); - - @old: #34fa03; - @new: hsl(hue(@old), 45%, 90%); - what: @new; - - zero1: saturate(#123456, -100%); - zero2: saturate(#123456, 100%); - zero3: saturate(#000000, 100%); - zero4: saturate(#ffffff, 100%); - - zero5: lighten(#123456, -100%); - zero6: lighten(#123456, 100%); - zero7: lighten(#000000, 100%); - zero8: lighten(#ffffff, 100%); - - zero9: spin(#123456, -100); - zeroa: spin(#123456, 100); - zerob: spin(#000000, 100); - zeroc: spin(#ffffff, 100); -} - - -alpha { - // g: alpha(red); - g1: alpha(rgba(0,0,0,0)); - g2: alpha(rgb(155,55,0)); -} - -fade { - f1: fade(red, 50%); - f2: fade(#fff, 20%); - f3: fade(rgba(34,23,64,0.4), 50%); -} - -@a: rgb(255,255,255); -@b: rgb(0,0,0); - -.mix { - color1: mix(@a, @b, 50%); - color2: mix(@a, @b); - color3: mix(rgba(5,3,1,0.3), rgba(6,3,2, 0.8), 50%); -} - -.contrast { - color1: contrast(#000, red, blue); - color2: contrast(#fff, red, blue); -} - -.percent { - per: percentage(0.5); -} - -// color keywords - -.colorz { - color1: whitesmoke - 10; - color2: spin(red, 34); - color3: spin(blah); -} - - - -// purposfuly whacky to match less.js - -@color: #fcf8e3; - -body { - start: @color; - spin: spin(@color, -10); // #fcf4e3 - chained: darken(spin(@color, -10), 3%); // gives #fbeed5, should be #fbefd5 - direct: darken(#fcf4e3, 3%); // #fbefd5 -} - -// spin around -pre { - @errorBackground: #f2dede; - spin: spin(@errorBackground, -10); -} - -dd { - @white: #fff; - background-color: mix(@white, darken(@white, 10%), 60%); -} - -// math - -.ops { - c1: red * 0.3; - c2: green / 2; - c3: purple % 7; - c4: 4 * salmon; - c5: 1 + salmon; - - c6: 132 / red; - c7: 132 - red; - c8: 132- red; -} - -.transparent { - r: red(transparent); - g: green(transparent); - b: blue(transparent); - a: alpha(transparent); -} - diff --git a/vendor/leafo/lessphp/tests/inputs/compile_on_mixin.less b/vendor/leafo/lessphp/tests/inputs/compile_on_mixin.less deleted file mode 100644 index 79d628f4..00000000 --- a/vendor/leafo/lessphp/tests/inputs/compile_on_mixin.less +++ /dev/null @@ -1,39 +0,0 @@ - -@mixin { - height: 22px; - ul { - height: 20px; - li { - @color: red; - height: 10px; - div span, link { - margin: 10px; - color: @color; - } - } - - div, p { - border: 1px; - &.hello { - color: green; - } - - :what { - color: blue; - } - } - - - a { - b { - color: blue; - } - } - } -} - - - -body { - @mixin; -} diff --git a/vendor/leafo/lessphp/tests/inputs/data-uri.less b/vendor/leafo/lessphp/tests/inputs/data-uri.less deleted file mode 100644 index 0cfa941a..00000000 --- a/vendor/leafo/lessphp/tests/inputs/data-uri.less +++ /dev/null @@ -1,7 +0,0 @@ -.small { - background: data-uri("../hi.less"); -} - -.large { - background: data-uri('../../../lessc.inc.php'); -} diff --git a/vendor/leafo/lessphp/tests/inputs/directives.less b/vendor/leafo/lessphp/tests/inputs/directives.less deleted file mode 100644 index 1b3a9b58..00000000 --- a/vendor/leafo/lessphp/tests/inputs/directives.less +++ /dev/null @@ -1,28 +0,0 @@ - -@hello: "utf-8"; -@charset @hello; - -@-moz-document url-prefix(){ - div { - color: red; - } -} - -@page :left { margin-left: 4cm; } -@page :right { margin-left: 3cm; } -@page { margin: 2cm } - -@-ms-viewport { - width: device-width; -} -@-moz-viewport { - width: device-width; -} -@-o-viewport { - width: device-width; -} -@viewport { - width: device-width; -} - - diff --git a/vendor/leafo/lessphp/tests/inputs/escape.less b/vendor/leafo/lessphp/tests/inputs/escape.less deleted file mode 100644 index 5c15e786..00000000 --- a/vendor/leafo/lessphp/tests/inputs/escape.less +++ /dev/null @@ -1,18 +0,0 @@ - -body { - @hello: "world"; - e1: e("this is simple"); - e2: e("this is simple", "cool lad"); - e3: e(1232); - e4: e(@hello); - e5: e("one" + 'more'); - - t1: ~"eating rice"; - t2: ~"string cheese"; - t3: a b c ~"string me" d e f; - t4: ~"string @{hello}"; -} - -.class { - filter: ~"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png')"; -} diff --git a/vendor/leafo/lessphp/tests/inputs/font_family.less b/vendor/leafo/lessphp/tests/inputs/font_family.less deleted file mode 100644 index d1dfb72d..00000000 --- a/vendor/leafo/lessphp/tests/inputs/font_family.less +++ /dev/null @@ -1,28 +0,0 @@ - -@font-directory: 'fonts/'; -@some-family: Gentium; - -@font-face: maroon; // won't collide with @font-face { } - -@font-face { - font-family: Graublau Sans Web; - src: url(@{font-directory}GraublauWeb.otf) format("opentype"); -} - -@font-face { - font-family: @some-family; - src: url('@{font-directory}Gentium.ttf'); -} - -@font-face { - font-family: @some-family; - src: url("@{font-directory}GentiumItalic.ttf"); - font-style: italic; -} - -h2 { - font-family: @some-family; - crazy: @font-face; -} - - diff --git a/vendor/leafo/lessphp/tests/inputs/guards.less b/vendor/leafo/lessphp/tests/inputs/guards.less deleted file mode 100644 index fc4e344e..00000000 --- a/vendor/leafo/lessphp/tests/inputs/guards.less +++ /dev/null @@ -1,74 +0,0 @@ - -.simple(@hi) when (@hi) { - simple: yellow; -} - - -.something(@hi) when (@hi = cool) { - something: red; -} - -.another(@x) when (@x > 10) { - another: green; -} - - -.flipped(@x) when (@x =< 10) { - flipped: teal; -} - -.yeah(@arg) when (isnumber(@arg)) { - yeah-number: purple @arg; -} - - -.yeah(@arg) when (ispixel(@arg)) { - yeah-pixel: silver; -} - - -.hello(@arg) when not (@arg) { - hello: orange; -} - -dd { - .simple(true); -} - -b { - .something(cool); - .something(birthday); -} - -img { - .another(12); - .flipped(2); -} - -body { - .yeah(232px); - .yeah(232); -} - -.something(@x) when (@x) and (@y), not (@x = what) { - something-complex: blue @x; -} - -div { - @y: true; - .something(true); - -} - -.coloras(@g) when (iscolor(@g)) { - color: true @g; -} - -link { - .coloras(red); - .coloras(#fff); - .coloras(#fffddd); - .coloras(rgb(0,0,0)); - .coloras(rgba(0,0,0, .34)); -} - diff --git a/vendor/leafo/lessphp/tests/inputs/hacks.less b/vendor/leafo/lessphp/tests/inputs/hacks.less deleted file mode 100644 index e69b7bf9..00000000 --- a/vendor/leafo/lessphp/tests/inputs/hacks.less +++ /dev/null @@ -1,6 +0,0 @@ -// css hacks - -:root .alert-message, :root .btn { - border-radius: 0 \0; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/hi.less b/vendor/leafo/lessphp/tests/inputs/hi.less deleted file mode 100644 index 9a3d8198..00000000 --- a/vendor/leafo/lessphp/tests/inputs/hi.less +++ /dev/null @@ -1,5 +0,0 @@ - -div:before { - content: "hi!"; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/ie.less b/vendor/leafo/lessphp/tests/inputs/ie.less deleted file mode 100644 index 37a5f1f6..00000000 --- a/vendor/leafo/lessphp/tests/inputs/ie.less +++ /dev/null @@ -1,12 +0,0 @@ - -foo { - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000); - filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000001); -} - - -foo { - filter: alpha(opacity=20); - filter: alpha(opacity=20, enabled=true); - filter: blaznicate(foo=bar, baz=bang bip, bart=#fa4600); -} diff --git a/vendor/leafo/lessphp/tests/inputs/import.less b/vendor/leafo/lessphp/tests/inputs/import.less deleted file mode 100644 index a5005674..00000000 --- a/vendor/leafo/lessphp/tests/inputs/import.less +++ /dev/null @@ -1,56 +0,0 @@ - -@import 'file1.less'; // file found and imported - -@import "not-found"; - -@import "something.css" media; -@import url("something.css") media; -@import url(something.css) media, screen, print; - -@color: maroon; - -@import url(file2); // found and imported - -body { - line-height: 10em; - @colors; -} - -div { - @color: fuchsia; - @import "file2"; -} - - -.mixin-import() { - @import "file3"; -} - -.one { - .mixin-import(); - color: blue; -} - -.two { - .mixin-import(); -} - - -#merge-import-mixins { - @import "a"; - @import "b"; - div { .just-a-class; } -} - - -@import "inner/file1"; - - -// test bubbling variables up from imports, while preserving order - -pre { - color: @someValue; -} - -@import "file3"; - diff --git a/vendor/leafo/lessphp/tests/inputs/interpolation.less b/vendor/leafo/lessphp/tests/inputs/interpolation.less deleted file mode 100644 index 8aad0004..00000000 --- a/vendor/leafo/lessphp/tests/inputs/interpolation.less +++ /dev/null @@ -1,47 +0,0 @@ - -@cool-hello: "yes"; -@cool-yes: "okay"; -@var: "hello"; - -div { - interp1: ~"@{cool-hello}"; - interp2: ~"@{cool-@{var}}"; - interp3: ~"@{cool-@{cool-@{var}}}"; -} - -// interpolation in selectors - -@hello: 10; -@world: "yeah"; - -@{hello}@{world} { - color: blue; -} - -@{hello} { - color: blue; -} - -hello world @{hello} { - color: red; -} - -#@{world} { - color: "hello @{hello}"; -} - - -@num: 3; - -[prop], -[prop="value@{num}"], -[prop*="val@{num}"], -[|prop~="val@{num}"], -[*|prop$="val@{num}"], -[ns|prop^="val@{num}"], -[@{num}^="val@{num}"], -[@{num}=@{num}], -[@{num}] { - attributes: yes; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/keyframes.less b/vendor/leafo/lessphp/tests/inputs/keyframes.less deleted file mode 100644 index e65a38b9..00000000 --- a/vendor/leafo/lessphp/tests/inputs/keyframes.less +++ /dev/null @@ -1,52 +0,0 @@ -@keyframes 'bounce' { - from { - top: 100px; - animation-timing-function: ease-out; - } - - 25% { - top: 50px; - animation-timing-function: ease-in; - } - - 50% { - top: 100px; - animation-timing-function: ease-out; - } - - 75% { - top: 75px; - animation-timing-function: ease-in; - } - - to { - top: 100px; - } -} - -@-webkit-keyframes flowouttoleft { - 0% { -webkit-transform: translateX(0) scale(1); } - 60%, 70% { -webkit-transform: translateX(0) scale(.7); } - 100% { -webkit-transform: translateX(-100%) scale(.7); } -} - -div { - animation-name: 'diagonal-slide'; - animation-duration: 5s; - animation-iteration-count: 10; -} - -@keyframes 'diagonal-slide' { - - from { - left: 0; - top: 0; - } - - to { - left: 100px; - top: 100px; - } - -} - diff --git a/vendor/leafo/lessphp/tests/inputs/math.less b/vendor/leafo/lessphp/tests/inputs/math.less deleted file mode 100644 index db59d356..00000000 --- a/vendor/leafo/lessphp/tests/inputs/math.less +++ /dev/null @@ -1,122 +0,0 @@ - -.unary { - // all operators are parsable as unary operators, anything - // but - throws an error right now though, - - // this gives two numbers - sub: 10 -5; - // add: 10 +5; // error - // div: 10 /5; // error - // mul: 10 *5; // error -} - -.spaces { - // we can make the parser do math by leaving out the - // space after the first value, or putting spaces on both sides - - sub1: 10-5; - sub2: 10 - 5; - - add1: 10+5; - add2: 10 + 5; - - // div: 10/5; // this wont work, read on - div: 10 / 5; - - mul1: 10*5; - mul2: 10 * 5; -} - -// these properties have divison not in parenthases -.supress-division { - border-radius: 10px / 10px; - border-radius: 10px/12px; - border-radius: hello (10px/10px) world; - @x: 10px; - font: @x/30 sans-serif; - font: 10px / 20px sans-serif; - font: 10px/22px sans-serif; - border-radius:0 15px 15px 15px / 0 50% 50% 50%; -} - - -.parens { - // if you are unsure, then just wrap the expression in parentheses and it will - // always evaluate. - - // notice we no longer have unary operators, and these will evaluate - sub: (10 -5); - add: (10 +5); - div1: (10 /5); - div2: (10/5); // no longer interpreted as the shorthand - mul: (10 *5); -} - -.keyword-names { - // watch out when doing math with keywords, - is a valid keyword character - @a: 100; - @b: 25; - @a-: "hello"; - height: @a-@b; // here we get "hello" 25, not 75 -} - - -.negation { - neg1: -(1px); - neg2: 0-(1px); - - @something: 10; - neg3: -@something; -} - - -// and now here are the tests - -.test { - single1: (5); - single2: 5+(5); - single3: (5)+((5)); - - parens: (5 +(5)) -2; - // parens: ((5 +(5)) -2); // FAILS - fixme - - math1: (5 + 5)*(2 / 1); - math2: (5+5)*(2/1); - - complex1: 2 * (4 * (2 + (1 + 6))) - 1; - complex2: ((2+3)*(2+3) / (9-4)) + 1; - complex3: (2px + 4px) 1em 2px 2; - - @var: (2 * 2); - var1: (2 * @var) 4 4 (@var * 1px); - var2: (@var * @var) * 6; - var3: 4 * (5 + 5) / 2 - (@var * 2); - - complex4: (7 * 7) + (8 * 8); -} - -.percents { - p1: 100 * 10%; - p2: 10% * 100; - p3: 10% * 10%; - - p4: 100px * 10%; // lessjs makes this px - p5: 10% * 100px; // lessjs makes this % - - p6: 20% + 10%; - p7: 20% - 10%; - - p8: 20% / 10%; -} - -.misc { - x: 10px * 4em; - y: 10 * 4em; -} - - -.cond { - c1: 10 < 10; - c2: 10 >= 10; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/media.less b/vendor/leafo/lessphp/tests/inputs/media.less deleted file mode 100644 index 8c16a3cf..00000000 --- a/vendor/leafo/lessphp/tests/inputs/media.less +++ /dev/null @@ -1,68 +0,0 @@ -@media screen, 3D { - P { color: green; } -} -@media print { - body { font-size: 10pt } -} -@media screen { - body { font-size: 13px } -} -@media screen, print { - body { line-height: 1.2 } -} - -@media all and (min-width: 0px) { - body { line-height: 1.2 } -} - -@media all and (min-width: 0) { - body { line-height: 1.2 } -} - -@media - screen and (min-width: 102.5em) and (max-width: 117.9375em), - screen and (min-width: 150em) { - body { color: blue } -} - - -@media screen and (min-height: 100px + 10px) { - body { color: red; } -} - -@cool: 100px; - -@media screen and (height: @cool) and (width: @cool + 10), (size: @cool + 20) { - body { color: red; } -} - - -// media bubbling - -@media test { - div { - height: 20px; - @media (hello) { - color: red; - - pre { - color: orange; - } - } - } -} - -// should not cross boundary -@media yeah { - @page { - @media cool { - color: red; - } - } -} - -// variable in query -@mobile: ~"(max-width: 599px)"; -@media @mobile { - .helloworld { color: blue } -} diff --git a/vendor/leafo/lessphp/tests/inputs/misc.less b/vendor/leafo/lessphp/tests/inputs/misc.less deleted file mode 100644 index eb690b9a..00000000 --- a/vendor/leafo/lessphp/tests/inputs/misc.less +++ /dev/null @@ -1,100 +0,0 @@ - -@color: #fff; -@base_path: "/assets/images/"; -@images: @base_path + "test/"; -.topbar { background: url(@{images}topbar.png); } -.hello { test: empty-function(@images, 40%, to(@color)); } - -.css3 { - background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, - from(#E9A000), to(#A37000)); -} - - -/** - -Here is a block comment - -**/ - - -// this is a comment - -.test, /*hello*/.world { - border: 1px solid red; // world - /* another property */ - color: url(http://mage-page.com); - string: "hello /* this is not a comment */"; - world: "// neither is this"; - string: 'hello /* this is not a comment */' /*what if this is a comment */; - world: '// neither is this' // hell world; - ; - what-/*something?*/ever: 100px; - background: url(/*no comment here*/); -} - - -.urls { - @var: "http://google.com"; - background1: url(@var); - background2: url(@{var}); - background3: url("@{var}"); -} - -.mix(@arg) { color: @arg; } -@aaa: aaa; -@bbb: bbb; -// make sure the opening selector isn't too greedy -.cool {.mix("@{aaa}, @{bbb}")} -.cool(); - - - -// merging of mixins -.span-17 { float: left; } -.span-17 { width: 660px; } - -.x {.span-17;} - -.hi { - pre { - color: red; - } -} - -.hi { - pre { - color: blue; - } -} - -.rad { - .hi; -} - - -hello { - numbers: 1.0 0.1 .1 1.; - numbers: 1.0s 0.1s .1s 1.s; - numbers: -1.0s -0.1s -.1s -1.s; - numbers: -1.0 -0.1 -.1 -1.; -} - - -#string { - hello: 'what\'s going on here'; - hello: 'blah blag @{ blah blah'; - - join: 3434 + "hello"; - join: 3434 + hello; -} - - -.duplicates { - hello: world; - hello: "world"; - hello: world; - hello: "what"; - hello: world; - hello: "world"; -} diff --git a/vendor/leafo/lessphp/tests/inputs/mixin_functions.less b/vendor/leafo/lessphp/tests/inputs/mixin_functions.less deleted file mode 100644 index 2d858ad6..00000000 --- a/vendor/leafo/lessphp/tests/inputs/mixin_functions.less +++ /dev/null @@ -1,33 +0,0 @@ - -@outer: 10px; -@class(@var:22px, @car: 400px + @outer) { - margin: @var; - height: @car; -} - -@group { - @f(@color) { - color: @color; - } - .cool { - border-bottom: 1px solid green; - } -} - -.class(@width:200px) { - padding: @width; -} - -body { - .class(2.0em); - @group > @f(red); - @class(10px, 10px + 2); - @group > .cool; -} - - -@lots(@a: 10px, @b: 20px, @c: 30px, @d: 40px, @e: 4px, @f:3px, @g:2px, @h: 1px) { - padding: @a @b @c @d; - margin: @e @f @g @h; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/mixin_merging.less.disable b/vendor/leafo/lessphp/tests/inputs/mixin_merging.less.disable deleted file mode 100644 index 86b3e0cb..00000000 --- a/vendor/leafo/lessphp/tests/inputs/mixin_merging.less.disable +++ /dev/null @@ -1,100 +0,0 @@ - -@tester { - p, div { height: 10px; } -} - -#test1 { - div { color: red; } - @tester; -} - - -@cool { - a,b,i { width: 1px; } -} - -#test2 { - b { color: red; } - @cool; -} - -#test3 { - @cool; - b { color: red; } -} - -@cooler { - a { margin: 1px; } -} - -#test4 { - a, div, html { color: blue; } - @cooler; -} - -@hi { - img, strong { float: right; } -} - -#test5 { - img, strong { padding: 2px; } - @hi; -} - -@nested { - div, span { - a { - color: red; - } - } -} - -#test6 { - div, span { - a { - line-height: 10px; - } - } - @nested; -} - -@broken-nesting { - div, span { - strong, b { - color: red; - } - } - -} - -#test7 { - div { - strong { - margin: 1px; - } - } - @broken-nesting; -} - - -@another-nest { - a,b { - i { - color: red; - } - - s { - color: blue; - } - } -} - -#test8 { - a, b { - i,s { - background: red; - } - } - @another-nest; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/mixins.less b/vendor/leafo/lessphp/tests/inputs/mixins.less deleted file mode 100644 index 768e6384..00000000 --- a/vendor/leafo/lessphp/tests/inputs/mixins.less +++ /dev/null @@ -1,197 +0,0 @@ - -@rounded-corners { - border-radius: 10px; -} - -.bold { - @font-size: 20px; - font-size: @font-size; - font-weight: bold; -} - -body #window { - @rounded-corners; - .bold; - line-height: @font-size * 1.5; -} - -#bundle { - .button { - display: block; - border: 1px solid black; - background-color: grey; - &:hover { background-color: white } - } -} -#header a { - color: orange; - #bundle > .button; // mixin the button class -} - -div { - @abstract { - hello: world; - b { - color: blue; - } - } - - @abstract > b; - @abstract; -} - -@poop { - big: baby; -} - -body { - div; -} - -// not using > to list mixins - -.hello { - .world { - color: blue; - } -} - -.foobar { - .hello .world; -} - - -// arguments - -.spam(@something: 100, @dad: land) { - @wow: 23434; - foo: @arguments; - bar: @arguments; -} - -.eggs { - .spam(1px, 2px); - .spam(); -} - -.first(@one, @two, @three, @four: cool) { - cool: @arguments; -} - -#hello { - .first(one, two, three); -} - -#hello-important { - .first(one, two, three) !important; -} - -.rad(@name) { - cool: @arguments; -} - -#world { - @hello: "world"; - .rad("@{hello}"); -} - -.second(@x, @y:skip, @z: me) { - things: @arguments; -} - -#another { - .second(red, blue, green); - .second(red blue green); -} - - -.another(@x, @y:skip, @z:me) { - .cool { - color: @arguments; - } -} - -#day { - .another(one,two, three); - .another(one two three); -} - - -.to-be-important() { - color: red; - @color: red; - height: 20px; - - pre { - color: @color; - } -} - -.mix-suffix { - .to-be-important() !important; -} - - - - -#search-all { - .red() { - color:#f00 !important; - } -} - -#search-all { - .green() { - color: #0f0 !important; - } -} - -.search-test { - #search-all > .red(); - #search-all > .green(); -} - - -// mixin self without infinite loop -.cowboy() { - color: blue; -} - -.cowboy { - .cowboy; -} - - -// semicolon - -.semi1(@color: red, blue, green;) { - color: @color; -} - -.semi2(@color: red, blue, green; dad) { - color: @color; -} - -.semi3(hello; world; piss) { - hello: world; -} - - - -// self referencing skipping - -.nav-divider(@color: red){ - padding: 10px; -} - -.nav { - .nav-divider { - .nav-divider(); - } -} - -.nav-divider { - .nav-divider(); -} - - diff --git a/vendor/leafo/lessphp/tests/inputs/nested.less b/vendor/leafo/lessphp/tests/inputs/nested.less deleted file mode 100644 index 0b62ea19..00000000 --- a/vendor/leafo/lessphp/tests/inputs/nested.less +++ /dev/null @@ -1,60 +0,0 @@ -#header { - color: black; - - .navigation { - font-size: 12px; - .border { - .outside { - color: blue; - } - } - } - .logo { - width: 300px; - &:hover { text-decoration: none } - } -} - -a { b { ul { li { color: green; } } } } - -this { will { not { show { } } } } - -.cool { - div & { color: green; } - p & span { color: yellow; } -} - -another { - .cool; -} - -b { - & .something { - color: blue; - } - - &.something { - color: blue; - } -} - -.foo { - .bar, .baz { - & .qux { - display: block; - } - .qux & { - display: inline; - } - .qux & .biz { - display: none; - } - } -} - -b { - hello [x="&yeah"] { - color: red; - } -} - diff --git a/vendor/leafo/lessphp/tests/inputs/pattern_matching.less b/vendor/leafo/lessphp/tests/inputs/pattern_matching.less deleted file mode 100644 index c2a0da91..00000000 --- a/vendor/leafo/lessphp/tests/inputs/pattern_matching.less +++ /dev/null @@ -1,157 +0,0 @@ - -.demo (light, @color) { - color: lighten(@color, 10%); -} -.demo (@_, @color) { - display: block; -} - -@switch: light; - -.class { - .demo(@switch, #888); -} - -// by arity - -.mixin () { - zero: 0; -} -.mixin (@a: 1px) { - one: 1; -} -.mixin (@a) { - one-req: 1; -} -.mixin (@a: 1px, @b: 2px) { - two: 2; -} - -.mixin (@a, @b, @c) { - three-req: 3; -} - -.mixin (@a: 1px, @b: 2px, @c: 3px) { - three: 3; -} - -.zero { - .mixin(); -} - -.one { - .mixin(1); -} - -.two { - .mixin(1, 2); -} - -.three { - .mixin(1, 2, 3); -} - -// - -.mixout ('left') { - left: 1; -} - -.mixout ('right') { - right: 1; -} - -.left { - .mixout('left'); -} -.right { - .mixout('right'); -} - -// - -.border (@side, @width) { - color: black; - .border-side(@side, @width); -} -.border-side (left, @w) { - border-left: @w; -} -.border-side (right, @w) { - border-right: @w; -} - -.border-right { - .border(right, 4px); -} -.border-left { - .border(left, 4px); -} - -// - - -.border-radius (@r) { - both: @r * 10; -} -.border-radius (@r, left) { - left: @r; -} -.border-radius (@r, right) { - right: @r; -} - -.only-right { - .border-radius(33, right); -} -.only-left { - .border-radius(33, left); -} -.left-right { - .border-radius(33); -} - -.hola(hello, @hello...) { - color: blue; -} - -#hola { - .hola(hello, world); -} - -.resty(@hello, @world, @the_rest...) { - padding: @hello @world; - rest: @the_rest; -} - -.defaults(@aa, @bb:e343, @cc: "heah", ...) { - height: @aa; -} - -#defaults_1 { - .defaults(one); - .defaults(two, one); - .defaults(three, two, one); - .defaults(four, three, two, one); -} - - -.thing() { color: green; } -.thing(...) { color: blue; } -.thing { color: red; } - -#aa { - .thing(); -} - -#bb { - .thing; -} - - -#cc { - .thing(1); -} - - - diff --git a/vendor/leafo/lessphp/tests/inputs/scopes.less b/vendor/leafo/lessphp/tests/inputs/scopes.less deleted file mode 100644 index 42e46969..00000000 --- a/vendor/leafo/lessphp/tests/inputs/scopes.less +++ /dev/null @@ -1,40 +0,0 @@ - - -@a: 10; -@some { - @b: @a + 10; - div { - @c: @b + 10; - other { - @d: @c + 10; - world { - @e: @d + 10; - height: @e; - } - } - } -} - - -body { - @some; -} - -@some; - -.test(@x: 10) { - height: @x; - .test(@y: 11) { - height: @y; - .test(@z: 12) { - height: @z; - } - .test; - } - .test; -} - -pre { - .test; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/selector_expressions.less b/vendor/leafo/lessphp/tests/inputs/selector_expressions.less deleted file mode 100644 index b8aa2214..00000000 --- a/vendor/leafo/lessphp/tests/inputs/selector_expressions.less +++ /dev/null @@ -1,29 +0,0 @@ - -@color: blue; - -something @{color}, world { - color: blue; -} - -.div { - @color: red; - (3434) { - height: 100px; - } - - cool @{color} { - height: 4000px; - } -} - -.heck(@a) { color: @a+10 } - -.spanX (@index) when (@index > 0) { - .span@{index} { .heck(@index) } - .spanX(@index - 1); -} -.spanX (0) {} - -.spanX (5); - - diff --git a/vendor/leafo/lessphp/tests/inputs/site_demos.less b/vendor/leafo/lessphp/tests/inputs/site_demos.less deleted file mode 100644 index 08d7f1e5..00000000 --- a/vendor/leafo/lessphp/tests/inputs/site_demos.less +++ /dev/null @@ -1,120 +0,0 @@ -// these are the demos from the lessphp homepage - -default { - @base: 24px; - @border-color: #B2B; - - .underline { border-bottom: 1px solid green } - - #header { - color: black; - border: 1px solid @border-color + #222222; - - .navigation { - font-size: @base / 2; - a { - .underline; - } - } - .logo { - width: 300px; - &:hover { text-decoration: none } - } - } -} - -variables { - @a: 2; - @x: @a * @a; - @y: @x + 1; - @z: @x * 2 + @y; - - @nice-blue: #5B83AD; - @light-blue: @nice-blue + #111; - - @b: @a * 10; - @c: #888; - @fonts: "Trebuchet MS", Verdana, sans-serif; - - .variables { - width: @z + 1cm; // 14cm - height: @b + @x + 0px; // 24px - color: @c; - background: @light-blue; - font-family: @fonts; - } -} - -mixins { - .bordered { - border-top: dotted 1px black; - border-bottom: solid 2px black; - } - #menu a { - color: #111; - .bordered; - } - - .post a { - color: red; - .bordered; - } -} - -nested-rules { - #header { - color: black; - - .navigation { - font-size: 12px; - } - .logo { - width: 300px; - &:hover { text-decoration: none } - } - } -} - -namespaces { - #bundle { - .button { - display: block; - border: 1px solid black; - background-color: grey; - &:hover { background-color: white } - } - } - #header a { - color: orange; - #bundle > .button; // mixin the button class - } -} - -mixin-functions { - @outer: 10px; - @class(@var:22px, @car: 400px + @outer) { - margin: @var; - height: @car; - } - - @group { - @f(@color) { - color: @color; - } - .cool { - border-bottom: 1px solid green; - } - } - - .class(@width:200px) { - padding: @width; - } - - body { - .class(2.0em); - @group > @f(red); - @class(10px, 10px + 2); - @group > .cool; - } -} - diff --git a/vendor/leafo/lessphp/tests/inputs/test-imports/a.less b/vendor/leafo/lessphp/tests/inputs/test-imports/a.less deleted file mode 100644 index a00464db..00000000 --- a/vendor/leafo/lessphp/tests/inputs/test-imports/a.less +++ /dev/null @@ -1,6 +0,0 @@ -.just-a-class { background: red; } - -.some-mixin() { - height: 200px; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/test-imports/b.less b/vendor/leafo/lessphp/tests/inputs/test-imports/b.less deleted file mode 100644 index 599ed3a4..00000000 --- a/vendor/leafo/lessphp/tests/inputs/test-imports/b.less +++ /dev/null @@ -1,12 +0,0 @@ -.just-a-class { background: blue; } - -.hello { - .some-mixin(); -} - - -@media cool { - color: red; - .some-mixin(); -} - diff --git a/vendor/leafo/lessphp/tests/inputs/test-imports/file1.less b/vendor/leafo/lessphp/tests/inputs/test-imports/file1.less deleted file mode 100644 index 658de0c5..00000000 --- a/vendor/leafo/lessphp/tests/inputs/test-imports/file1.less +++ /dev/null @@ -1,16 +0,0 @@ - - -/** - * This is a test import file - */ - -@colors { - div.bright { - color: red; - } - - div.sad { - color: blue; - } -} - diff --git a/vendor/leafo/lessphp/tests/inputs/test-imports/file2.less b/vendor/leafo/lessphp/tests/inputs/test-imports/file2.less deleted file mode 100644 index 2cae8dce..00000000 --- a/vendor/leafo/lessphp/tests/inputs/test-imports/file2.less +++ /dev/null @@ -1,6 +0,0 @@ - -b { - color: @color; - padding: 16px; -} - diff --git a/vendor/leafo/lessphp/tests/inputs/test-imports/file3.less b/vendor/leafo/lessphp/tests/inputs/test-imports/file3.less deleted file mode 100644 index 28b643ea..00000000 --- a/vendor/leafo/lessphp/tests/inputs/test-imports/file3.less +++ /dev/null @@ -1,7 +0,0 @@ - -h2 { - background: url("../images/logo.png") no-repeat; -} - -@someValue: hello-from-file-3; - diff --git a/vendor/leafo/lessphp/tests/inputs/test-imports/inner/file1.less b/vendor/leafo/lessphp/tests/inputs/test-imports/inner/file1.less deleted file mode 100644 index df654a7e..00000000 --- a/vendor/leafo/lessphp/tests/inputs/test-imports/inner/file1.less +++ /dev/null @@ -1,6 +0,0 @@ - -.inner { - content: "inner/file1.less" -} - -@import "file2"; // should get the one in inner diff --git a/vendor/leafo/lessphp/tests/inputs/test-imports/inner/file2.less b/vendor/leafo/lessphp/tests/inputs/test-imports/inner/file2.less deleted file mode 100644 index f40d3c67..00000000 --- a/vendor/leafo/lessphp/tests/inputs/test-imports/inner/file2.less +++ /dev/null @@ -1,4 +0,0 @@ - -.inner { - content: "inner/file2.less" -} diff --git a/vendor/leafo/lessphp/tests/inputs/variables.less b/vendor/leafo/lessphp/tests/inputs/variables.less deleted file mode 100644 index 6e18eb80..00000000 --- a/vendor/leafo/lessphp/tests/inputs/variables.less +++ /dev/null @@ -1,44 +0,0 @@ -@a: 2; -@x: @a * @a; -@y: @x + 1; -@z: @y + @x * 2; -@m: @z % @y; - -@nice-blue: #5B83AD; -@light-blue: @nice-blue + #111; - -@rgb-color: rgb(20%, 15%, 80%); -@rgba-color: rgba(23,68,149,0.5); - -@b: @a * 10px; -@c: #888; -@fonts: "Trebuchet MS", Verdana, sans-serif; - -.variables { - width: @z + 1cm; // 14cm - height: @b + @x + 0px; // 24px - margin-top: -@b; // -20px - margin-bottom: 10 - -@b; // 30px - @d: @c + #001; - color: @d; - background: @light-blue; - font-family: @fonts; - margin: @m + 0px; // 3px - font: 10px/12px serif; - font: 120%/120% serif; -} - -.external { - color: @c; - border: 1px solid @rgb-color; - background: @rgba-color; -} - -@hello: 44px; -@something: "hello"; -@cool: something; - -outer1: @@something; -outer2: @@@cool; - - diff --git a/vendor/leafo/lessphp/tests/inputs_lessjs/mixins-args.less b/vendor/leafo/lessphp/tests/inputs_lessjs/mixins-args.less deleted file mode 100644 index c3965924..00000000 --- a/vendor/leafo/lessphp/tests/inputs_lessjs/mixins-args.less +++ /dev/null @@ -1,205 +0,0 @@ -.mixin (@a: 1px, @b: 50%) { - width: (@a * 5); - height: (@b - 1%); -} - -.mixina (@style, @width, @color: black) { - border: @width @style @color; -} - -.mixiny -(@a: 0, @b: 0) { - margin: @a; - padding: @b; -} - -.hidden() { - color: transparent; // asd -} - -#hidden { - .hidden; -} - -#hidden1 { - .hidden(); -} - -.two-args { - color: blue; - .mixin(2px, 100%); - .mixina(dotted, 2px); -} - -.one-arg { - .mixin(3px); -} - -.no-parens { - .mixin; -} - -.no-args { - .mixin(); -} - -.var-args { - @var: 9; - .mixin(@var, (@var * 2)); -} - -.multi-mix { - .mixin(2px, 30%); - .mixiny(4, 5); -} - -.maxa(@arg1: 10, @arg2: #f00) { - padding: (@arg1 * 2px); - color: @arg2; -} - -body { - .maxa(15); -} - -@glob: 5; -.global-mixin(@a:2) { - width: (@glob + @a); -} - -.scope-mix { - .global-mixin(3); -} - -.nested-ruleset (@width: 200px) { - width: @width; - .column { margin: @width; } -} -.content { - .nested-ruleset(600px); -} - -// - -.same-var-name2(@radius) { - radius: @radius; -} -.same-var-name(@radius) { - .same-var-name2(@radius); -} -#same-var-name { - .same-var-name(5px); -} - -// - -.var-inside () { - @var: 10px; - width: @var; -} -#var-inside { .var-inside; } - -.mixin-arguments (@width: 0px, ...) { - border: @arguments; - width: @width; -} - -.arguments { - .mixin-arguments(1px, solid, black); -} -.arguments2 { - .mixin-arguments(); -} -.arguments3 { - .mixin-arguments; -} - -.mixin-arguments2 (@width, @rest...) { - border: @arguments; - rest: @rest; - width: @width; -} -.arguments4 { - .mixin-arguments2(0, 1, 2, 3, 4); -} - -// Edge cases - -.edge-case { - .mixin-arguments("{"); -} - -// Division vs. Literal Slash -.border-radius(@r: 2px/5px) { - border-radius: @r; -} -.slash-vs-math { - .border-radius(); - .border-radius(5px/10px); - .border-radius((3px * 2)); -} -// semi-colon vs comma for delimiting - -.mixin-takes-one(@a) { - one: @a; -} - -.mixin-takes-two(@a; @b) { - one: @a; - two: @b; -} - -.comma-vs-semi-colon { - .mixin-takes-two(@a : a; @b : b, c); - .mixin-takes-two(@a : d, e; @b : f); - .mixin-takes-one(@a: g); - .mixin-takes-one(@a : h;); - .mixin-takes-one(i); - .mixin-takes-one(j;); - .mixin-takes-two(k, l); - .mixin-takes-one(m, n;); - .mixin-takes-two(o, p; q); - .mixin-takes-two(r, s; t;); -} - -.mixin-conflict(@a:defA, @b:defB, @c:defC) { - three: @a, @b, @c; -} - -.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { - four: @a, @b, @c, @d; -} - -#named-conflict { - .mixin-conflict(11, 12, 13, @a:a); - .mixin-conflict(@a:a, 21, 22, 23); -} -@a: 3px; -.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} - -.test-mixin-default-arg { - .mixin-default-arg(); - .mixin-default-arg(2px); -} - -.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { - margin: @margin; -} -.selector { - .mixin-comma-default1(#33acfe; 4); -} -.mixin-comma-default2(@margin: 2, 2, 2, 2;) { - margin: @margin; -} -.selector2 { - .mixin-comma-default2(); -} -.mixin-comma-default3(@margin: 2, 2, 2, 2) { - margin: @margin; -} -.selector3 { - .mixin-comma-default3(4,2,2,2); -} diff --git a/vendor/leafo/lessphp/tests/inputs_lessjs/mixins-named-args.less b/vendor/leafo/lessphp/tests/inputs_lessjs/mixins-named-args.less deleted file mode 100644 index f62dc86a..00000000 --- a/vendor/leafo/lessphp/tests/inputs_lessjs/mixins-named-args.less +++ /dev/null @@ -1,36 +0,0 @@ -.mixin (@a: 1px, @b: 50%) { - width: (@a * 5); - height: (@b - 1%); - args: @arguments; -} -.mixin (@a: 1px, @b: 50%) when (@b > 75%){ - text-align: center; -} - -.named-arg { - color: blue; - .mixin(@b: 100%); -} - -.class { - @var: 20%; - .mixin(@b: @var); -} - -.all-args-wrong-args { - .mixin(@b: 10%, @a: 2px); -} - -.mixin2 (@a: 1px, @b: 50%, @c: 50) { - width: (@a * 5); - height: (@b - 1%); - color: (#000000 + @c); -} - -.named-args2 { - .mixin2(3px, @c: 100); -} - -.named-args3 { - .mixin2(@b: 30%, @c: #123456); -} diff --git a/vendor/leafo/lessphp/tests/inputs_lessjs/strings.less b/vendor/leafo/lessphp/tests/inputs_lessjs/strings.less deleted file mode 100644 index 32fad721..00000000 --- a/vendor/leafo/lessphp/tests/inputs_lessjs/strings.less +++ /dev/null @@ -1,51 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: ~"DX.Transform.MS.BS.filter(opacity=50)"; -} -#one-line { image: url(http://tooks.com) } -#crazy { image: url(http://), "}", url("http://}") } -#interpolation { - @var: '/dev'; - url: "http://lesscss.org@{var}/image.jpg"; - - @var2: 256; - url2: "http://lesscss.org/image-@{var2}.jpg"; - - @var3: #456; - url3: "http://lesscss.org@{var3}"; - - @var4: hello; - url4: "http://lesscss.org/@{var4}"; - - @var5: 54.4px; - url5: "http://lesscss.org/@{var5}"; -} - -// multiple calls with string interpolation - -.mix-mul (@a: green) { - color: ~"@{a}"; -} -.mix-mul-class { - .mix-mul(blue); - .mix-mul(red); - .mix-mul(black); - .mix-mul(orange); -} diff --git a/vendor/leafo/lessphp/tests/outputs/accessors.css b/vendor/leafo/lessphp/tests/outputs/accessors.css deleted file mode 100644 index 2f3c9e61..00000000 --- a/vendor/leafo/lessphp/tests/outputs/accessors.css +++ /dev/null @@ -1,14 +0,0 @@ -.article { color:#294366; } -.comment { - width:960px; - color:#294366; - padding:10px; -} -.wow { - height:960px; - background-color:#294366; - color:green; - padding:; - margin:; -} -.mix { font-size:10px; } diff --git a/vendor/leafo/lessphp/tests/outputs/arity.css b/vendor/leafo/lessphp/tests/outputs/arity.css deleted file mode 100644 index 5173561d..00000000 --- a/vendor/leafo/lessphp/tests/outputs/arity.css +++ /dev/null @@ -1,25 +0,0 @@ -.one { - hello: one; - world: one; -} -.two { - hello: two; - world: two; -} -.three { - hello: three; - world: three; -} -.multi-foo { - foo: two cool; - foo: three cool yeah; - foo: two 1; - foo: three 1 yeah; - foo: three 1 1; -} -.multi-baz { - baz: two cool; - baz: three yeah; - baz: two 1; - baz: three 1; -} diff --git a/vendor/leafo/lessphp/tests/outputs/attributes.css b/vendor/leafo/lessphp/tests/outputs/attributes.css deleted file mode 100644 index fb0e176c..00000000 --- a/vendor/leafo/lessphp/tests/outputs/attributes.css +++ /dev/null @@ -1,105 +0,0 @@ -* { - color: blue; -} -E { - color: blue; -} -E[foo] { - color: blue; -} -[foo] { - color: blue; -} -[foo] .helloWorld { - color: blue; -} -[foo].helloWorld { - color: blue; -} -E[foo="barbar"] { - color: blue; -} -E[foo~="hello#$@%@$#^"] { - color: blue; -} -E[foo^="color: green;"] { - color: blue; -} -E[foo$="239023"] { - color: blue; -} -E[foo*="29302"] { - color: blue; -} -E[foo|="239032"] { - color: blue; -} -E:root { - color: blue; -} -E:nth-child(odd) { - color: blue; -} -E:nth-child(2n+1) { - color: blue; -} -E:nth-child(5) { - color: blue; -} -E:nth-last-child(-n+2) { - color: blue; -} -E:nth-of-type(2n) { - color: blue; -} -E:nth-last-of-type(n) { - color: blue; -} -E:first-child { - color: blue; -} -E:last-child { - color: blue; -} -E:first-of-type { - color: blue; -} -E:last-of-type { - color: blue; -} -E:only-child { - color: blue; -} -E:only-of-type { - color: blue; -} -E:empty { - color: blue; -} -E:lang(en) { - color: blue; -} -E::first-line { - color: blue; -} -E::before { - color: blue; -} -E#id { - color: blue; -} -E:not(:link) { - color: blue; -} -E F { - color: blue; -} -E > F { - color: blue; -} -E + F { - color: blue; -} -E ~ F { - color: blue; -} diff --git a/vendor/leafo/lessphp/tests/outputs/builtins.css b/vendor/leafo/lessphp/tests/outputs/builtins.css deleted file mode 100644 index 6ac21f2c..00000000 --- a/vendor/leafo/lessphp/tests/outputs/builtins.css +++ /dev/null @@ -1,61 +0,0 @@ -body { - color: "hello world"; - num-basic: 5.1666666666667; - num-floor: 5px; - num-ceil: 6px; - num2: 0.66666666666667; - num2-round: 1; - num2-floor: 0; - num2-ceil: 1; - round-lit: 3px; - rgba1: #ff112233; - rgba2: #992c3742; - argb: #992c3742; -} -format { - format: "rgb(32, 128, 64)"; - format-string: "hello world"; - format-multiple: "hello earth 2"; - format-url-encode: 'red is %A'; - eformat: rgb(32, 128, 64); -} -#functions { - str1: true; - str2: false; - num1: true; - num2: true; - num3: true; - num4: false; - col1: true; - col2: false; - col3: true; - col4: true; - key1: true; - key2: false; - px1: true; - px2: false; - per1: true; - per2: false; - em1: true; - em2: false; - ex1: 2; - ex2: 1; - ex3: extract(1,1); - ex4: 2; - pow: 16; - pi: 3.1415926535898; - mod: 4; - tan: 1.5574077246549; - cos: 0.54030230586814; - sin: 0.8414709848079; - atan: 0.78539816339745rad; - acos: 0rad; - asin: 1.5707963267949rad; - sqrt: 2.8284271247462; -} -#unit { - unit-lit: 10; - unit-arg: 10s; - unit-arg2: 10em; - unit-math: 7.407%; -} diff --git a/vendor/leafo/lessphp/tests/outputs/colors.css b/vendor/leafo/lessphp/tests/outputs/colors.css deleted file mode 100644 index 5310ffb0..00000000 --- a/vendor/leafo/lessphp/tests/outputs/colors.css +++ /dev/null @@ -1,103 +0,0 @@ -body { - color: #ff0000; - color: #ffffff; - color: #000000; - color: #996d33; - color: rgba(153,109,51,0.3); - lighten1: #ffffff; - lighten2: #7c8df2; - lighten3: rgba(222,140,129,0.5); - darken1: #d6d6d6; - darken2: #0d1e81; - darken3: rgba(18,42,185,0.5); - saturate1: #f1eded; - saturate2: #0025fe; - saturate3: rgba(10,44,244,0.5); - desaturate1: #efefef; - desaturate2: #3349cb; - desaturate3: rgba(36,62,218,0.5); - spin1: #efefef; - spin2: #2d17e7; - spin3: rgba(59,23,231,0.5); - spin2: #efefef; - spin3: #1769e7; - spin4: rgba(23,119,231,0.5); - one1: #abcdef; - one2: #abcdef; - two1: rgba(2,159,35,0.9); - two2: rgba(2,159,35,0.9); - three1: rgba(1,2,3,0.6); - three2: rgba(1,2,3,0.6); - four1: rgba(1,2,3,0); - four2: rgba(1,2,3,0); - hue: 282; - sat: 33; - lit: 12; - what: #dff1da; - zero1: #343434; - zero2: #003468; - zero3: #000000; - zero4: #ffffff; - zero5: #000000; - zero6: #ffffff; - zero7: #ffffff; - zero8: #ffffff; - zero9: #1d5612; - zeroa: #56124b; - zerob: #000000; - zeroc: #ffffff; -} -alpha { - g1: 0; - g2: 1; -} -fade { - f1: rgba(255,0,0,0.5); - f2: rgba(255,255,255,0.2); - f3: rgba(34,23,64,0.5); -} -.mix { - color1: #808080; - color2: #808080; - color3: rgba(6,3,2,-0.25); -} -.contrast { - color1: #ff0000; - color2: #0000ff; -} -.percent { - per: 50%; -} -.colorz { - color1: #ebebeb; - color2: #ff9100; - color3: #000000; -} -body { - start: #fcf8e3; - spin: #fcf4e3; - chained: #fbeed5; - direct: #fbefd5; -} -pre { - spin: #f2dee1; -} -dd { - background-color: #f5f5f5; -} -.ops { - c1: #4d0000; - c2: #004000; - c3: #020002; - c4: #ffffff; - c5: #fb8173; - c6: 132 / #ff0000; - c7: 132 - #ff0000; - c8: 132- #ff0000; -} -.transparent { - r: 0; - g: 0; - b: 0; - a: 0; -} diff --git a/vendor/leafo/lessphp/tests/outputs/compile_on_mixin.css b/vendor/leafo/lessphp/tests/outputs/compile_on_mixin.css deleted file mode 100644 index 318526a5..00000000 --- a/vendor/leafo/lessphp/tests/outputs/compile_on_mixin.css +++ /dev/null @@ -1,29 +0,0 @@ -body { - height: 22px; -} -body ul { - height: 20px; -} -body ul li { - height: 10px; -} -body ul li div span, -body ul li link { - margin: 10px; - color: red; -} -body ul div, -body ul p { - border: 1px; -} -body ul div.hello, -body ul p.hello { - color: green; -} -body ul div :what, -body ul p :what { - color: blue; -} -body ul a b { - color: blue; -} diff --git a/vendor/leafo/lessphp/tests/outputs/data-uri.css b/vendor/leafo/lessphp/tests/outputs/data-uri.css deleted file mode 100644 index e51b8f9c..00000000 --- a/vendor/leafo/lessphp/tests/outputs/data-uri.css +++ /dev/null @@ -1,6 +0,0 @@ -.small { - background: url("data:text/plain;base64,CmRpdjpiZWZvcmUgewoJY29udGVudDogImhpISI7Cn0KCg=="); -} -.large { - background: url("../../../lessc.inc.php"); -} diff --git a/vendor/leafo/lessphp/tests/outputs/directives.css b/vendor/leafo/lessphp/tests/outputs/directives.css deleted file mode 100644 index c2d82b83..00000000 --- a/vendor/leafo/lessphp/tests/outputs/directives.css +++ /dev/null @@ -1,27 +0,0 @@ -@charset "utf-8"; -@-moz-document url-prefix() { - div { - color: red; - } -} -@page :left { - margin-left: 4cm; -} -@page :right { - margin-left: 3cm; -} -@page { - margin: 2cm; -} -@-ms-viewport { - width: device-width; -} -@-moz-viewport { - width: device-width; -} -@-o-viewport { - width: device-width; -} -@viewport { - width: device-width; -} diff --git a/vendor/leafo/lessphp/tests/outputs/escape.css b/vendor/leafo/lessphp/tests/outputs/escape.css deleted file mode 100644 index 0587bcab..00000000 --- a/vendor/leafo/lessphp/tests/outputs/escape.css +++ /dev/null @@ -1,14 +0,0 @@ -body { - e1: this is simple; - e2: this is simple; - e3: 1232; - e4: world; - e5: onemore; - t1: eating rice; - t2: string cheese; - t3: a b c string me d e f; - t4: string world; -} -.class { - filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png'); -} diff --git a/vendor/leafo/lessphp/tests/outputs/font_family.css b/vendor/leafo/lessphp/tests/outputs/font_family.css deleted file mode 100644 index fc260fd4..00000000 --- a/vendor/leafo/lessphp/tests/outputs/font_family.css +++ /dev/null @@ -1,17 +0,0 @@ -@font-face { - font-family: Graublau Sans Web; - src: url(fonts/GraublauWeb.otf) format("opentype"); -} -@font-face { - font-family: Gentium; - src: url('fonts/Gentium.ttf'); -} -@font-face { - font-family: Gentium; - src: url("fonts/GentiumItalic.ttf"); - font-style: italic; -} -h2 { - font-family: Gentium; - crazy: maroon; -} diff --git a/vendor/leafo/lessphp/tests/outputs/guards.css b/vendor/leafo/lessphp/tests/outputs/guards.css deleted file mode 100644 index 34af5495..00000000 --- a/vendor/leafo/lessphp/tests/outputs/guards.css +++ /dev/null @@ -1,27 +0,0 @@ -dd { - simple: yellow; -} -b { - something: red; - something-complex: blue cool; - something-complex: blue birthday; -} -img { - another: green; - flipped: teal; -} -body { - yeah-number: purple 232px; - yeah-pixel: silver; - yeah-number: purple 232; -} -div { - something-complex: blue true; -} -link { - color: true red; - color: true #fff; - color: true #fffddd; - color: true #000000; - color: true rgba(0,0,0,0.34); -} diff --git a/vendor/leafo/lessphp/tests/outputs/hacks.css b/vendor/leafo/lessphp/tests/outputs/hacks.css deleted file mode 100644 index b8327eb5..00000000 --- a/vendor/leafo/lessphp/tests/outputs/hacks.css +++ /dev/null @@ -1,4 +0,0 @@ -:root .alert-message, -:root .btn { - border-radius: 0 \0; -} diff --git a/vendor/leafo/lessphp/tests/outputs/hi.css b/vendor/leafo/lessphp/tests/outputs/hi.css deleted file mode 100644 index 3bffcf0b..00000000 --- a/vendor/leafo/lessphp/tests/outputs/hi.css +++ /dev/null @@ -1,3 +0,0 @@ -div:before { - content: "hi!"; -} diff --git a/vendor/leafo/lessphp/tests/outputs/ie.css b/vendor/leafo/lessphp/tests/outputs/ie.css deleted file mode 100644 index 7e4571c8..00000000 --- a/vendor/leafo/lessphp/tests/outputs/ie.css +++ /dev/null @@ -1,9 +0,0 @@ -foo { - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr=#c0ff3300,endColorstr=#ff000000); - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr=#c0ff3300,endColorstr=#ff000001); -} -foo { - filter: alpha(opacity=20); - filter: alpha(opacity=20,enabled=true); - filter: blaznicate(foo=bar,baz=bang bip,bart=#fa4600); -} diff --git a/vendor/leafo/lessphp/tests/outputs/import.css b/vendor/leafo/lessphp/tests/outputs/import.css deleted file mode 100644 index b76c25b5..00000000 --- a/vendor/leafo/lessphp/tests/outputs/import.css +++ /dev/null @@ -1,51 +0,0 @@ -@import "not-found"; -@import "something.css" media; -@import url("something.css") media; -@import url(something.css) media, screen, print; -b { - color: maroon; - padding: 16px; -} -body { - line-height: 10em; -} -body div.bright { - color: red; -} -body div.sad { - color: blue; -} -.one { - color: blue; -} -#merge-import-mixins .just-a-class { - background: red; -} -#merge-import-mixins .just-a-class { - background: blue; -} -#merge-import-mixins .hello { - height: 200px; -} -@media cool { - #merge-import-mixins { - color: red; - height: 200px; - } -} -#merge-import-mixins div { - background: red; - background: blue; -} -.inner { - content: "inner/file1.less"; -} -.inner { - content: "inner/file2.less"; -} -pre { - color: hello-from-file-3; -} -h2 { - background: url("../images/logo.png") no-repeat; -} diff --git a/vendor/leafo/lessphp/tests/outputs/interpolation.css b/vendor/leafo/lessphp/tests/outputs/interpolation.css deleted file mode 100644 index c3ff1f42..00000000 --- a/vendor/leafo/lessphp/tests/outputs/interpolation.css +++ /dev/null @@ -1,28 +0,0 @@ -div { - interp1: yes; - interp2: yes; - interp3: okay; -} -10"yeah" { - color: blue; -} -10 { - color: blue; -} -hello world 10 { - color: red; -} -#"yeah" { - color: "hello 10"; -} -[prop], -[prop="value3"], -[prop*="val3"], -[|prop~="val3"], -[*|prop$="val3"], -[ns|prop^="val3"], -[3^="val3"], -[3=3], -[3] { - attributes: yes; -} diff --git a/vendor/leafo/lessphp/tests/outputs/keyframes.css b/vendor/leafo/lessphp/tests/outputs/keyframes.css deleted file mode 100644 index cf62be11..00000000 --- a/vendor/leafo/lessphp/tests/outputs/keyframes.css +++ /dev/null @@ -1,48 +0,0 @@ -@keyframes 'bounce' { - from { - top: 100px; - animation-timing-function: ease-out; - } - 25% { - top: 50px; - animation-timing-function: ease-in; - } - 50% { - top: 100px; - animation-timing-function: ease-out; - } - 75% { - top: 75px; - animation-timing-function: ease-in; - } - to { - top: 100px; - } -} -@-webkit-keyframes flowouttoleft { - 0% { - -webkit-transform: translateX(0) scale(1); - } - 60%, - 70% { - -webkit-transform: translateX(0) scale(.7); - } - 100% { - -webkit-transform: translateX(-100%) scale(.7); - } -} -div { - animation-name: 'diagonal-slide'; - animation-duration: 5s; - animation-iteration-count: 10; -} -@keyframes 'diagonal-slide' { - from { - left: 0; - top: 0; - } - to { - left: 100px; - top: 100px; - } -} diff --git a/vendor/leafo/lessphp/tests/outputs/math.css b/vendor/leafo/lessphp/tests/outputs/math.css deleted file mode 100644 index 8d425f30..00000000 --- a/vendor/leafo/lessphp/tests/outputs/math.css +++ /dev/null @@ -1,69 +0,0 @@ -.unary { - sub: 10 -5; -} -.spaces { - sub1: 5; - sub2: 5; - add1: 15; - add2: 15; - div: 2; - mul1: 50; - mul2: 50; -} -.supress-division { - border-radius: 10px/10px; - border-radius: 10px/12px; - border-radius: hello(10px/10px) world; - font: 10px/30 sans-serif; - font: 10px/20px sans-serif; - font: 10px/22px sans-serif; - border-radius: 0 15px 15px 15px/0 50% 50% 50%; -} -.parens { - sub: 5; - add: 15; - div1: 2; - div2: 2; - mul: 50; -} -.keyword-names { - height: "hello" 25; -} -.negation { - neg1: -1px; - neg2: -1px; - neg3: -10; -} -.test { - single1: 5; - single2: 10; - single3: 10; - parens: 10 -2; - math1: 20; - math2: 20; - complex1: 71; - complex2: 6; - complex3: 6px 1em 2px 2; - var1: 8 4 4 4px; - var2: 96; - var3: 12; - complex4: 113; -} -.percents { - p1: 1000%; - p2: 1000%; - p3: 100%; - p4: 1000px; - p5: 1000%; - p6: 30%; - p7: 10%; - p8: 2%; -} -.misc { - x: 40px; - y: 40em; -} -.cond { - c1: false; - c2: true; -} diff --git a/vendor/leafo/lessphp/tests/outputs/media.css b/vendor/leafo/lessphp/tests/outputs/media.css deleted file mode 100644 index 99da8c31..00000000 --- a/vendor/leafo/lessphp/tests/outputs/media.css +++ /dev/null @@ -1,70 +0,0 @@ -@media screen,3D { - P { - color: green; - } -} -@media print { - body { - font-size: 10pt; - } -} -@media screen { - body { - font-size: 13px; - } -} -@media screen,print { - body { - line-height: 1.2; - } -} -@media all and (min-width: 0px) { - body { - line-height: 1.2; - } -} -@media all and (min-width: 0) { - body { - line-height: 1.2; - } -} -@media screen and (min-width: 102.5em) and (max-width: 117.9375em),screen and (min-width: 150em) { - body { - color: blue; - } -} -@media screen and (min-height: 110px) { - body { - color: red; - } -} -@media screen and (height: 100px) and (width: 110px),(size: 120px) { - body { - color: red; - } -} -@media test { - div { - height: 20px; - } -} -@media test and (hello) { - div { - color: red; - } - div pre { - color: orange; - } -} -@media yeah { - @page { - @media cool { - color: red; - } - } -} -@media (max-width: 599px) { - .helloworld { - color: blue; - } -} diff --git a/vendor/leafo/lessphp/tests/outputs/misc.css b/vendor/leafo/lessphp/tests/outputs/misc.css deleted file mode 100644 index 6c99cc39..00000000 --- a/vendor/leafo/lessphp/tests/outputs/misc.css +++ /dev/null @@ -1,68 +0,0 @@ -color: "aaa, bbb"; -.topbar { - background: url(/assets/images/test/topbar.png); -} -.hello { - test: empty-function("/assets/images/test/",40%,to(#fff)); -} -.css3 { - background-image: -webkit-gradient(linear,0% 0%,0% 90%,from(#E9A000),to(#A37000)); -} -.test, -.world { - border: 1px solid red; - color: url(http://mage-page.com); - string: "hello /* this is not a comment */"; - world: "// neither is this"; - string: 'hello /* this is not a comment */'; - world: '// neither is this'; - what-ever: 100px; - background: url(/*no comment here*/); -} -.urls { - background1: url("http://google.com"); - background2: url(http://google.com); - background3: url("http://google.com"); -} -.cool { - color: "aaa, bbb"; -} -.span-17 { - float: left; -} -.span-17 { - width: 660px; -} -.x { - float: left; - width: 660px; -} -.hi pre { - color: red; -} -.hi pre { - color: blue; -} -.rad pre { - color: red; -} -.rad pre { - color: blue; -} -hello { - numbers: 1.0 0.1 .1 1.; - numbers: 1.0s 0.1s .1s 1.s; - numbers: -1s -0.1s -0.1s -1s; - numbers: -1 -0.1 -0.1 -1; -} -#string { - hello: 'what\'s going on here'; - hello: 'blah blag @{ blah blah'; - join: "3434hello"; - join: 3434hello; -} -.duplicates { - hello: world; - hello: "world"; - hello: "what"; -} diff --git a/vendor/leafo/lessphp/tests/outputs/mixin_functions.css b/vendor/leafo/lessphp/tests/outputs/mixin_functions.css deleted file mode 100644 index 53785803..00000000 --- a/vendor/leafo/lessphp/tests/outputs/mixin_functions.css +++ /dev/null @@ -1,7 +0,0 @@ -body { - padding: 2.0em; - color: red; - margin: 10px; - height: 12px; - border-bottom: 1px solid green; -} diff --git a/vendor/leafo/lessphp/tests/outputs/mixin_merging.css b/vendor/leafo/lessphp/tests/outputs/mixin_merging.css deleted file mode 100644 index f396ba92..00000000 --- a/vendor/leafo/lessphp/tests/outputs/mixin_merging.css +++ /dev/null @@ -1,42 +0,0 @@ -#test1 div { - color:red; - height:10px; -} -#test1 p { height:10px; } -#test2 b { - color:red; - width:1px; -} -#test2 a, #test2 i { width:1px; } -#test3 a, #test3 i { width:1px; } -#test3 b { - width:1px; - color:red; -} -#test4 a { - color:blue; - margin:1px; -} -#test4 div, #test4 html { color:blue; } -#test5 img, #test5 strong { - padding:2px; - float:right; -} -#test6 div a, #test6 span a { - line-height:10px; - color:red; -} -#test7 div strong { - margin:1px; - color:red; -} -#test7 div b { color:red; } -#test7 span strong, #test7 span b { color:red; } -#test8 a i, #test8 b i { - background:red; - color:red; -} -#test8 a s, #test8 b s { - background:red; - color:blue; -} diff --git a/vendor/leafo/lessphp/tests/outputs/mixins.css b/vendor/leafo/lessphp/tests/outputs/mixins.css deleted file mode 100644 index cce87eb4..00000000 --- a/vendor/leafo/lessphp/tests/outputs/mixins.css +++ /dev/null @@ -1,92 +0,0 @@ -.bold { - font-size: 20px; - font-weight: bold; -} -body #window { - border-radius: 10px; - font-size: 20px; - font-weight: bold; - line-height: 30px; -} -#bundle .button { - display: block; - border: 1px solid black; - background-color: grey; -} -#bundle .button:hover { - background-color: white; -} -#header a { - color: orange; - display: block; - border: 1px solid black; - background-color: grey; -} -#header a:hover { - background-color: white; -} -div { - color: blue; - hello: world; -} -div b { - color: blue; -} -body { - color: blue; - hello: world; -} -body b { - color: blue; -} -.hello .world { - color: blue; -} -.foobar { - color: blue; -} -.eggs { - foo: 1px 2px; - bar: 1px 2px; - foo: 100 land; - bar: 100 land; -} -#hello { - cool: one two three cool; -} -#hello-important { - cool: one two three cool !important; -} -#world { - cool: "world"; -} -#another { - things: red blue green; - things: red blue green skip me; -} -#day .cool { - color: one two three; -} -#day .cool { - color: one two three skip me; -} -.mix-suffix { - color: red !important; - height: 20px !important; -} -.mix-suffix pre { - color: red; -} -.search-test { - color: #f00 !important; - color: #0f0 !important; -} -.cowboy { - color: blue; -} -.nav .nav-divider { - padding: 10px; -} -.nav-divider { - padding: 10px; -} diff --git a/vendor/leafo/lessphp/tests/outputs/nested.css b/vendor/leafo/lessphp/tests/outputs/nested.css deleted file mode 100644 index 454dcfcc..00000000 --- a/vendor/leafo/lessphp/tests/outputs/nested.css +++ /dev/null @@ -1,51 +0,0 @@ -#header { - color: black; -} -#header .navigation { - font-size: 12px; -} -#header .navigation .border .outside { - color: blue; -} -#header .logo { - width: 300px; -} -#header .logo:hover { - text-decoration: none; -} -a b ul li { - color: green; -} -div .cool { - color: green; -} -p .cool span { - color: yellow; -} -div another { - color: green; -} -p another span { - color: yellow; -} -b .something { - color: blue; -} -b.something { - color: blue; -} -.foo .bar .qux, -.foo .baz .qux { - display: block; -} -.qux .foo .bar, -.qux .foo .baz { - display: inline; -} -.qux .foo .bar .biz, -.qux .foo .baz .biz { - display: none; -} -b hello [x="&yeah"] { - color: red; -} diff --git a/vendor/leafo/lessphp/tests/outputs/nesting.css b/vendor/leafo/lessphp/tests/outputs/nesting.css deleted file mode 100644 index 804a56bf..00000000 --- a/vendor/leafo/lessphp/tests/outputs/nesting.css +++ /dev/null @@ -1,6 +0,0 @@ -#header .navigation .border .outside { color:blue; } -#header .navigation { font-size:12px; } -#header .logo:hover { text-decoration:none; } -#header .logo { width:300px; } -#header { color:black; } -a b ul li { color:green; } diff --git a/vendor/leafo/lessphp/tests/outputs/pattern_matching.css b/vendor/leafo/lessphp/tests/outputs/pattern_matching.css deleted file mode 100644 index 215371b0..00000000 --- a/vendor/leafo/lessphp/tests/outputs/pattern_matching.css +++ /dev/null @@ -1,72 +0,0 @@ -.class { - color: #a2a2a2; - display: block; -} -.zero { - zero: 0; - one: 1; - two: 2; - three: 3; -} -.one { - one: 1; - one-req: 1; - two: 2; - three: 3; -} -.two { - two: 2; - three: 3; -} -.three { - three-req: 3; - three: 3; -} -.left { - left: 1; -} -.right { - right: 1; -} -.border-right { - color: black; - border-right: 4px; -} -.border-left { - color: black; - border-left: 4px; -} -.only-right { - right: 33; -} -.only-left { - left: 33; -} -.left-right { - both: 330; -} -#hola { - color: blue; -} -#defaults_1 { - height: one; - height: two; - height: three; - height: four; -} -.thing { - color: red; -} -#aa { - color: green; - color: blue; - color: red; -} -#bb { - color: green; - color: blue; - color: red; -} -#cc { - color: blue; -} diff --git a/vendor/leafo/lessphp/tests/outputs/scopes.css b/vendor/leafo/lessphp/tests/outputs/scopes.css deleted file mode 100644 index ea2a4573..00000000 --- a/vendor/leafo/lessphp/tests/outputs/scopes.css +++ /dev/null @@ -1,11 +0,0 @@ -body div other world { - height: 50; -} -div other world { - height: 50; -} -pre { - height: 10; - height: 11; - height: 12; -} diff --git a/vendor/leafo/lessphp/tests/outputs/selector_expressions.css b/vendor/leafo/lessphp/tests/outputs/selector_expressions.css deleted file mode 100644 index 71d4a5d8..00000000 --- a/vendor/leafo/lessphp/tests/outputs/selector_expressions.css +++ /dev/null @@ -1,25 +0,0 @@ -something blue, -world { - color: blue; -} -.div (3434) { - height: 100px; -} -.div cool red { - height: 4000px; -} -.span5 { - color: 15; -} -.span4 { - color: 14; -} -.span3 { - color: 13; -} -.span2 { - color: 12; -} -.span1 { - color: 11; -} diff --git a/vendor/leafo/lessphp/tests/outputs/site_demos.css b/vendor/leafo/lessphp/tests/outputs/site_demos.css deleted file mode 100644 index 3428ad3a..00000000 --- a/vendor/leafo/lessphp/tests/outputs/site_demos.css +++ /dev/null @@ -1,76 +0,0 @@ -default .underline { - border-bottom: 1px solid green; -} -default #header { - color: black; - border: 1px solid #dd44dd; -} -default #header .navigation { - font-size: 12px; -} -default #header .navigation a { - border-bottom: 1px solid green; -} -default #header .logo { - width: 300px; -} -default #header .logo:hover { - text-decoration: none; -} -variables .variables { - width: 14cm; - height: 24px; - color: #888; - background: #6c94be; - font-family: "Trebuchet MS", Verdana, sans-serif; -} -mixins .bordered { - border-top: dotted 1px black; - border-bottom: solid 2px black; -} -mixins #menu a { - color: #111; - border-top: dotted 1px black; - border-bottom: solid 2px black; -} -mixins .post a { - color: red; - border-top: dotted 1px black; - border-bottom: solid 2px black; -} -nested-rules #header { - color: black; -} -nested-rules #header .navigation { - font-size: 12px; -} -nested-rules #header .logo { - width: 300px; -} -nested-rules #header .logo:hover { - text-decoration: none; -} -namespaces #bundle .button { - display: block; - border: 1px solid black; - background-color: grey; -} -namespaces #bundle .button:hover { - background-color: white; -} -namespaces #header a { - color: orange; - display: block; - border: 1px solid black; - background-color: grey; -} -namespaces #header a:hover { - background-color: white; -} -mixin-functions body { - padding: 2.0em; - color: red; - margin: 10px; - height: 12px; - border-bottom: 1px solid green; -} diff --git a/vendor/leafo/lessphp/tests/outputs/variables.css b/vendor/leafo/lessphp/tests/outputs/variables.css deleted file mode 100644 index c4857cc6..00000000 --- a/vendor/leafo/lessphp/tests/outputs/variables.css +++ /dev/null @@ -1,19 +0,0 @@ -outer1: 44px; -outer2: 44px; -.variables { - width: 14cm; - height: 24px; - margin-top: -20px; - margin-bottom: 30px; - color: #888899; - background: #6c94be; - font-family: "Trebuchet MS", Verdana, sans-serif; - margin: 3px; - font: 10px/12px serif; - font: 120%/120% serif; -} -.external { - color: #888; - border: 1px solid #3326cc; - background: rgba(23,68,149,0.5); -} diff --git a/vendor/leafo/lessphp/tests/outputs_lessjs/mixins-args.css b/vendor/leafo/lessphp/tests/outputs_lessjs/mixins-args.css deleted file mode 100644 index 0a8e6bee..00000000 --- a/vendor/leafo/lessphp/tests/outputs_lessjs/mixins-args.css +++ /dev/null @@ -1,113 +0,0 @@ -#hidden { - color: transparent; -} -#hidden1 { - color: transparent; -} -.two-args { - color: blue; - width: 10px; - height: 99%; - border: 2px dotted black; -} -.one-arg { - width: 15px; - height: 49%; -} -.no-parens { - width: 5px; - height: 49%; -} -.no-args { - width: 5px; - height: 49%; -} -.var-args { - width: 45; - height: 17%; -} -.multi-mix { - width: 10px; - height: 29%; - margin: 4; - padding: 5; -} -body { - padding: 30px; - color: #f00; -} -.scope-mix { - width: 8; -} -.content { - width: 600px; -} -.content .column { - margin: 600px; -} -#same-var-name { - radius: 5px; -} -#var-inside { - width: 10px; -} -.arguments { - border: 1px solid black; - width: 1px; -} -.arguments2 { - border: 0px; - width: 0px; -} -.arguments3 { - border: 0px; - width: 0px; -} -.arguments4 { - border: 0 1 2 3 4; - rest: 1 2 3 4; - width: 0; -} -.edge-case { - border: "{"; - width: "{"; -} -.slash-vs-math { - border-radius: 0.4px; - border-radius: 0.5px; - border-radius: 6px; -} -.comma-vs-semi-colon { - one: a; - two: b, c; - one: d, e; - two: f; - one: g; - one: h; - one: i; - one: j; - one: k; - two: l; - one: m, n; - one: o, p; - two: q; - one: r, s; - two: t; -} -#named-conflict { - four: a, 11, 12, 13; - four: a, 21, 22, 23; -} -.test-mixin-default-arg { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} -.selector { - margin: 2, 2, 2, 2; -} -.selector2 { - margin: 2, 2, 2, 2; -} -.selector3 { - margin: 4; -} diff --git a/vendor/leafo/lessphp/tests/outputs_lessjs/mixins-named-args.css b/vendor/leafo/lessphp/tests/outputs_lessjs/mixins-named-args.css deleted file mode 100644 index e460aa10..00000000 --- a/vendor/leafo/lessphp/tests/outputs_lessjs/mixins-named-args.css +++ /dev/null @@ -1,27 +0,0 @@ -.named-arg { - color: blue; - width: 5px; - height: 99%; - args: 1px 100%; - text-align: center; -} -.class { - width: 5px; - height: 19%; - args: 1px 20%; -} -.all-args-wrong-args { - width: 10px; - height: 9%; - args: 2px 10%; -} -.named-args2 { - width: 15px; - height: 49%; - color: #646464; -} -.named-args3 { - width: 5px; - height: 29%; - color: #123456; -} diff --git a/vendor/leafo/lessphp/tests/outputs_lessjs/strings.css b/vendor/leafo/lessphp/tests/outputs_lessjs/strings.css deleted file mode 100644 index f7b9c27d..00000000 --- a/vendor/leafo/lessphp/tests/outputs_lessjs/strings.css +++ /dev/null @@ -1,40 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: DX.Transform.MS.BS.filter(opacity=50); -} -#one-line { - image: url(http://tooks.com); -} -#crazy { - image: url(http://), "}", url("http://}"); -} -#interpolation { - url: "http://lesscss.org/dev/image.jpg"; - url2: "http://lesscss.org/image-256.jpg"; - url3: "http://lesscss.org#445566"; - url4: "http://lesscss.org/hello"; - url5: "http://lesscss.org/54.4px"; -} -.mix-mul-class { - color: blue; - color: red; - color: black; - color: orange; -} diff --git a/vendor/leafo/lessphp/tests/sort.php b/vendor/leafo/lessphp/tests/sort.php deleted file mode 100644 index 70b907ea..00000000 --- a/vendor/leafo/lessphp/tests/sort.php +++ /dev/null @@ -1,57 +0,0 @@ -coerceColor($value); - } - - return parent::compileValue($value); - } -} - -class SortingFormatter extends lessc_formatter_lessjs { - function sortKey($block) { - if (!isset($block->sortKey)) { - sort($block->selectors, SORT_STRING); - $block->sortKey = implode(",", $block->selectors); - } - - return $block->sortKey; - } - - function sortBlock($block) { - usort($block->children, function($a, $b) { - $sort = strcmp($this->sortKey($a), $this->sortKey($b)); - if ($sort == 0) { - // TODO - } - return $sort; - }); - - } - - function block($block) { - $this->sortBlock($block); - return parent::block($block); - } - -} - -$less = new lesscNormalized(); -$less->setFormatter(new SortingFormatter); -echo $less->parse(file_get_contents($fname)); - diff --git a/vendor/liuggio/statsd-php-client/CHANGELOG.md b/vendor/liuggio/statsd-php-client/CHANGELOG.md new file mode 100644 index 00000000..e7ee9a44 --- /dev/null +++ b/vendor/liuggio/statsd-php-client/CHANGELOG.md @@ -0,0 +1,17 @@ +CHANGELOG for 1.x.x +=================== + +This changelog references the relevant changes (bug and security fixes) done +in 1.x.x minor. + +To get the diff for a specific change, go to https://github.com/liuggio/statsd-php-client/commit/XXX where XXX is the change hash +To get the diff between two versions, go to https://github.com/liuggio/statsd-php-client/compare/v1.0.12...v1.0.13 + +### 1.0.14, 1.0.16 + * fix minor casing issue + * php 5.3.2 instead of php5.2 + +### 1.0.13 + * add changelog + * feature StatsdService abstracting Client/Factory usage + * feature Deal with sampling in StatsdService diff --git a/vendor/liuggio/statsd-php-client/README.md b/vendor/liuggio/statsd-php-client/README.md new file mode 100644 index 00000000..e7c6f67a --- /dev/null +++ b/vendor/liuggio/statsd-php-client/README.md @@ -0,0 +1,152 @@ +## statsd-php-client + +Be careful, see the [Upgrading section](Readme.md#upgrade) for <= v1.0.4, there's a BC. + +[![Build Status](https://secure.travis-ci.org/liuggio/statsd-php-client.png)](http://travis-ci.org/liuggio/statsd-php-client) [![Latest Stable Version](https://poser.pugx.org/liuggio/statsd-php-client/v/stable.png)](https://packagist.org/packages/liuggio/statsd-php-client) [![Total Downloads](https://poser.pugx.org/liuggio/statsd-php-client/downloads.png)](https://packagist.org/packages/liuggio/statsd-php-client) + +`statsd-php-client` is an Open Source, and **Object Oriented** Client for **etsy/statsd** written in php + +- `StatsdDataFactory` creates the `Liuggio\StatsdClient\Entity\StatsdDataInterface` Objects + +- `Sender` just sends data over the network (there are many sender) + +- `StatsdClient` sends the created objects via the `Sender` to the server + +## Why use this library instead the [statsd/php-example](https://github.com/etsy/statsd/blob/master/examples/php-example.php)? + +- You are wise. + +- You could also use monolog to redirect data to statsd + +- This library is tested. + +- This library optimizes the messages to send, compressing multiple messages in individual UDP packets. + +- This library pays attention to the maximum length of the UDP. + +- This library is made by Objects not array, but it also accepts array. + +- You do want to debug the packets, and using `SysLogSender` the packets will be logged in your `syslog` log (on debian-like distro: `tail -f /var/log/syslog`) + + +## Example + +1. create the Sender + +2. create the Client + +3. create the Factory + +4. the Factory will help you to create data + +5. the Client will send the data + +### Standard Usage + +```php +use Liuggio\StatsdClient\StatsdClient, + Liuggio\StatsdClient\Factory\StatsdDataFactory, + Liuggio\StatsdClient\Sender\SocketSender, + Liuggio\StatsdClient\Service\StatsdService; +// use Liuggio\StatsdClient\Sender\SysLogSender; + +$sender = new SocketSender(/*'localhost', 8126, 'udp'*/); +// $sender = new SysLogSender(); // enabling this, the packet will not send over the socket + +$client = new StatsdClient($sender); +$factory = new StatsdDataFactory('\Liuggio\StatsdClient\Entity\StatsdData'); +$service = new StatsdService($client, $factory); + +// create the metrics with the service +$service->timing('usageTime', 100); +$service->increment('visitor'); +$service->decrement('click'); +$service->gauge('gaugor', 333); +$service->set('uniques', 765); + +// send the data to statsd +$service->flush(); + +``` + +### Usage with Monolog + +```php +use Liuggio\StatsdClient\StatsdClient, + Liuggio\StatsdClient\Factory\StatsdDataFactory, + Liuggio\StatsdClient\Sender\SocketSender; +// use Liuggio\StatsdClient\Sender\SysLogSender; + +use Monolog\Logger; +use Liuggio\StatsdClient\Monolog\Handler\StatsDHandler; + +$sender = new SocketSender(/*'localhost', 8126, 'udp'*/); +// $sender = new SysLogSender(); // enabling this, the packet will not send over the socket +$client = new StatsdClient($sender); +$factory = new StatsdDataFactory(); + +$logger = new Logger('my_logger'); +$logger->pushHandler(new StatsDHandler($client, $factory, 'prefix', Logger::DEBUG)); + +$logger->addInfo('My logger is now ready'); +``` + +the output will be: `prefix.my_logger.INFO.My-logger:1|c" 36 Bytes` + + + + +## Short Theory + +### Easily Install StatSD and Graphite + +In order to try this application monitor you have to install etsy/statsd and Graphite + +see this blog post to install it with vagrant [Easy install statsd graphite](http://welcometothebundle.com/easily-install-statsd-and-graphite-with-vagrant/). + +#### [StatsD](https://github.com/etsy/statsd) + +StatsD is a simple daemon for easy stats aggregation + +#### [Graphite](http://graphite.wikidot.com/) + +Graphite is a Scalable Realtime Graphing + +#### The Client sends data with UDP (faster) + +https://www.google.com/search?q=tcp+vs+udp + +## Contribution + +Active contribution and patches are very welcome. +To keep things in shape we have quite a bunch of unit tests. If you're submitting pull requests please +make sure that they are still passing and if you add functionality please +take a look at the coverage as well it should be pretty high :) + +- First fork or clone the repository + +``` +git clone git://github.com/liuggio/statsd-php-client.git +cd statsd-php-client +``` + +- Install vendors: + +``` bash +composer.phar install +``` + +- This will give you proper results: + +``` bash +phpunit --coverage-html reports +``` + +## Upgrade + +BC from the v1.0.4 version, [see Sender and Client differences](https://github.com/liuggio/statsd-php-client/pull/5/files). + + +## TODO + +example with monolog diff --git a/vendor/liuggio/statsd-php-client/Readme.md b/vendor/liuggio/statsd-php-client/Readme.md deleted file mode 100644 index 81083e05..00000000 --- a/vendor/liuggio/statsd-php-client/Readme.md +++ /dev/null @@ -1,149 +0,0 @@ -## statsd-php-client - -Be careful, see the [Upgrading section](Readme.md#upgrade) for <= v1.0.4, there's a BC. - -[![Build Status](https://secure.travis-ci.org/liuggio/statsd-php-client.png)](http://travis-ci.org/liuggio/statsd-php-client) [![Latest Stable Version](https://poser.pugx.org/liuggio/statsd-php-client/v/stable.png)](https://packagist.org/packages/liuggio/statsd-php-client) [![Total Downloads](https://poser.pugx.org/liuggio/statsd-php-client/downloads.png)](https://packagist.org/packages/liuggio/statsd-php-client) - -`statsd-php-client` is an Open Source, and **Object Oriented** Client for **etsy/statsd** written in php - -- `StatsdDataFactory` creates the `Liuggio\StatsdClient\Entity\StatsdDataInterface` Objects - -- `Sender` just sends data over the network (there are many sender) - -- `StatsdClient` sends the created objects via the `Sender` to the server - -## Why use this library instead the [statsd/php-example](https://github.com/etsy/statsd/blob/master/examples/php-example.php)? - -- You are wise. - -- You could also use monolog to redirect data to statsd - -- This library is tested. - -- This library optimizes the messages to send, compressing multiple messages in individual UDP packets. - -- This library pays attention to the maximum length of the UDP. - -- This library is made by Objects not array, but it also accepts array. - -- You do want to debug the packets, and using `SysLogSender` the packets will be logged in your `syslog` log (on debian-like distro: `tail -f /var/log/syslog`) - - -## Example - -1. create the Sender - -2. create the Client - -3. create the Factory - -4. the Factory will help you to create data - -5. the Client will send the data - -### Standard Usage - -```php -use Liuggio\StatsdClient\StatsdClient, - Liuggio\StatsdClient\Factory\StatsdDataFactory, - Liuggio\StatsdClient\Sender\SocketSender; -// use Liuggio\StatsdClient\Sender\SysLogSender; - -$sender = new SocketSender(/*'localhost', 8126, 'udp'*/); -// $sender = new SysLogSender(); // enabling this, the packet will not send over the socket - -$client = new StatsdClient($sender); -$factory = new StatsdDataFactory('\Liuggio\StatsdClient\Entity\StatsdData'); - -// create the data with the factory -$data[] = $factory->timing('usageTime', 100); -$data[] = $factory->increment('visitor'); -$data[] = $factory->decrement('click'); -$data[] = $factory->gauge('gaugor', 333); -$data[] = $factory->set('uniques', 765); - -// send the data as array or directly as object -$client->send($data); -``` - -### Usage with Monolog - -```php -use Liuggio\StatsdClient\StatsdClient, - Liuggio\StatsdClient\Factory\StatsdDataFactory, - Liuggio\StatsdClient\Sender\SocketSender; -// use Liuggio\StatsdClient\Sender\SysLogSender; - -use Monolog\Logger; -use Liuggio\StatsdClient\Monolog\Handler\StatsDHandler; - -$sender = new SocketSender(/*'localhost', 8126, 'udp'*/); -// $sender = new SysLogSender(); // enabling this, the packet will not send over the socket -$client = new StatsdClient($sender); -$factory = new StatsdDataFactory(); - -$logger = new Logger('my_logger'); -$logger->pushHandler(new StatsDHandler($client, $factory, 'prefix', Logger::DEBUG)); - -$logger->addInfo('My logger is now ready'); -``` - -the output will be: `prefix.my_logger.INFO.My-logger:1|c" 36 Bytes` - - - - -## Short Theory - -### Easily Install StatSD and Graphite - -In order to try this application monitor you have to install etsy/statsd and Graphite - -see this blog post to install it with vagrant [Easy install statsd graphite](http://welcometothebundle.com/easily-install-statsd-and-graphite-with-vagrant/). - -#### [StatsD](https://github.com/etsy/statsd) - -StatsD is a simple daemon for easy stats aggregation - -#### [Graphite](http://graphite.wikidot.com/) - -Graphite is a Scalable Realtime Graphing - -#### The Client sends data with UDP (faster) - -https://www.google.com/search?q=tcp+vs+udp - -## Contribution - -Active contribution and patches are very welcome. -To keep things in shape we have quite a bunch of unit tests. If you're submitting pull requests please -make sure that they are still passing and if you add functionality please -take a look at the coverage as well it should be pretty high :) - -- First fork or clone the repository - -``` -git clone git://github.com/liuggio/statsd-php-client.git -cd statsd-php-client -``` - -- Install vendors: - -``` bash -composer.phar install -``` - -- This will give you proper results: - -``` bash -phpunit --coverage-html reports -``` - -## Upgrade - -BC from the v1.0.4 version, [see Sender and Client differences](https://github.com/liuggio/statsd-php-client/pull/5/files). - - -## TODO - -example with monolog diff --git a/vendor/liuggio/statsd-php-client/composer.json b/vendor/liuggio/statsd-php-client/composer.json index 705dbdf8..b47e0fd6 100644 --- a/vendor/liuggio/statsd-php-client/composer.json +++ b/vendor/liuggio/statsd-php-client/composer.json @@ -6,7 +6,7 @@ "type": "library", "license": "MIT", "require": { - "php": ">=5.2" + "php": ">=5.3.2" }, "authors": [ { diff --git a/vendor/liuggio/statsd-php-client/phpunit.xml b/vendor/liuggio/statsd-php-client/phpunit.xml new file mode 100644 index 00000000..621efd75 --- /dev/null +++ b/vendor/liuggio/statsd-php-client/phpunit.xml @@ -0,0 +1,15 @@ + + + + + + tests/Liuggio/StatsdClient + + + + + + src/Liuggio/ + + + \ No newline at end of file diff --git a/vendor/liuggio/statsd-php-client/phpunit.xml.dist b/vendor/liuggio/statsd-php-client/phpunit.xml.dist deleted file mode 100644 index 621efd75..00000000 --- a/vendor/liuggio/statsd-php-client/phpunit.xml.dist +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - tests/Liuggio/StatsdClient - - - - - - src/Liuggio/ - - - \ No newline at end of file diff --git a/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php b/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php index 9c6203db..2f030859 100644 --- a/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php +++ b/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdData.php @@ -10,6 +10,7 @@ class StatsdData implements StatsdDataInterface private $key; private $value; private $metric; + private $sampleRate = 1; /** * @param string $key @@ -54,6 +55,22 @@ class StatsdData implements StatsdDataInterface return $this->metric; } + /** + * @param float $sampleRate + */ + public function setSampleRate($sampleRate) + { + $this->sampleRate = $sampleRate; + } + + /** + * @return float + */ + public function getSampleRate() + { + return $this->sampleRate; + } + /** * @param bool $withMetric * @@ -62,10 +79,17 @@ class StatsdData implements StatsdDataInterface public function getMessage($withMetric = true) { if (!$withMetric) { - return sprintf('%s:%s', $this->getKey(), $this->getValue()); + $result = sprintf('%s:%s', $this->getKey(), $this->getValue()); } else { - return sprintf('%s:%s|%s', $this->getKey(), $this->getValue(), $this->getMetric()); + $result = sprintf('%s:%s|%s', $this->getKey(), $this->getValue(), $this->getMetric()); } + + $sampleRate = $this->getSampleRate(); + if($sampleRate < 1){ + $result.= "|@$sampleRate"; + } + + return $result; } /** diff --git a/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php b/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php index 846bc7cc..d7b07a80 100644 --- a/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php +++ b/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Entity/StatsdDataInterface.php @@ -33,6 +33,12 @@ interface StatsdDataInterface */ function getMessage(); + /** + * @abstract + * @return float + */ + function getSampleRate(); + /** * @abstract * @return string diff --git a/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php b/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php new file mode 100644 index 00000000..061e3510 --- /dev/null +++ b/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/Service/StatsdService.php @@ -0,0 +1,196 @@ +client = $client; + if (is_null($factory)) { + $factory = new StatsdDataFactory(); + } + $this->factory = $factory; + $this->setSamplingRate($samplingRate); + } + + /** + * Actually defines the sampling rate used by the service. + * If set to 0.1, the service will automatically discard 10% + * of the incoming metrics. It will also automatically flag these + * as sampled data to statsd. + * + * @param float $samplingRate + */ + public function setSamplingRate($samplingRate) + { + if ($samplingRate <= 0.0 || 1.0 < $samplingRate) { + throw new \LogicException('Sampling rate shall be within ]0, 1]'); + } + $this->samplingRate = $samplingRate; + $this->samplingFunction = function($min, $max){ + return rand($min, $max); + }; + } + + /** + * @return float + */ + public function getSamplingRate() + { + return $this->samplingRate; + } + + /** + * {@inheritdoc} + */ + public function timing($key, $time) + { + $this->appendToBuffer( + $this->factory->timing($key, $time) + ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function gauge($key, $value) + { + $this->appendToBuffer( + $this->factory->gauge($key, $value) + ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value) + { + $this->appendToBuffer( + $this->factory->set($key, $value) + ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function increment($key) + { + $this->appendToBuffer( + $this->factory->increment($key) + ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function decrement($key) + { + $this->appendToBuffer( + $this->factory->decrement($key) + ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function updateCount($key, $delta) + { + $this->appendToBuffer( + $this->factory->updateCount($key, $delta) + ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function produceStatsdData($key, $value = 1, $metric = StatsdDataInterface::STATSD_METRIC_COUNT) + { + throw new \BadFunctionCallException('produceStatsdData is not implemented'); + } + + /** + * @param callable $samplingFunction rand() function by default. + */ + public function setSamplingFunction(\Closure $samplingFunction) + { + $this->samplingFunction = $samplingFunction; + } + + private function appendToBuffer(StatsdData $data) + { + if($this->samplingRate < 1){ + $data->setSampleRate($this->samplingRate); + $result = call_user_func($this->samplingFunction, 0 , floor(1 / $this->samplingRate)); + if ($result == 0) { + array_push($this->buffer, $data); + }; + } else { + array_push($this->buffer, $data); + } + } + + /** + * Send all buffered data to statsd. + * + * @return $this + */ + public function flush() + { + $this->client->send($this->buffer); + $this->buffer = array(); + + return $this; + } +} diff --git a/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php b/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php index a1d232a5..c5c16fed 100644 --- a/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php +++ b/vendor/liuggio/statsd-php-client/src/Liuggio/StatsdClient/StatsdClient.php @@ -109,12 +109,10 @@ class StatsdClient implements StatsdClientInterface */ public function appendSampleRate($data, $sampleRate = 1) { - $sampledData = array(); if ($sampleRate < 1) { - foreach ($data as $key => $message) { - $sampledData[$key] = sprintf('%s|@%s', $message, $sampleRate); - } - $data = $sampledData; + array_walk($data, function(&$message, $key) use ($sampleRate) { + $message = sprintf('%s|@%s', $message, $sampleRate); + }); } return $data; diff --git a/vendor/liuggio/statsd-php-client/tests/Liuggio/StatsdClient/Service/StatsdServiceTest.php b/vendor/liuggio/statsd-php-client/tests/Liuggio/StatsdClient/Service/StatsdServiceTest.php new file mode 100644 index 00000000..dcf2710d --- /dev/null +++ b/vendor/liuggio/statsd-php-client/tests/Liuggio/StatsdClient/Service/StatsdServiceTest.php @@ -0,0 +1,86 @@ +clientMock = $this->getMockBuilder('Liuggio\StatsdClient\StatsdClient') + ->disableOriginalConstructor() + ->getMock(); + $this->factoryMock = $this->getMockBuilder('Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface') + ->disableOriginalConstructor() + ->getMock(); + } + + public function testConstructorWithoutFactory() + { + $dut = new StatsdService($this->clientMock); + $dut->timing('foo.bar', 123); + } + + public function testFactoryImplementation() + { + $data = new StatsdData(); + + // Configure the client mock. + $this->factoryMock->expects($this->once())->method('timing')->willReturn($data); + $this->factoryMock->expects($this->once())->method('gauge')->willReturn($data); + $this->factoryMock->expects($this->once())->method('set')->willReturn($data); + $this->factoryMock->expects($this->once())->method('increment')->willReturn($data); + $this->factoryMock->expects($this->once())->method('decrement')->willReturn($data); + $this->factoryMock->expects($this->once())->method('updateCount')->willReturn($data); + + // Actual test + $dut = new StatsdService($this->clientMock, $this->factoryMock); + $dut->timing('foo.bar', 123); + $dut->gauge('foo.bar', 123); + $dut->set('foo.bar', 123); + $dut->increment('foo.bar'); + $dut->decrement('foo.bar'); + $dut->updateCount('foo.bar', 123); + } + + public function testFlush() + { + $data = new StatsdData(); + $this->factoryMock->expects($this->once())->method('timing')->willReturn($data); + $this->clientMock->expects($this->once())->method('send') + ->with($this->equalTo(array($data))); + + // Actual test + $dut = new StatsdService($this->clientMock, $this->factoryMock); + $dut->timing('foobar', 123); + $dut->flush(); + } + + public function testSampling() + { + $tries = false; + $closure = function($a, $b) use (&$tries) { + $tries = !$tries; + return $tries ? 1 : 0; + }; + + $data = new StatsdData(); + $this->factoryMock->expects($this->exactly(2))->method('timing')->willReturn($data); + $this->clientMock->expects($this->once())->method('send') + ->with($this->equalTo(array($data))); + + // Actual test + $dut = new StatsdService($this->clientMock, $this->factoryMock); + $dut->setSamplingRate(0.1); + $dut->setSamplingFunction($closure); + $dut->timing('foo', 123); + $dut->timing('bar', 123); + $dut->flush(); + + $this->assertSame(0.1, $data->getSampleRate()); + } +} diff --git a/vendor/mediawiki/at-ease/COPYING b/vendor/mediawiki/at-ease/COPYING new file mode 100644 index 00000000..019694a9 --- /dev/null +++ b/vendor/mediawiki/at-ease/COPYING @@ -0,0 +1,342 @@ +== GNU GENERAL PUBLIC LICENSE == + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +=== Preamble === + +The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +== TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION == + +'''0.''' This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +'''1.''' You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +'''2.''' You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + '''a)''' You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + '''b)''' You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + '''c)''' If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +'''3.''' You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + '''a)''' Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + '''b)''' Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + '''c)''' Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +'''4.''' You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +'''5.''' You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +'''6.''' Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +'''7.''' If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +'''8.''' If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +'''9.''' The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +'''10.''' If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +=== NO WARRANTY === + +'''11.''' BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +'''12.''' IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + '''END OF TERMS AND CONDITIONS''' + +== How to Apply These Terms to Your New Programs == + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/vendor/mediawiki/at-ease/README.md b/vendor/mediawiki/at-ease/README.md new file mode 100644 index 00000000..578f78ce --- /dev/null +++ b/vendor/mediawiki/at-ease/README.md @@ -0,0 +1,59 @@ +[![Latest Stable Version]](https://packagist.org/packages/mediawiki/at-ease) [![License]](https://packagist.org/packages/mediawiki/at-ease) + +at-ease +======= + +at-ease is a PHP library that provides a safe alternative to PHP's +[@ error control operator][]. + +`@` is broken when `E_STRICT` is enabled and it causes an unlogged, +unexplained error if there is a fatal, which is hard to support. The proper +method of handling errors is to actually handle the errors. For example, if +you are thinking of using an error suppression operator to suppress an invalid +array index warning, you should instead perform an `isset()` check on the +array index before trying to access it. When possible, always prevent PHP +errors rather than catching and handling them afterward. It makes the code +more understandable and avoids dealing with slow error suppression methods. + +However, there are some cases where warnings are inevitable, even if you check +beforehand, like when accessing files. You can check that the file exists by +using `file_exists()` and `is_readable()`, but the file could have been +deleted by the time you go to read it. In that case, you can use this library +to suppress the warnings and prevent PHP from being noisy. + + +Usage +----- + + // Suppress warnings in a block of code: + \MediaWiki\suppressWarnings(); + $content = file_get_contents( 'foobar.txt' ); + \MediaWiki\restoreWarnings(); + + + // ..or in a callback function: + \MediaWiki\quietCall( 'file_get_contents', 'foobar.txt' ); + + +Running tests +------------- + + composer install --prefer-dist + composer test + + +History +------- + +This library was first introduced in [MediaWiki 1.3][] ([r4261][]). It was +split out of the MediaWiki codebase and published as an independent library +during the [MediaWiki 1.26][] development cycle. + + +--- +[@ error control operator]: https://php.net/manual/en/language.operators.errorcontrol.php +[MediaWiki 1.3]: https://www.mediawiki.org/wiki/MediaWiki_1.3 +[r4261]: https://www.mediawiki.org/wiki/Special:Code/MediaWiki/r4261 +[MediaWiki 1.26]: https://www.mediawiki.org/wiki/MediaWiki_1.26 +[Latest Stable Version]: https://poser.pugx.org/mediawiki/at-ease/v/stable.svg +[License]: https://poser.pugx.org/mediawiki/at-ease/license.svg diff --git a/vendor/mediawiki/at-ease/src/Functions.php b/vendor/mediawiki/at-ease/src/Functions.php new file mode 100644 index 00000000..0be91eb6 --- /dev/null +++ b/vendor/mediawiki/at-ease/src/Functions.php @@ -0,0 +1,75 @@ +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 00000000..41d072e1 --- /dev/null +++ b/vendor/monolog/monolog/CHANGELOG.mdown @@ -0,0 +1,226 @@ +### 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 00000000..56e08d55 --- /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 00000000..af745c8a --- /dev/null +++ b/vendor/monolog/monolog/README.mdown @@ -0,0 +1,302 @@ +Monolog - Logging for PHP 5.3+ [![Build Status](https://secure.travis-ci.org/Seldaek/monolog.png)](http://travis-ci.org/Seldaek/monolog) +============================== + +[![Total Downloads](https://poser.pugx.org/monolog/monolog/downloads.png)](https://packagist.org/packages/monolog/monolog) +[![Latest Stable Version](https://poser.pugx.org/monolog/monolog/v/stable.png)](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 +``` + +Usage +----- + +```php +pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); + +// add records to the log +$log->addWarning('Foo'); +$log->addError('Bar'); +``` + +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. + +Docs +==== + +**See the `doc` directory for more detailed documentation. +The following is only a list of all parts that come with Monolog.** + +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. + +### 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](https://github.com/Seldaek/monolog/blob/master/doc/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. + +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. + +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) + +Frameworks Integration +---------------------- + +- 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 00000000..239484b3 --- /dev/null +++ b/vendor/monolog/monolog/composer.json @@ -0,0 +1,61 @@ +{ + "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.8", + "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" + }, + "_": "phpunit/phpunit-mock-objects required in 2.3.0 due to https://github.com/sebastianbergmann/phpunit-mock-objects/issues/223", + "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.14.x-dev" + } + }, + "scripts": { + "test": "phpunit" + } +} diff --git a/vendor/monolog/monolog/doc/extending.md b/vendor/monolog/monolog/doc/extending.md new file mode 100644 index 00000000..bb39ddcf --- /dev/null +++ b/vendor/monolog/monolog/doc/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']``). diff --git a/vendor/monolog/monolog/doc/sockets.md b/vendor/monolog/monolog/doc/sockets.md new file mode 100644 index 00000000..fad30a9f --- /dev/null +++ b/vendor/monolog/monolog/doc/sockets.md @@ -0,0 +1,37 @@ +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. + +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/doc/usage.md b/vendor/monolog/monolog/doc/usage.md new file mode 100644 index 00000000..7585fa2a --- /dev/null +++ b/vendor/monolog/monolog/doc/usage.md @@ -0,0 +1,162 @@ +Using Monolog +============= + +Installation +------------ + +Monolog is available on Packagist ([monolog/monolog](http://packagist.org/packages/monolog/monolog)) +and as such installable via [Composer](http://getcomposer.org/). + +```bash +php composer.phar 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. + +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. + +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 [README file](https://github.com/Seldaek/monolog/blob/master/README.mdown) 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 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. diff --git a/vendor/monolog/monolog/phpunit.xml.dist b/vendor/monolog/monolog/phpunit.xml.dist new file mode 100644 index 00000000..20d82b63 --- /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 00000000..c8923354 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/ErrorHandler.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; + +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; + +/** + * 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 $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; + } + + 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(\Exception $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); + } + } + + /** + * @private + */ + public function handleError($code, $message, $file = '', $line = 0, $context = array()) + { + if (!(error_reporting() & $code)) { + return; + } + + $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)) { + $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']) + ); + } + } + + 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 00000000..56d3e278 --- /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 00000000..b0b0cf06 --- /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 00000000..af63d011 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php @@ -0,0 +1,104 @@ + + * + * 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) + { + $maxLength = 45; + + 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 00000000..b5de7511 --- /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 00000000..1e431750 --- /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 00000000..255d2887 --- /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 00000000..e5a1d2c4 --- /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 00000000..388e2266 --- /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 00000000..f02bceb0 --- /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 00000000..7a7b3b3c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php @@ -0,0 +1,165 @@ + + * + * 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_ + */ + 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 00000000..eb067bb7 --- /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 00000000..46bf41b3 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.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 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 '[resource]'; + } + + 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', '>=')) { + return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + return json_encode($data); + } +} 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 00000000..5d345d53 --- /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 00000000..654710a8 --- /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 00000000..69ede49a --- /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 00000000..6f18f72e --- /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 00000000..3eb83bd4 --- /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 00000000..a28ba02a --- /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 00000000..589ff779 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.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\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. + */ + public static function send() + { + // Check content type + foreach (headers_list() as $header) { + if (stripos($header, 'content-type:') === 0) { + if (stripos($header, 'text/html') === false) { + // This handler only works with HTML outputs + return; + } + break; + } + } + + if (count(self::$records)) { + echo ''; + 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 00000000..6d8136f7 --- /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 00000000..bc659349 --- /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 00000000..b3687c3d --- /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 00000000..db8e6552 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php @@ -0,0 +1,151 @@ + + * + * 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.']')) + ); + + if (curl_exec($this->httpConnection) === false) { + throw new \RuntimeException(sprintf('Curl error (code %s): %s', curl_errno($ch), curl_error($ch))); + } + } +} 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 00000000..b91ffec9 --- /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 00000000..e7f843c8 --- /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 00000000..96e5d57f --- /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 00000000..d1e1ee60 --- /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 00000000..dad82273 --- /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 00000000..c3e42efe --- /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 00000000..e3b403f6 --- /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 00000000..6e630852 --- /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 00000000..30a85dd6 --- /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 00000000..fee47950 --- /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 00000000..388692c4 --- /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 00000000..6eaaa9d4 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php @@ -0,0 +1,103 @@ + + * + * 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 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} + * + * @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 00000000..28c7b55f --- /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 00000000..99384d35 --- /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 00000000..d920c4ba --- /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 00000000..34d3437f --- /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/LogEntriesHandler.php b/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php new file mode 100644 index 00000000..bd56230f --- /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 00000000..9785cec0 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php @@ -0,0 +1,106 @@ + + * + * 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); + + if (curl_exec($ch) === false) { + throw new \RuntimeException(sprintf('Curl error (code %s): %s', curl_errno($ch), curl_error($ch))); + } + + curl_close($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 00000000..50ed6380 --- /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 00000000..6726e1e4 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; + +/** + * MandrillHandler uses cURL to send the emails to the Mandrill API + * + * @author Adam Nicholson + */ +class MandrillHandler extends MailHandler +{ + protected $client; + protected $message; + + /** + * @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, + ))); + + if (curl_exec($ch) === false) { + throw new \RuntimeException(sprintf('Curl error (code %s): %s', curl_errno($ch), curl_error($ch))); + } + curl_close($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 00000000..4724a7e2 --- /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 00000000..6c431f2b --- /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 00000000..5118a0e2 --- /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 00000000..8cb4ab38 --- /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 00000000..3754e45d --- /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 00000000..169bea0e --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php @@ -0,0 +1,243 @@ + + * + * 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 00000000..1ae85845 --- /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 00000000..9917b649 --- /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 00000000..7fedc16f --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php @@ -0,0 +1,190 @@ + + * + * 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']; + } + 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(); + } +} 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 00000000..ee8c2363 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.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\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; + + /** + * @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 + */ + public function __construct($redis, $key, $level = Logger::DEBUG, $bubble = true) + { + if (!(($redis instanceof \Predis\Client) || ($redis instanceof \Redis))) { + throw new \InvalidArgumentException('Predis\Client or Redis instance required'); + } + + $this->redisClient = $redis; + $this->redisKey = $key; + + parent::__construct($level, $bubble); + } + + protected function write(array $record) + { + $this->redisClient->rpush($this->redisKey, $record["formatted"]); + } + + /** + * {@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 00000000..81abf086 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.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 RollbarNotifier; +use Exception; +use Monolog\Logger; + +/** + * Sends errors to Rollbar + * + * @author Paul Statezny + */ +class RollbarHandler extends AbstractProcessingHandler +{ + /** + * Rollbar notifier + * + * @var RollbarNotifier + */ + protected $rollbarNotifier; + + /** + * @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) { + $this->rollbarNotifier->report_exception($record['context']['exception']); + } 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) + ); + } + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->rollbarNotifier->flush(); + } +} 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 00000000..4168c32f --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.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\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); + } + } + } + + 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 00000000..9509ae37 --- /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 00000000..c7a1c7e9 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php @@ -0,0 +1,292 @@ + + * + * 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']) + ); + + if ($this->useShortAttachment) { + $attachment['fields'] = array( + array( + 'title' => $record['level_name'], + 'value' => $record['message'], + 'short' => false + ) + ); + } else { + $attachment['fields'] = array( + array( + 'title' => 'Message', + 'value' => $record['message'], + 'short' => false + ), + 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 00000000..ee486f69 --- /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 type $boolean + */ + public function setPersistent($boolean) + { + $this->persistent = (boolean) $boolean; + } + + /** + * 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 00000000..7965db74 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php @@ -0,0 +1,104 @@ + + * + * 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; + + /** + * @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 \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->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\(.*?\): }', '', $msg); + } +} 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 00000000..003a1a2a --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.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\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; + } else if (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 00000000..47c73e12 --- /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 00000000..dcf3f1f9 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.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\Handler\SyslogUdp; + +class UdpSocket +{ + const DATAGRAM_MAX_LENGTH = 65023; + + 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() + { + socket_close($this->socket); + } + + protected function send($chunk) + { + 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 00000000..aa047c07 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.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\Logger; +use Monolog\Handler\SyslogUdp\UdpSocket; + +/** + * A Handler for logging to a remote syslogd server. + * + * @author Jesper Skovgaard Nielsen + */ +class SyslogUdpHandler extends AbstractSyslogHandler +{ + /** + * @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 00000000..80b7f283 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.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\Logger; + +/** + * Used for testing purposes. + * + * It records all records and gives you access to them for verification. + * + * @author Jordi Boggiano + */ +class TestHandler extends AbstractProcessingHandler +{ + protected $records = array(); + protected $recordsByLevel = array(); + + public function getRecords() + { + return $this->records; + } + + public function hasEmergency($record) + { + return $this->hasRecord($record, Logger::EMERGENCY); + } + + public function hasAlert($record) + { + return $this->hasRecord($record, Logger::ALERT); + } + + public function hasCritical($record) + { + return $this->hasRecord($record, Logger::CRITICAL); + } + + public function hasError($record) + { + return $this->hasRecord($record, Logger::ERROR); + } + + public function hasWarning($record) + { + return $this->hasRecord($record, Logger::WARNING); + } + + public function hasNotice($record) + { + return $this->hasRecord($record, Logger::NOTICE); + } + + public function hasInfo($record) + { + return $this->hasRecord($record, Logger::INFO); + } + + public function hasDebug($record) + { + return $this->hasRecord($record, Logger::DEBUG); + } + + public function hasEmergencyRecords() + { + return isset($this->recordsByLevel[Logger::EMERGENCY]); + } + + public function hasAlertRecords() + { + return isset($this->recordsByLevel[Logger::ALERT]); + } + + public function hasCriticalRecords() + { + return isset($this->recordsByLevel[Logger::CRITICAL]); + } + + public function hasErrorRecords() + { + return isset($this->recordsByLevel[Logger::ERROR]); + } + + public function hasWarningRecords() + { + return isset($this->recordsByLevel[Logger::WARNING]); + } + + public function hasNoticeRecords() + { + return isset($this->recordsByLevel[Logger::NOTICE]); + } + + public function hasInfoRecords() + { + return isset($this->recordsByLevel[Logger::INFO]); + } + + public function hasDebugRecords() + { + return isset($this->recordsByLevel[Logger::DEBUG]); + } + + protected function hasRecord($record, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + + if (is_array($record)) { + $record = $record['message']; + } + + foreach ($this->recordsByLevel[$level] as $rec) { + if ($rec['message'] === $record) { + return true; + } + } + + return false; + } + + public function hasEmergencyThatContains($message) + { + return $this->hasRecordThatContains($message, Logger::EMERGENCY); + } + + public function hasAlertThatContains($message) + { + return $this->hasRecordThatContains($message, Logger::ALERT); + } + + public function hasCriticalThatContains($message) + { + return $this->hasRecordThatContains($message, Logger::CRITICAL); + } + + public function hasErrorThatContains($message) + { + return $this->hasRecordThatContains($message, Logger::ERROR); + } + + public function hasWarningThatContains($message) + { + return $this->hasRecordThatContains($message, Logger::WARNING); + } + + public function hasNoticeThatContains($message) + { + return $this->hasRecordThatContains($message, Logger::NOTICE); + } + + public function hasInfoThatContains($message) + { + return $this->hasRecordThatContains($message, Logger::INFO); + } + + public function hasDebugThatContains($message) + { + return $this->hasRecordThatContains($message, Logger::DEBUG); + } + + public function hasRecordThatContains($message, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + + foreach ($this->recordsByLevel[$level] as $rec) { + if (strpos($rec['message'], $message) !== false) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } +} 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 00000000..05a88173 --- /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 00000000..f22cf218 --- /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 00000000..32e3dd92 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Logger.php @@ -0,0 +1,629 @@ + + * + * 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); + } + + /** + * @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 00000000..1899400d --- /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 00000000..294a295c --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.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\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; + + public function __construct($level = Logger::DEBUG, array $skipClassesPartials = array('Monolog\\')) + { + $this->level = Logger::toMonologLevel($level); + $this->skipClassesPartials = $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 (isset($trace[$i]['class'])) { + foreach ($this->skipClassesPartials as $part) { + if (strpos($trace[$i]['class'], $part) !== false) { + $i++; + continue 2; + } + } + 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; + } +} 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 00000000..552fd709 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.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\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'] = array_merge( + $record['extra'], + array( + '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 00000000..0820def4 --- /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 00000000..0c4dd9ab --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.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\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'] = array_merge( + $record['extra'], + array( + '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 00000000..9d3f5590 --- /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 00000000..c2686ce5 --- /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 00000000..2784cef4 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.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\Processor; + +/** + * Adds a tags array into record + * + * @author Martijn Riemers + */ +class TagProcessor +{ + private $tags; + + public function __construct(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 00000000..80270d08 --- /dev/null +++ b/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php @@ -0,0 +1,38 @@ + + * + * 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; + } +} 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 00000000..21f22a6e --- /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 00000000..a33cb7c4 --- /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 00000000..a9a3f301 --- /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 00000000..e7f7334e --- /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 00000000..546e5c26 --- /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 00000000..1b2fd97a --- /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 00000000..6ac14854 --- /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 00000000..69e20077 --- /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 00000000..c1b2e0ee --- /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]"}'."\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 00000000..6d59b3f3 --- /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 00000000..de4a3c2c --- /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 00000000..1554ef46 --- /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 00000000..4ffeded0 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -0,0 +1,254 @@ + + * + * 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]', + ), + '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); + } + + 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\]"%', + $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 00000000..c5a4ebb5 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php @@ -0,0 +1,98 @@ +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 00000000..52f15a36 --- /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 00000000..568eb9da --- /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 00000000..24d4f63c --- /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 00000000..a71d6251 --- /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 00000000..ffb1d746 --- /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 00000000..da8b3c39 --- /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 00000000..2f55faf8 --- /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 00000000..9fc4b388 --- /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 00000000..d67da90a --- /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 00000000..a38a8cb7 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.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 Monolog\TestCase; + +class DynamoDbHandlerTest extends TestCase +{ + 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 00000000..1687074b --- /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 00000000..99785cbb --- /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 00000000..31b7686a --- /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 00000000..8e31e9b8 --- /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 00000000..0eb10a63 --- /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/FleepHookHandlerTest.php b/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php new file mode 100644 index 00000000..91cdd312 --- /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 00000000..4b120d51 --- /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 00000000..9d007b13 --- /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 00000000..8cdd64f4 --- /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 00000000..873d92fb --- /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 00000000..c6298a6e --- /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 00000000..ff773c98 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php @@ -0,0 +1,240 @@ + + * + * 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 \Monolog\Handler\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 \Monolog\Handler\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 00000000..7af60be8 --- /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 00000000..6754f3d6 --- /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 00000000..a0833225 --- /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 00000000..0fdef63a --- /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 00000000..c2553ee4 --- /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 00000000..4eda6155 --- /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 00000000..292df78c --- /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 00000000..81684c5e --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php @@ -0,0 +1,271 @@ + + * + * 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() + { + $exception = new Exception(); + $this->errorDispatcher->expects($this->once())->method('dispatchException')->with( + $this->equalTo($exception) + ); + $errorHandler = ErrorHandler::register($this->initLogger(), false, false); + $errorHandler->registerExceptionHandler(null, false); + $errorHandler->handleException($exception); + } + + /** + * @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 00000000..64eaab16 --- /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 00000000..89408236 --- /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 00000000..9a9d1006 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.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\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 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['sentry.interfaces.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['sentry.interfaces.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 00000000..3629f8a2 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace 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); + } +} 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 00000000..f4cefda1 --- /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 00000000..b354cee1 --- /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 00000000..d657fae3 --- /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 00000000..2e3d504a --- /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 00000000..44d3d9f1 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php @@ -0,0 +1,118 @@ + + * + * 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('/foo/bar/baz/'.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 00000000..ac885220 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php @@ -0,0 +1,65 @@ +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); + } +} 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 00000000..8f9e46bf --- /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 00000000..497812b3 --- /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 00000000..2a79fdc6 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.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\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)); + $this->assertFalse($handler->{'has'.$method.'ThatContains'}('test')); + $this->assertFalse($handler->{'has'.$method.'Records'}()); + $handler->handle($record); + + $this->assertFalse($handler->{'has'.$method}('bar')); + $this->assertTrue($handler->{'has'.$method}($record)); + $this->assertTrue($handler->{'has'.$method}('test'.$method)); + $this->assertTrue($handler->{'has'.$method.'ThatContains'}('test')); + $this->assertTrue($handler->{'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 00000000..bcaf52b3 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.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\Handler; + +use Monolog\TestCase; + +/** + * @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"); + } +} 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 00000000..8d37a1fc --- /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 00000000..416039e6 --- /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 00000000..146b6f1b --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/LoggerTest.php @@ -0,0 +1,447 @@ + + * + * 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::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 00000000..5adb505d --- /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 00000000..0dd411d7 --- /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 00000000..eb666144 --- /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 00000000..4692dbfc --- /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 00000000..458d2a33 --- /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 00000000..81bfbdc3 --- /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 00000000..851a9dc2 --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/TagProcessorTest.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 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']); + } +} 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 00000000..7ced62ca --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/Processor/UidProcessorTest.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\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']); + } +} 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 00000000..dba89412 --- /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 00000000..ab899449 --- /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 00000000..29925f8a --- /dev/null +++ b/vendor/monolog/monolog/tests/Monolog/RegistryTest.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; + + +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), + ), + ); + } +} diff --git a/vendor/monolog/monolog/tests/Monolog/TestCase.php b/vendor/monolog/monolog/tests/Monolog/TestCase.php new file mode 100644 index 00000000..cae79340 --- /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/nmred/kafka-php/LICENSE b/vendor/nmred/kafka-php/LICENSE new file mode 100644 index 00000000..96d08492 --- /dev/null +++ b/vendor/nmred/kafka-php/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2014, SWANSOFT +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 the {organization} nor the names of its + 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 HOLDER 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/nmred/kafka-php/README.md b/vendor/nmred/kafka-php/README.md new file mode 100644 index 00000000..5ed12e23 --- /dev/null +++ b/vendor/nmred/kafka-php/README.md @@ -0,0 +1,496 @@ +Kafka-php +========== + +[![Build Status](https://travis-ci.org/nmred/kafka-php.svg?branch=master)](https://travis-ci.org/nmred/Kafka-php) + +Kafka-php is a php client with Zookeeper integration for apache Kafka. It only supports the latest version of Kafka 0.8 which is still under development, so this module is _not production ready_ so far. + +The Zookeeper integration does the following jobs: + +* Loads broker metadata from Zookeeper before we can communicate with the Kafka server +* Watches broker state, if broker changes, the client will refresh broker and topic metadata stored in the client + +## Requirements + +* Minimum PHP version: 5.3.3. +* Apache Kafka 0.8.x +* You need to have access to your Kafka instance and be able to connect through TCP. You can obtain a copy and instructions on how to setup kafka at https://github.com/kafka-dev/kafka [kafka-08-quick-start](https://cwiki.apache.org/KAFKA/kafka-08-quick-start.html) +* The [PHP Zookeeper extension](https://github.com/andreiz/php-zookeeper) is required if you want to use the Zookeeper-based consumer. +* Productor can not dependency zookeeper + +## Installation +Add the lib directory to the PHP include_path and use an autoloader like the one in the examples directory (the code follows the PEAR/Zend one-class-per-file convention). + +## Composer Install + +Simply add a dependency on nmred/kafka-php to your project's composer.json file if you use Composer to manage the dependencies of your project. Here is a minimal example of a composer.json file : + +``` +{ + "require": { + "nmred/kafka-php": "0.1.*" + } +} +``` + +## Produce + +### \Kafka\Produce::getInstance($hostList, $timeout) + +* `hostList` : zookeeper host list , example 127.0.0.1:2181,192.168.1.114:2181 +* `timeout` : zookeeper timeout + +### \Kafka\Produce::setRequireAck($ack = -1) + +* `ack`: This field indicates how many acknowledgements the servers should receive before responding to the request. + +### \Kafka\Produce::setMessages($topicName, $partitionId, $messages) + +* `topicName` : The topic that data is being published to. +* `partitionId` : The partition that data is being published to. +* `messages` : [Array] publish message. + +### \Kafka\Produce::send() + +send message sets to the server. + +### Example + +``` php +$produce = \Kafka\Produce::getInstance('localhost:2181', 3000); + +$produce->setRequireAck(-1); +$produce->setMessages('test', 0, array('test1111111')); +$produce->setMessages('test6', 0, array('test1111111')); +$produce->setMessages('test6', 2, array('test1111111')); +$produce->setMessages('test6', 1, array('test111111111133')); +$result = $produce->send(); +var_dump($result); + +``` + +## Consumer + +### \Kafka\Consumer::getInstance($hostList, $timeout) + +* `hostList` : zookeeper host list , example 127.0.0.1:2181,192.168.1.114:2181 +* `timeout` : zookeeper timeout + +### \Kafka\Consumer::setGroup($groupName) + +* `groupName` : Specify consumer group. + +### \Kafka\Consumer::setPartition($topicName, $partitionId, $offset = 0) + +* `topicName` : The topic that data is being fetch to. +* `partitionId` : The partition that data is being fetch to. +* `offset`: set fetch offset. default `0`. + +### \Kafka\Consumer::fetch() + +return fetch message Iterator. `\Kafka\Protocol\Fetch\Topic` + +### \Kafka\Protocol\Fetch\Topic + +this object is iterator + +`key` : topic name +`value`: `\Kafka\Protocol\Fetch\Partition` + +### \Kafka\Protocol\Fetch\Partition + +this object is iterator. + +`key`: partition id +`value`: messageSet object + +#### \Kafka\Protocol\Fetch\Partition::getErrCode() + +return partition fetch errcode. + +#### \Kafka\Protocol\Fetch\Partition::getHighOffset() + +return partition fetch offset. + +### \Kafka\Protocol\Fetch\MessageSet + +this object is iterator. `\Kafka\Protocol\Fetch\Message` + +### Example + +``` php +$consumer = \Kafka\Consumer::getInstance('localhost:2181'); + +$consumer->setGroup('testgroup'); +$consumer->setPartition('test', 0); +$consumer->setPartition('test6', 2, 10); +$result = $consumer->fetch(); +foreach ($result as $topicName => $topic) { + foreach ($topic as $partId => $partition) { + var_dump($partition->getHighOffset()); + foreach ($partition as $message) { + var_dump((string)$message); + } + } +} +``` + +## Basic Protocol +### Produce API + +The produce API is used to send message sets to the server. For efficiency it allows sending message sets intended for many topic partitions in a single request. + +\Kafka\Protocol\Encoder::produceRequest + +#### Param struct +``` php +array( + 'required_ack' => 1, + // This field indicates how many acknowledgements the servers should receive before responding to the request. default `0` + // If it is 0 the server will not send any response + // If it is -1 the server will block until the message is committed by all in sync replicas before sending a response + // For any number > 1 the server will block waiting for this number of acknowledgements to occur + 'timeout' => 1000, + // This provides a maximum time in milliseconds the server can await the receipt of the number of acknowledgements in RequiredAcks. + 'data' => array( + array( + 'topic_name' => 'testtopic', + // The topic that data is being published to.[String] + 'partitions' => array( + array( + 'partition_id' => 0, + // The partition that data is being published to. + 'messages' => array( + 'message1', + // [String] message + ), + ), + ), + ), + ), +); +``` + +#### Return + +Array + +#### Example + +``` php + +$data = array( + 'required_ack' => 1, + 'timeout' => 1000, + 'data' => array( + array( + 'topic_name' => 'test', + 'partitions' => array( + array( + 'partition_id' => 0, + 'messages' => array( + 'message1', + 'message2', + ), + ), + ), + ), + ), +); + +$conn = new \Kafka\Socket('localhost', '9092'); +$conn->connect(); +$encoder = new \Kafka\Protocol\Encoder($conn); +$encoder->produceRequest($data); + +$decoder = new \Kafka\Protocol\Decoder($conn); +$result = $decoder->produceResponse(); +var_dump($result); + +``` +### Fetch API + +The fetch API is used to fetch a chunk of one or more logs for some topic-partitions. Logically one specifies the topics, partitions, and starting offset at which to begin the fetch and gets back a chunk of messages + +\Kafka\Protocol\Encoder::fetchRequest + +#### Param struct +``` php +array( + 'replica_id' => -1, + // The replica id indicates the node id of the replica initiating this request. default `-1` + 'max_wait_time' => 100, + // The max wait time is the maximum amount of time in milliseconds to block waiting if insufficient data is available at the time the request is issued. default 100 ms. + 'min_bytes' => 64 * 1024 // 64k + // This is the minimum number of bytes of messages that must be available to give a response. default 64k. + 'data' => array( + array( + 'topic_name' => 'testtopic', + // The topic that data is being published to.[String] + 'partitions' => array( + array( + 'partition_id' => 0, + // The partition that data is being published to. + 'offset' => 0, + // The offset to begin this fetch from. default 0 + 'max_bytes' => 100 * 1024 * 1024, + // This is the minimum number of bytes of messages that must be available to give a response. default 100Mb + ), + ), + ), + ), +); +``` + +#### Return + +\Kafka\Protocol\Fetch\Topic iterator + +#### Example +``` php + +$data = array( + 'data' => array( + array( + 'topic_name' => 'test', + 'partitions' => array( + array( + 'partition_id' => 0, + 'offset' => 0, + ), + ), + ), + ), +); + +$conn = new \Kafka\Socket('localhost', '9092'); +$conn->connect(); +$encoder = new \Kafka\Protocol\Encoder($conn); +$encoder->fetchRequest($data); + +$decoder = new \Kafka\Protocol\Decoder($conn); +$result = $decoder->fetchResponse(); +var_dump($result); + +``` +### Offset API + +This API describes the valid offset range available for a set of topic-partitions. As with the produce and fetch APIs requests must be directed to the broker that is currently the leader for the partitions in question. This can be determined using the metadata API. + +\Kafka\Protocol\Encoder::offsetRequest + +####param struct +``` php +array( + 'replica_id' => -1, + // The replica id indicates the node id of the replica initiating this request. default `-1` + 'data' => array( + array( + 'topic_name' => 'testtopic', + // The topic that data is being published to.[String] + 'partitions' => array( + array( + 'partition_id' => 0, + // The partition that get offset . + 'time' => -1, + // Used to ask for all messages before a certain time (ms). + // Specify -1 to receive the latest offsets + // Specify -2 to receive the earliest available offset. + 'max_offset' => 1, + // max return offset element. default 10000. + ), + ), + ), + ), +); +``` + +#### Return + +Array. + +#### Example + +``` php + +$data = array( + 'data' => array( + array( + 'topic_name' => 'test', + 'partitions' => array( + array( + 'partition_id' => 0, + 'max_offset' => 10, + 'time' => -1, + ), + ), + ), + ), +); + +$conn = new \Kafka\Socket('localhost', '9092'); +$conn->connect(); +$encoder = new \Kafka\Protocol\Encoder($conn); +$encoder->offsetRequest($data); + +$decoder = new \Kafka\Protocol\Decoder($conn); +$result = $decoder->offsetResponse(); +var_dump($result); + +``` +### Metadata API + +The metdata returned is at the partition level, but grouped together by topic for convenience and to avoid redundancy. For each partition the metadata contains the information for the leader as well as for all the replicas and the list of replicas that are currently in-sync. + +\Kafka\Protocol\Encoder::metadataRequest + +####param struct +``` php +array( + 'topic_name1', // topic name +); +``` + +#### Return + +Array. + +#### Example + +``` php + +$data = array( + 'test' +); + +$conn = new \Kafka\Socket('localhost', '9092'); +$conn->connect(); +$encoder = new \Kafka\Protocol\Encoder($conn); +$encoder->metadataRequest($data); + +$decoder = new \Kafka\Protocol\Decoder($conn); +$result = $decoder->metadataResponse(); +var_dump($result); + +``` +### Offset Commit API + +These APIs allow for centralized management of offsets. + +\Kafka\Protocol\Encoder::commitOffsetRequest + +####param struct +``` php +array( + 'group_id' => 'testgroup', + // consumer group + 'data' => array( + array( + 'topic_name' => 'testtopic', + // The topic that data is being published to.[String] + 'partitions' => array( + array( + 'partition_id' => 0, + // The partition that get offset . + 'offset' => 0, + // The offset to begin this fetch from. + 'time' => -1, + // If the time stamp field is set to -1, then the broker sets the time stamp to the receive time before committing the offset. + ), + ), + ), + ), +); +``` + +#### Return + +Array. + +#### Example + +``` php +$data = array( + 'group_id' => 'testgroup', + 'data' => array( + array( + 'topic_name' => 'test', + 'partitions' => array( + array( + 'partition_id' => 0, + 'offset' => 2, + ), + ), + ), + ), +); + + +$conn = new \Kafka\Socket('localhost', '9092'); +$conn->connect(); +$encoder = new \Kafka\Protocol\Encoder($conn); +$encoder->commitOffsetRequest($data); + +$decoder = new \Kafka\Protocol\Decoder($conn); +$result = $decoder->commitOffsetResponse(); +var_dump($result); + +``` +### Offset Fetch API + +These APIs allow for centralized management of offsets. + +\Kafka\Protocol\Encoder::fetchOffsetRequest + +####param struct +``` php +array( + 'group_id' => 'testgroup', + // consumer group + 'data' => array( + array( + 'topic_name' => 'testtopic', + // The topic that data is being published to.[String] + 'partitions' => array( + array( + 'partition_id' => 0, + // The partition that get offset . + ), + ), + ), + ), +); +``` + +#### Return + +Array. + +#### Example + +``` php +$data = array( + 'group_id' => 'testgroup', + 'data' => array( + array( + 'topic_name' => 'test', + 'partitions' => array( + array( + 'partition_id' => 0, + ), + ), + ), + ), +); + + +$conn = new \Kafka\Socket('localhost', '9092'); +$conn->connect(); +$encoder = new \Kafka\Protocol\Encoder($conn); +$encoder->fetchOffsetRequest($data); + +$decoder = new \Kafka\Protocol\Decoder($conn); +$result = $decoder->fetchOffsetResponse(); +var_dump($result); + +``` diff --git a/vendor/nmred/kafka-php/src/Kafka/Client.php b/vendor/nmred/kafka-php/src/Kafka/Client.php new file mode 100644 index 00000000..a38e705b --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Client.php @@ -0,0 +1,290 @@ + 0, + 'RecvTimeoutUsec' => 750000, + 'SendTimeoutSec' => 0, + 'SendTimeoutUsec' => 100000, + ); + + // }}} + // {{{ functions + // {{{ public function __construct() + + /** + * __construct + * + * @access public + * @return void + */ + public function __construct(ClusterMetaData $metadata) + { + $this->metadata = $metadata; + if (method_exists($metadata, 'setClient')) { + $this->metadata->setClient($this); + } + } + + /** + * update stream options + * + * @param array $options + */ + public function setStreamOptions($options = array()) + { + // Merge the arrays + $this->streamOptions = array_merge($this->streamOptions, $options); + $this->updateStreamOptions(); + } + + /** + * @access public + * @param $name - name of stream option + * @param $value - value for option + */ + public function setStreamOption($name, $value) + { + $this->streamOptions[$name] = $value; + $this->updateStreamOptions(); + } + + /** + * @access public + * @param $name - name of option + * @return mixed + */ + public function getStreamOption($name) + { + if (array_key_exists($name, $this->streamOptions)) { + return $this->streamOptions[$name]; + } + return null; + } + + /** + * @access private + */ + private function updateStreamOptions() + { + // Loop thru each stream + foreach (self::$stream as $host => $streams) { + foreach ($streams as $key => $info) { + // Update options + if (isset($info['stream'])) { + /** @var \Kafka\Socket $stream */ + $stream = $info['stream']; + $stream->setRecvTimeoutSec($this->streamOptions['RecvTimeoutSec']); + $stream->setRecvTimeoutUsec($this->streamOptions['SendTimeoutUsec']); + $stream->setSendTimeoutSec($this->streamOptions['SendTimeoutSec']); + $stream->setSendTimeoutUsec($this->streamOptions['SendTimeoutUsec']); + } + } + } + } + + // }}} + // {{{ public function getBrokers() + + /** + * get broker server + * + * @access public + * @return void + */ + public function getBrokers() + { + if (empty($this->hostList)) { + $brokerList = $this->metadata->listBrokers(); + foreach ($brokerList as $brokerId => $info) { + if (!isset($info['host']) || !isset($info['port'])) { + continue; + } + $this->hostList[$brokerId] = $info['host'] . ':' . $info['port']; + } + } + + return $this->hostList; + } + + // }}} + // {{{ public function getHostByPartition() + + /** + * get broker host by topic partition + * + * @param string $topicName + * @param int $partitionId + * @access public + * @return string + */ + public function getHostByPartition($topicName, $partitionId = 0) + { + $partitionInfo = $this->metadata->getPartitionState($topicName, $partitionId); + if (!$partitionInfo) { + throw new \Kafka\Exception('topic:' . $topicName . ', partition id: ' . $partitionId . ' is not exists.'); + } + + $hostList = $this->getBrokers(); + if (isset($partitionInfo['leader']) && isset($hostList[$partitionInfo['leader']])) { + return $hostList[$partitionInfo['leader']]; + } else { + throw new \Kafka\Exception('can\'t find broker host.'); + } + } + + // }}} + // {{{ public function getZooKeeper() + + /** + * get kafka zookeeper object + * + * @access public + * @return \Kafka\ZooKeeper + */ + public function getZooKeeper() + { + if ($this->metadata instanceof \Kafka\ZooKeeper) { + return $this->metadata; + } else { + throw new \Kafka\Exception( 'ZooKeeper was not provided' ); + } + } + + // }}} + // {{{ public function getStream() + + /** + * get broker broker connect + * + * @param string $host + * @access private + * @return void + */ + public function getStream($host, $lockKey = null) + { + if (!$lockKey) { + $lockKey = uniqid($host); + } + + list($hostname, $port) = explode(':', $host); + // find unlock stream + if (isset(self::$stream[$host])) { + foreach (self::$stream[$host] as $key => $info) { + if ($info['locked']) { + continue; + } else { + self::$stream[$host][$key]['locked'] = true; + $info['stream']->connect(); + return array('key' => $key, 'stream' => $info['stream']); + } + } + } + + // no idle stream + $stream = new \Kafka\Socket($hostname, $port, $this->getStreamOption('RecvTimeoutSec'), $this->getStreamOption('RecvTimeoutUsec'), $this->getStreamOption('SendTimeoutSec'), $this->getStreamOption('SendTimeoutUsec')); + $stream->connect(); + self::$stream[$host][$lockKey] = array( + 'locked' => true, + 'stream' => $stream, + ); + return array('key' => $lockKey, 'stream' => $stream); + } + + // }}} + // {{{ public function freeStream() + + /** + * free stream pool + * + * @param string $key + * @access public + * @return void + */ + public function freeStream($key) + { + foreach (self::$stream as $host => $values) { + if (isset($values[$key])) { + self::$stream[$host][$key]['locked'] = false; + } + } + } + + // }}} + // {{{ public function getTopicDetail() + + /** + * get topic detail info + * + * @param string $topicName + * @return array + */ + public function getTopicDetail($topicName) + { + return $this->metadata->getTopicDetail($topicName); + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/ClusterMetaData.php b/vendor/nmred/kafka-php/src/Kafka/ClusterMetaData.php new file mode 100644 index 00000000..e9b3d064 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/ClusterMetaData.php @@ -0,0 +1,53 @@ +client = new \Kafka\Client($zookeeper); + } + + // }}} + // {{{ public function clearPayload() + + /** + * clearPayload + * + * @access public + * @return void + */ + public function clearPayload() + { + $this->payload = array(); + } + + // }}} + // {{{ public function setTopic() + + /** + * set topic name + * + * @access public + * @return void + */ + public function setTopic($topicName, $defaultOffset = null) + { + $parts = $this->client->getTopicDetail($topicName); + if (!isset($parts['partitions']) || empty($parts['partitions'])) { + // set topic fail. + return $this; + } + + foreach ($parts['partitions'] as $partId => $info) { + $this->setPartition($topicName, $partId, $defaultOffset); + } + + return $this; + } + + // }}} + // {{{ public function setPartition() + + /** + * set topic partition + * + * @access public + * @return void + */ + public function setPartition($topicName, $partitionId = 0, $offset = null) + { + if (is_null($offset)) { + if ($this->fromOffset) { + $offsetObject = new \Kafka\Offset($this->client, $this->group, $topicName, $partitionId); + $offset = $offsetObject->getOffset($this->offsetStrategy); + \Kafka\Log::log('topic name:' . $topicName . ', part:' . $partitionId . 'get offset from kafka server, offet:' . $offset, LOG_DEBUG); + } else { + $offset = 0; + } + } + $this->payload[$topicName][$partitionId] = $offset; + + return $this; + } + + // }}} + // {{{ public function setFromOffset() + + /** + * set whether starting offset fetch + * + * @param boolean $fromOffset + * @access public + * @return void + */ + public function setFromOffset($fromOffset) + { + $this->fromOffset = (boolean) $fromOffset; + } + + // }}} + // {{{ public function setMaxBytes() + + /** + * set fetch message max bytes + * + * @param int $maxSize + * @access public + * @return void + */ + public function setMaxBytes($maxSize) + { + $this->maxSize = $maxSize; + } + + // }}} + // {{{ public function setGroup() + + /** + * set consumer group + * + * @param string $group + * @access public + * @return void + */ + public function setGroup($group) + { + $this->group = (string) $group; + return $this; + } + + // }}} + // {{{ public function fetch() + + /** + * fetch message to broker + * + * @access public + * @return void + */ + public function fetch() + { + $data = $this->_formatPayload(); + if (empty($data)) { + return false; + } + + $responseData = array(); + $streams = array(); + foreach ($data as $host => $requestData) { + $connArr = $this->client->getStream($host); + $conn = $connArr['stream']; + $encoder = new \Kafka\Protocol\Encoder($conn); + $encoder->fetchRequest($requestData); + $streams[$connArr['key']] = $conn; + } + + $fetch = new \Kafka\Protocol\Fetch\Topic($streams, $data); + + // register fetch helper + $freeStream = new \Kafka\Protocol\Fetch\Helper\FreeStream($this->client); + $freeStream->setStreams($streams); + \Kafka\Protocol\Fetch\Helper\Helper::registerHelper('freeStream', $freeStream); + + // register partition commit offset + $commitOffset = new \Kafka\Protocol\Fetch\Helper\CommitOffset($this->client); + $commitOffset->setGroup($this->group); + \Kafka\Protocol\Fetch\Helper\Helper::registerHelper('commitOffset', $commitOffset); + + $updateConsumer = new \Kafka\Protocol\Fetch\Helper\Consumer($this); + \Kafka\Protocol\Fetch\Helper\Helper::registerHelper('updateConsumer', $updateConsumer); + + return $fetch; + } + + // }}} + // {{{ public function getClient() + + /** + * get client object + * + * @access public + * @return void + */ + public function getClient() + { + return $this->client; + } + + /** + * passthru method to client for setting stream options + * + * @param array $options + */ + public function setStreamOptions($options = array()) + { + $this->client->setStreamOptions($options); + } + + // }}} + // {{{ private function _formatPayload() + + /** + * format payload array + * + * @access private + * @return array + */ + private function _formatPayload() + { + if (empty($this->payload)) { + return array(); + } + + $data = array(); + foreach ($this->payload as $topicName => $partitions) { + foreach ($partitions as $partitionId => $offset) { + $host = $this->client->getHostByPartition($topicName, $partitionId); + $data[$host][$topicName][$partitionId] = $offset; + } + } + + $requestData = array(); + foreach ($data as $host => $info) { + $topicData = array(); + foreach ($info as $topicName => $partitions) { + $partitionData = array(); + foreach ($partitions as $partitionId => $offset) { + $partitionData[] = array( + 'partition_id' => $partitionId, + 'offset' => $offset, + 'max_bytes' => $this->maxSize, + ); + } + $topicData[] = array( + 'topic_name' => $topicName, + 'partitions' => $partitionData, + ); + } + + $requestData[$host] = array( + 'data' => $topicData, + ); + } + + return $requestData; + } + + /** + * const LAST_OFFSET = -1; + * const EARLIEST_OFFSET = -2; + * const DEFAULT_LAST = -2; + * const DEFAULT_EARLY = -1; + * @param type $offsetStrategy + */ + public function setOffsetStrategy($offsetStrategy) + { + $this->offsetStrategy = $offsetStrategy; + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Exception.php b/vendor/nmred/kafka-php/src/Kafka/Exception.php new file mode 100644 index 00000000..f336f1c3 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Exception.php @@ -0,0 +1,31 @@ +log($message, $level); + } + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/MetaDataFromKafka.php b/vendor/nmred/kafka-php/src/Kafka/MetaDataFromKafka.php new file mode 100644 index 00000000..9d2c613e --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/MetaDataFromKafka.php @@ -0,0 +1,200 @@ +hostList = explode(',', $hostList); + } else { + $this->hostList = (array)$hostList; + } + // randomize the order of servers we collect metadata from + shuffle($this->hostList); + } + + // }}} + // {{{ public function setClient() + + /** + * @var \Kafka\Client $client + * @access public + * @return void + */ + public function setClient(\Kafka\Client $client) + { + $this->client = $client; + } + + // }}} + // {{{ public function listBrokers() + + /** + * get broker list from kafka metadata + * + * @access public + * @return array + */ + public function listBrokers() + { + if ($this->brokers === null) { + $this->loadBrokers(); + } + return $this->brokers; + } + + // }}} + // {{{ public function getPartitionState() + + public function getPartitionState($topicName, $partitionId = 0) + { + if (!isset( $this->topics[$topicName] ) ) { + $this->loadTopicDetail(array($topicName)); + } + if ( isset( $this->topics[$topicName]['partitions'][$partitionId] ) ) { + return $this->topics[$topicName]['partitions'][$partitionId]; + } else { + return null; + } + } + + // }}} + // {{{ public function getTopicDetail() + + /** + * + * @param string $topicName + * @access public + * @return array + */ + public function getTopicDetail($topicName) + { + if (!isset( $this->topics[$topicName] ) ) { + $this->loadTopicDetail(array($topicName)); + } + if (isset( $this->topics[$topicName] ) ) { + return $this->topics[$topicName]; + } else { + return array(); + } + } + + // }}} + // {{{ private function loadBrokers() + + private function loadBrokers() + { + $this->brokers = array(); + // not sure how to ask for only the brokers without a topic... + // just ask for a topic we don't care about + $this->loadTopicDetail(array('test')); + } + + // }}} + // {{{ private function loadTopicDetail() + + private function loadTopicDetail(array $topics) + { + if ($this->client === null) { + throw new \Kafka\Exception('client was not provided'); + } + $response = null; + foreach ($this->hostList as $host) { + try { + $response = null; + $stream = $this->client->getStream($host); + $conn = $stream['stream']; + $encoder = new \Kafka\Protocol\Encoder($conn); + $encoder->metadataRequest($topics); + $decoder = new \Kafka\Protocol\Decoder($conn); + $response = $decoder->metadataResponse(); + $this->client->freeStream($stream['key']); + break; + } catch (\Kafka\Exception $e) { + // keep trying + } + } + if ($response) { + // Merge arrays using "+" operator to preserve key (which are broker IDs) + // instead of array_merge (which reindex numeric keys) + $this->brokers = $response['brokers'] + $this->brokers; + $this->topics = array_merge($response['topics'], $this->topics); + } else { + throw new \Kafka\Exception('Could not connect to any kafka brokers'); + } + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Offset.php b/vendor/nmred/kafka-php/src/Kafka/Offset.php new file mode 100644 index 00000000..7ad3f9d8 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Offset.php @@ -0,0 +1,305 @@ +client = $client; + $this->groupId = $groupId; + $this->topicName = $topicName; + $this->partitionId = $partitionId; + + $host = $this->client->getHostByPartition($topicName, $partitionId); + $stream = $this->client->getStream($host); + $conn = $stream['stream']; + $this->streamKey = $stream['key']; + $this->encoder = new \Kafka\Protocol\Encoder($conn); + $this->decoder = new \Kafka\Protocol\Decoder($conn); + } + + // }}} + // {{{ public function setOffset() + + /** + * set consumer offset + * + * @param integer $offset + * @access public + * @return void + */ + public function setOffset($offset) + { + $maxOffset = $this->getProduceOffset(); + if ($offset > $maxOffset) { + throw new \Kafka\Exception('this offset is invalid. must less than max offset:' . $maxOffset); + } + + $data = array( + 'group_id' => $this->groupId, + 'data' => array( + array( + 'topic_name' => $this->topicName, + 'partitions' => array( + array( + 'partition_id' => $this->partitionId, + 'offset' => $offset, + ), + ), + ), + ), + ); + + $topicName = $this->topicName; + $partitionId = $this->partitionId; + + $this->encoder->commitOffsetRequest($data); + $result = $this->decoder->commitOffsetResponse(); + $this->client->freeStream($this->streamKey); + if (!isset($result[$topicName][$partitionId]['errCode'])) { + throw new \Kafka\Exception('commit topic offset failed.'); + } + if ($result[$topicName][$partitionId]['errCode'] != 0) { + throw new \Kafka\Exception(\Kafka\Protocol\Decoder::getError($result[$topicName][$partitionId]['errCode'])); + } + } + + // }}} + // {{{ public function getOffset() + + /** + * get consumer offset + * + * @param integer $defaultOffset + * if defaultOffset -1 instead of early offset + * if defaultOffset -2 instead of last offset + * @access public + * @return void + */ + public function getOffset($defaultOffset = self::DEFAULT_LAST) + { + $maxOffset = $this->getProduceOffset(self::LAST_OFFSET); + $minOffset = $this->getProduceOffset(self::EARLIEST_OFFSET); + $data = array( + 'group_id' => $this->groupId, + 'data' => array( + array( + 'topic_name' => $this->topicName, + 'partitions' => array( + array( + 'partition_id' => $this->partitionId, + ), + ), + ), + ), + ); + + $this->encoder->fetchOffsetRequest($data); + $result = $this->decoder->fetchOffsetResponse(); + $this->client->freeStream($this->streamKey); + + $topicName = $this->topicName; + $partitionId = $this->partitionId; + if (!isset($result[$topicName][$partitionId]['errCode'])) { + throw new \Kafka\Exception('fetch topic offset failed.'); + } + if ($result[$topicName][$partitionId]['errCode'] == 3) { + switch ($defaultOffset) { + case self::DEFAULT_LAST: + return $maxOffset; + Log::log("topic name: $topicName, partitionId: $partitionId, get offset value is default last.", LOG_INFO); + case self::DEFAULT_EARLY: + Log::log("topic name: $topicName, partitionId: $partitionId, get offset value is default early.", LOG_INFO); + return $minOffset; + default: + $this->setOffset($defaultOffset); + Log::log("topic name: $topicName, partitionId: $partitionId, get offset value is default $defaultOffset.", LOG_INFO); + return $defaultOffset; + } + if ($defaultOffset) { + $this->setOffset($defaultOffset); + return $defaultOffset; + } + } elseif ($result[$topicName][$partitionId]['errCode'] == 0) { + $offset = $result[$topicName][$partitionId]['offset']; + if ($offset > $maxOffset || $offset < $minOffset) { + if ($defaultOffset == self::DEFAULT_EARLY) { + $offset = $minOffset; + } else { + $offset = $maxOffset; + } + } + Log::log("topic name: $topicName, partitionId: $partitionId, get offset value is $offset.", LOG_INFO); + + return $offset; + } else { + throw new \Kafka\Exception(\Kafka\Protocol\Decoder::getError($result[$topicName][$partitionId]['errCode'])); + } + } + + // }}} + // {{{ public function getProduceOffset() + + /** + * get produce server offset + * + * @param string $topicName + * @param integer $partitionId + * @access public + * @return int + */ + public function getProduceOffset($timeLine = self::LAST_OFFSET) + { + $topicName = $this->topicName; + $partitionId = $this->partitionId; + + $requestData = array( + 'data' => array( + array( + 'topic_name' => $this->topicName, + 'partitions' => array( + array( + 'partition_id' => $this->partitionId, + 'time' => $timeLine, + 'max_offset' => 1, + ), + ), + ), + ), + ); + $this->encoder->offsetRequest($requestData); + $result = $this->decoder->offsetResponse(); + $this->client->freeStream($this->streamKey); + + if (!isset($result[$topicName][$partitionId]['offset'])) { + if (isset($result[$topicName][$partitionId]['errCode'])) { + throw new \Kafka\Exception(\Kafka\Protocol\Decoder::getError($result[$topicName][$partitionId]['errCode'])); + } else { + throw new \Kafka\Exception('get offset failed. topic name:' . $this->topicName . ' partitionId: ' . $this->partitionId); + } + } + + return array_shift($result[$topicName][$partitionId]['offset']); + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Produce.php b/vendor/nmred/kafka-php/src/Kafka/Produce.php new file mode 100644 index 00000000..2b9e6cd3 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Produce.php @@ -0,0 +1,337 @@ +client = new \Kafka\Client($metadata); + } + + // }}} + // {{{ public function setMessages() + + /** + * set send messages + * + * @access public + * @return void + */ + public function setMessages($topicName, $partitionId = 0, $messages = array()) + { + if (isset($this->payload[$topicName][$partitionId])) { + $this->payload[$topicName][$partitionId] = + array_merge($this->payload[$topicName][$partitionId], $messages); + } else { + $this->payload[$topicName][$partitionId] = $messages; + } + + return $this; + } + + // }}} + // {{{ public function setRequireAck() + + /** + * set request mode + * This field indicates how many acknowledgements the servers should receive + * before responding to the request. If it is 0 the server will not send any + * response (this is the only case where the server will not reply to a + * request). If it is 1, the server will wait the data is written to the + * local log before sending a response. If it is -1 the server will block + * until the message is committed by all in sync replicas before sending a + * response. For any number > 1 the server will block waiting for this + * number of acknowledgements to occur (but the server will never wait for + * more acknowledgements than there are in-sync replicas). + * + * @param int $ack + * @access public + * @return void + */ + public function setRequireAck($ack = 0) + { + if ($ack >= -1) { + $this->requiredAck = (int) $ack; + } + + return $this; + } + + // }}} + // {{{ public function setTimeOut() + + /** + * set request timeout + * + * @param int $timeout + * @access public + * @return void + */ + public function setTimeOut($timeout = 100) + { + if ((int) $timeout) { + $this->timeout = (int) $timeout; + } + return $this; + } + + // }}} + // {{{ public function send() + + /** + * send message to broker + * + * @access public + * @return void + */ + public function send() + { + $data = $this->_formatPayload(); + if (empty($data)) { + return false; + } + + $responseData = array(); + foreach ($data as $host => $requestData) { + $stream = $this->client->getStream($host); + $conn = $stream['stream']; + $encoder = new \Kafka\Protocol\Encoder($conn); + $encoder->produceRequest($requestData); + if ((int) $this->requiredAck !== 0) { // get broker response + $decoder = new \Kafka\Protocol\Decoder($conn); + $response = $decoder->produceResponse(); + foreach ($response as $topicName => $info) { + if (!isset($responseData[$topicName])) { + $responseData[$topicName] = $info; + } else { + $responseData[$topicName] = array_merge($info, $responseData[$topicName]); + } + } + } + + $this->client->freeStream($stream['key']); + } + + $this->payload = array(); + return $responseData; + } + + // }}} + // {{{ public function getClient() + + /** + * get client object + * + * @access public + * @return void + */ + public function getClient() + { + return $this->client; + } + + /** + * passthru method to client for setting stream options + * + * @access public + * @param array $options + */ + public function setStreamOptions($options = array()) + { + $this->client->setStreamOptions($options); + } + + // }}} + // {{{ public function getAvailablePartitions() + + /** + * get available partition + * + * @access public + * @return array + */ + public function getAvailablePartitions($topicName) + { + $topicDetail = $this->client->getTopicDetail($topicName); + if (is_array($topicDetail) && isset($topicDetail['partitions'])) { + $topicPartitiions = array_keys($topicDetail['partitions']); + } else { + $topicPartitiions = array(); + } + + return $topicPartitiions; + } + + // }}} + // {{{ private function _formatPayload() + + /** + * format payload array + * + * @access private + * @return array + */ + private function _formatPayload() + { + if (empty($this->payload)) { + return array(); + } + + $data = array(); + foreach ($this->payload as $topicName => $partitions) { + foreach ($partitions as $partitionId => $messages) { + $host = $this->client->getHostByPartition($topicName, $partitionId); + $data[$host][$topicName][$partitionId] = $messages; + } + } + + $requestData = array(); + foreach ($data as $host => $info) { + $topicData = array(); + foreach ($info as $topicName => $partitions) { + $partitionData = array(); + foreach ($partitions as $partitionId => $messages) { + $partitionData[] = array( + 'partition_id' => $partitionId, + 'messages' => $messages, + ); + } + $topicData[] = array( + 'topic_name' => $topicName, + 'partitions' => $partitionData, + ); + } + + $requestData[$host] = array( + 'required_ack' => $this->requiredAck, + 'timeout' => $this->timeout, + 'data' => $topicData, + ); + } + + return $requestData; + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Decoder.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Decoder.php new file mode 100644 index 00000000..f1e4b496 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Decoder.php @@ -0,0 +1,430 @@ +stream->read(4, true)); + $dataLen = array_shift($dataLen); + if (!$dataLen) { + throw new \Kafka\Exception\Protocol('produce response invalid.'); + } + $data = $this->stream->read($dataLen, true); + + // parse data struct + $offset = 4; + $topicCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $topicCount = array_shift($topicCount); + $offset += 4; + for ($i = 0; $i < $topicCount; $i++) { + $topicLen = self::unpack(self::BIT_B16, substr($data, $offset, 2)); // int16 topic name length + $topicLen = isset($topicLen[1]) ? $topicLen[1] : 0; + $offset += 2; + $topicName = substr($data, $offset, $topicLen); + $offset += $topicLen; + $partitionCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $partitionCount = isset($partitionCount[1]) ? $partitionCount[1] : 0; + $offset += 4; + $result[$topicName] = array(); + for ($j = 0; $j < $partitionCount; $j++) { + $partitionId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $errCode = self::unpack(self::BIT_B16, substr($data, $offset, 2)); + $offset += 2; + $partitionOffset = self::unpack(self::BIT_B64, substr($data, $offset, 8)); + $offset += 8; + $result[$topicName][$partitionId[1]] = array( + 'errCode' => $errCode[1], + 'offset' => $partitionOffset + ); + } + } + + return $result; + } + + // }}} + // {{{ public function fetchResponse() + + /** + * decode fetch response + * + * @param string $data + * @access public + * @return Iterator + */ + public function fetchResponse() + { + return new \Kafka\Protocol\Fetch\Topic($this->stream); + } + + // }}} + // {{{ public function metadataResponse() + + /** + * decode metadata response + * + * @param string $data + * @access public + * @return array + */ + public function metadataResponse() + { + $result = array(); + $broker = array(); + $topic = array(); + $dataLen = self::unpack(self::BIT_B32, $this->stream->read(4, true)); + $dataLen = array_shift($dataLen); + if (!$dataLen) { + throw new \Kafka\Exception\Protocol('metaData response invalid.'); + } + $data = $this->stream->read($dataLen, true); + $offset = 4; + $brokerCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $brokerCount = isset($brokerCount[1]) ? $brokerCount[1] : 0; + for ($i = 0; $i < $brokerCount; $i++) { + $nodeId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $nodeId = $nodeId[1]; + $offset += 4; + $hostNameLen = self::unpack(self::BIT_B16, substr($data, $offset, 2)); // int16 host name length + $hostNameLen = isset($hostNameLen[1]) ? $hostNameLen[1] : 0; + $offset += 2; + $hostName = substr($data, $offset, $hostNameLen); + $offset += $hostNameLen; + $port = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $broker[$nodeId] = array( + 'host' => $hostName, + 'port' => $port[1], + ); + } + + $topicMetaCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $topicMetaCount = isset($topicMetaCount[1]) ? $topicMetaCount[1] : 0; + for ($i = 0; $i < $topicMetaCount; $i++) { + $topicErrCode = self::unpack(self::BIT_B16, substr($data, $offset, 2)); + $offset += 2; + $topicLen = self::unpack(self::BIT_B16, substr($data, $offset, 2)); + $offset += 2; + $topicName = substr($data, $offset, $topicLen[1]); + $offset += $topicLen[1]; + $partitionCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $partitionCount = isset($partitionCount[1]) ? $partitionCount[1] : 0; + $topic[$topicName]['errCode'] = $topicErrCode[1]; + $partitions = array(); + for ($j = 0; $j < $partitionCount; $j++) { + $partitionErrCode = self::unpack(self::BIT_B16, substr($data, $offset, 2)); + $offset += 2; + $partitionId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $partitionId = isset($partitionId[1]) ? $partitionId[1] : 0; + $offset += 4; + $leaderId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $repliasCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $repliasCount = isset($repliasCount[1]) ? $repliasCount[1] : 0; + $replias = array(); + for ($z = 0; $z < $repliasCount; $z++) { + $repliaId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $replias[] = $repliaId[1]; + } + $isrCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $isrCount = isset($isrCount[1]) ? $isrCount[1] : 0; + $isrs = array(); + for ($z = 0; $z < $isrCount; $z++) { + $isrId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $isrs[] = $isrId[1]; + } + + $partitions[$partitionId] = array( + 'errCode' => $partitionErrCode[1], + 'leader' => $leaderId[1], + 'replicas' => $replias, + 'isr' => $isrs, + ); + } + $topic[$topicName]['partitions'] = $partitions; + } + + $result = array( + 'brokers' => $broker, + 'topics' => $topic, + ); + return $result; + } + + // }}} + // {{{ public function offsetResponse() + + /** + * decode offset response + * + * @param string $data + * @access public + * @return array + */ + public function offsetResponse() + { + $result = array(); + $dataLen = self::unpack(self::BIT_B32, $this->stream->read(4, true)); + $dataLen = array_shift($dataLen); + if (!$dataLen) { + throw new \Kafka\Exception\Protocol('offset response invalid.'); + } + $data = $this->stream->read($dataLen, true); + $offset = 4; + $topicCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $topicCount = array_shift($topicCount); + for ($i = 0; $i < $topicCount; $i++) { + $topicLen = self::unpack(self::BIT_B16, substr($data, $offset, 2)); // int16 topic name length + $topicLen = isset($topicLen[1]) ? $topicLen[1] : 0; + $offset += 2; + $topicName = substr($data, $offset, $topicLen); + $offset += $topicLen; + $partitionCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $partitionCount = isset($partitionCount[1]) ? $partitionCount[1] : 0; + $offset += 4; + $result[$topicName] = array(); + for ($j = 0; $j < $partitionCount; $j++) { + $partitionId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $errCode = self::unpack(self::BIT_B16, substr($data, $offset, 2)); + $offset += 2; + $offsetCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $offsetCount = array_shift($offsetCount); + $offsetArr = array(); + for ($z = 0; $z < $offsetCount; $z++) { + $offsetArr[] = self::unpack(self::BIT_B64, substr($data, $offset, 8)); + $offset += 8; + } + $result[$topicName][$partitionId[1]] = array( + 'errCode' => $errCode[1], + 'offset' => $offsetArr + ); + } + } + return $result; + } + + // }}} + // {{{ public function commitOffsetResponse() + + /** + * decode commit offset response + * + * @param string $data + * @access public + * @return array + */ + public function commitOffsetResponse() + { + $result = array(); + $dataLen = self::unpack(self::BIT_B32, $this->stream->read(4, true)); + $dataLen = array_shift($dataLen); + if (!$dataLen) { + throw new \Kafka\Exception\Protocol('commit offset response invalid.'); + } + $data = $this->stream->read($dataLen, true); + $offset = 4; + $topicCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $topicCount = array_shift($topicCount); + for ($i = 0; $i < $topicCount; $i++) { + $topicLen = self::unpack(self::BIT_B16, substr($data, $offset, 2)); // int16 topic name length + $topicLen = isset($topicLen[1]) ? $topicLen[1] : 0; + $offset += 2; + $topicName = substr($data, $offset, $topicLen); + $offset += $topicLen; + $partitionCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $partitionCount = isset($partitionCount[1]) ? $partitionCount[1] : 0; + $offset += 4; + $result[$topicName] = array(); + for ($j = 0; $j < $partitionCount; $j++) { + $partitionId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $errCode = self::unpack(self::BIT_B16, substr($data, $offset, 2)); + $offset += 2; + $result[$topicName][$partitionId[1]] = array( + 'errCode' => $errCode[1], + ); + } + } + return $result; + } + + // }}} + // {{{ public function fetchOffsetResponse() + + /** + * decode fetch offset response + * + * @param string $data + * @access public + * @return array + */ + public function fetchOffsetResponse() + { + $result = array(); + $dataLen = self::unpack(self::BIT_B32, $this->stream->read(4, true)); + $dataLen = array_shift($dataLen); + if (!$dataLen) { + throw new \Kafka\Exception\Protocol('fetch offset response invalid.'); + } + $data = $this->stream->read($dataLen, true); + $offset = 4; + $topicCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $topicCount = array_shift($topicCount); + for ($i = 0; $i < $topicCount; $i++) { + $topicLen = self::unpack(self::BIT_B16, substr($data, $offset, 2)); // int16 topic name length + $topicLen = isset($topicLen[1]) ? $topicLen[1] : 0; + $offset += 2; + $topicName = substr($data, $offset, $topicLen); + $offset += $topicLen; + $partitionCount = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $partitionCount = isset($partitionCount[1]) ? $partitionCount[1] : 0; + $offset += 4; + $result[$topicName] = array(); + for ($j = 0; $j < $partitionCount; $j++) { + $partitionId = self::unpack(self::BIT_B32, substr($data, $offset, 4)); + $offset += 4; + $partitionOffset = self::unpack(self::BIT_B64, substr($data, $offset, 8)); + $offset += 8; + $metaLen = self::unpack(self::BIT_B16, substr($data, $offset, 2)); + $metaLen = array_shift($metaLen); + $offset += 2; + $metaData = ''; + if ($metaLen) { + $metaData = substr($data, $offset, $metaLen); + $offset += $metaLen; + } + $errCode = self::unpack(self::BIT_B16, substr($data, $offset, 2)); + $offset += 2; + $result[$topicName][$partitionId[1]] = array( + 'offset' => $partitionOffset, + 'metadata' => $metaData, + 'errCode' => $errCode[1], + ); + } + } + return $result; + } + + // }}} + // {{{ public static function getError() + + /** + * get error + * + * @param integer $errCode + * @static + * @access public + * @return string + */ + public static function getError($errCode) + { + $error = ''; + switch($errCode) { + case 0: + $error = 'No error--it worked!'; + break; + case -1: + $error = 'An unexpected server error'; + break; + case 1: + $error = 'The requested offset is outside the range of offsets maintained by the server for the given topic/partition.'; + break; + case 2: + $error = 'This indicates that a message contents does not match its CRC'; + break; + case 3: + $error = 'This request is for a topic or partition that does not exist on this broker.'; + break; + case 4: + $error = 'The message has a negative size'; + break; + case 5: + $error = 'This error is thrown if we are in the middle of a leadership election and there is currently no leader for this partition and hence it is unavailable for writes'; + break; + case 6: + $error = 'This error is thrown if the client attempts to send messages to a replica that is not the leader for some partition. It indicates that the clients metadata is out of date.'; + break; + case 7: + $error = 'This error is thrown if the request exceeds the user-specified time limit in the request.'; + break; + case 8: + $error = 'This is not a client facing error and is used only internally by intra-cluster broker communication.'; + break; + case 10: + $error = 'The server has a configurable maximum message size to avoid unbounded memory allocation. This error is thrown if the client attempt to produce a message larger than this maximum.'; + break; + case 11: + $error = 'Internal error code for broker-to-broker communication.'; + break; + case 12: + $error = 'If you specify a string larger than configured maximum for offset metadata'; + break; + case 14: + $error = 'The broker returns this error code for an offset fetch request if it is still loading offsets (after a leader change for that offsets topic partition).'; + break; + case 15: + $error = 'The broker returns this error code for consumer metadata requests or offset commit requests if the offsets topic has not yet been created.'; + break; + case 16: + $error = 'The broker returns this error code if it receives an offset fetch or commit request for a consumer group that it is not a coordinator for.'; + break; + default: + $error = 'Unknown error'; + } + + return $error; + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Encoder.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Encoder.php new file mode 100644 index 00000000..7d36e10f --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Encoder.php @@ -0,0 +1,652 @@ +stream->write($data); + } + + // }}} + // {{{ public function metadataRequest() + + /** + * build metadata request protocol + * + * @param array $topics + * @access public + * @return string + */ + public function metadataRequest($topics) + { + if (!is_array($topics)) { + $topics = array($topics); + } + + foreach ($topics as $topic) { + if (!is_string($topic)) { + throw new \Kafka\Exception\Protocol('request metadata topic array have invalid value. '); + } + } + + $header = self::requestHeader('kafka-php', 0, self::METADATA_REQUEST); + $data = self::encodeArray($topics, array(__CLASS__, 'encodeString'), self::PACK_INT16); + $data = self::encodeString($header . $data, self::PACK_INT32); + + return $this->stream->write($data); + } + + // }}} + // {{{ public function fetchRequest() + + /** + * build fetch request + * + * @param array $payloads + * @access public + * @return string + */ + public function fetchRequest($payloads) + { + if (!isset($payloads['data'])) { + throw new \Kafka\Exception\Protocol('given fetch kafka data invalid. `data` is undefined.'); + } + + if (!isset($payloads['replica_id'])) { + $payloads['replica_id'] = -1; + } + + if (!isset($payloads['max_wait_time'])) { + $payloads['max_wait_time'] = 100; // default timeout 100ms + } + + if (!isset($payloads['min_bytes'])) { + $payloads['min_bytes'] = 64 * 1024; // 64k + } + + $header = self::requestHeader('kafka-php', 0, self::FETCH_REQUEST); + $data = self::pack(self::BIT_B32, $payloads['replica_id']); + $data .= self::pack(self::BIT_B32, $payloads['max_wait_time']); + $data .= self::pack(self::BIT_B32, $payloads['min_bytes']); + $data .= self::encodeArray($payloads['data'], array(__CLASS__, '_encodeFetchTopic')); + $data = self::encodeString($header . $data, self::PACK_INT32); + + return $this->stream->write($data); + } + + // }}} + // {{{ public function offsetRequest() + + /** + * build offset request + * + * @param array $payloads + * @access public + * @return string + */ + public function offsetRequest($payloads) + { + if (!isset($payloads['data'])) { + throw new \Kafka\Exception\Protocol('given offset data invalid. `data` is undefined.'); + } + + if (!isset($payloads['replica_id'])) { + $payloads['replica_id'] = -1; + } + + $header = self::requestHeader('kafka-php', 0, self::OFFSET_REQUEST); + $data = self::pack(self::BIT_B32, $payloads['replica_id']); + $data .= self::encodeArray($payloads['data'], array(__CLASS__, '_encodeOffsetTopic')); + $data = self::encodeString($header . $data, self::PACK_INT32); + + return $this->stream->write($data); + } + + // }}} + // {{{ public function commitOffsetRequest() + + /** + * build consumer commit offset request + * + * @param array $payloads + * @access public + * @return string + */ + public function commitOffsetRequest($payloads) + { + if (!isset($payloads['data'])) { + throw new \Kafka\Exception\Protocol('given commit offset data invalid. `data` is undefined.'); + } + + if (!isset($payloads['group_id'])) { + throw new \Kafka\Exception\Protocol('given commit offset data invalid. `group_id` is undefined.'); + } + + $header = self::requestHeader('kafka-php', 0, self::OFFSET_COMMIT_REQUEST); + $data = self::encodeString($payloads['group_id'], self::PACK_INT16); + $data .= self::encodeArray($payloads['data'], array(__CLASS__, '_encodeCommitOffset')); + $data = self::encodeString($header . $data, self::PACK_INT32); + + return $this->stream->write($data); + } + + // }}} + // {{{ public function fetchOffsetRequest() + + /** + * build consumer fetch offset request + * + * @param array $payloads + * @access public + * @return string + */ + public function fetchOffsetRequest($payloads) + { + if (!isset($payloads['data'])) { + throw new \Kafka\Exception\Protocol('given fetch offset data invalid. `data` is undefined.'); + } + + if (!isset($payloads['group_id'])) { + throw new \Kafka\Exception\Protocol('given fetch offset data invalid. `group_id` is undefined.'); + } + + $header = self::requestHeader('kafka-php', 0, self::OFFSET_FETCH_REQUEST); + $data = self::encodeString($payloads['group_id'], self::PACK_INT16); + $data .= self::encodeArray($payloads['data'], array(__CLASS__, '_encodeFetchOffset')); + $data = self::encodeString($header . $data, self::PACK_INT32); + + return $this->stream->write($data); + } + + // }}} + // {{{ public static function encodeString() + + /** + * encode pack string type + * + * @param string $string + * @param int $bytes self::PACK_INT32: int32 big endian order. self::PACK_INT16: int16 big endian order. + * @static + * @access public + * @return string + */ + public static function encodeString($string, $bytes, $compression = self::COMPRESSION_NONE) + { + $packLen = ($bytes == self::PACK_INT32) ? self::BIT_B32 : self::BIT_B16; + switch ($compression) { + case self::COMPRESSION_NONE: + break; + case self::COMPRESSION_GZIP: + $string = gzencode($string); + break; + case self::COMPRESSION_SNAPPY: + throw new \Kafka\Exception\NotSupported('SNAPPY compression not yet implemented'); + default: + throw new \Kafka\Exception\NotSupported('Unknown compression flag: ' . $compression); + } + return self::pack($packLen, strlen($string)) . $string; + } + + // }}} + // {{{ public static function encodeArray() + + /** + * encode key array + * + * @param array $array + * @param Callable $func + * @static + * @access public + * @return string + */ + public static function encodeArray(array $array, $func, $options = null) + { + if (!is_callable($func, false)) { + throw new \Kafka\Exception\Protocol('Encode array failed, given function is not callable.'); + } + + $arrayCount = count($array); + + $body = ''; + foreach ($array as $value) { + if (!is_null($options)) { + $body .= call_user_func($func, $value, $options); + } else { + $body .= call_user_func($func, $value); + } + } + + return self::pack(self::BIT_B32, $arrayCount) . $body; + } + + // }}} + // {{{ public static function encodeMessageSet() + + /** + * encode message set + * N.B., MessageSets are not preceded by an int32 like other array elements + * in the protocol. + * + * @param array $messages + * @static + * @access public + * @return string + */ + public static function encodeMessageSet($messages, $compression = self::COMPRESSION_NONE) + { + if (!is_array($messages)) { + $messages = array($messages); + } + + $data = ''; + foreach ($messages as $message) { + $tmpMessage = self::_encodeMessage($message, $compression); + + // int64 -- message offset Message + $data .= self::pack(self::BIT_B64, 0) . self::encodeString($tmpMessage, self::PACK_INT32); + } + return $data; + } + + // }}} + // {{{ public static function requestHeader() + + /** + * get request header + * + * @param string $clientId + * @param integer $correlationId + * @param integer $apiKey + * @static + * @access public + * @return void + */ + public static function requestHeader($clientId, $correlationId, $apiKey) + { + // int16 -- apiKey int16 -- apiVersion int32 correlationId + $binData = self::pack(self::BIT_B16, $apiKey); + $binData .= self::pack(self::BIT_B16, self::API_VERSION); + $binData .= self::pack(self::BIT_B32, $correlationId); + + // concat client id + $binData .= self::encodeString($clientId, self::PACK_INT16); + + return $binData; + } + + // }}} + // {{{ protected static function _encodeMessage() + + /** + * encode signal message + * + * @param string $message + * @static + * @access protected + * @return string + */ + protected static function _encodeMessage($message, $compression = self::COMPRESSION_NONE) + { + // int8 -- magic int8 -- attribute + $data = self::pack(self::BIT_B8, self::MESSAGE_MAGIC); + $data .= self::pack(self::BIT_B8, $compression); + + // message key + $data .= self::encodeString('', self::PACK_INT32); + + // message value + $data .= self::encodeString($message, self::PACK_INT32, $compression); + + $crc = crc32($data); + + // int32 -- crc code string data + $message = self::pack(self::BIT_B32, $crc) . $data; + + return $message; + } + + // }}} + // {{{ protected static function _encodeProcudePartion() + + /** + * encode signal part + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeProcudePartion($values, $compression) + { + if (!isset($values['partition_id'])) { + throw new \Kafka\Exception\Protocol('given produce data invalid. `partition_id` is undefined.'); + } + + if (!isset($values['messages']) || empty($values['messages'])) { + throw new \Kafka\Exception\Protocol('given produce data invalid. `messages` is undefined.'); + } + + $data = self::pack(self::BIT_B32, $values['partition_id']); + $data .= self::encodeString(self::encodeMessageSet($values['messages'], $compression), self::PACK_INT32); + + return $data; + } + + // }}} + // {{{ protected static function _encodeProcudeTopic() + + /** + * encode signal topic + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeProcudeTopic($values, $compression) + { + if (!isset($values['topic_name'])) { + throw new \Kafka\Exception\Protocol('given produce data invalid. `topic_name` is undefined.'); + } + + if (!isset($values['partitions']) || empty($values['partitions'])) { + throw new \Kafka\Exception\Protocol('given produce data invalid. `partitions` is undefined.'); + } + + $topic = self::encodeString($values['topic_name'], self::PACK_INT16); + $partitions = self::encodeArray($values['partitions'], array(__CLASS__, '_encodeProcudePartion'), $compression); + + return $topic . $partitions; + } + + // }}} + // {{{ protected static function _encodeFetchPartion() + + /** + * encode signal part + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeFetchPartion($values) + { + if (!isset($values['partition_id'])) { + throw new \Kafka\Exception\Protocol('given fetch data invalid. `partition_id` is undefined.'); + } + + if (!isset($values['offset'])) { + $values['offset'] = 0; + } + + if (!isset($values['max_bytes'])) { + $values['max_bytes'] = 100 * 1024 * 1024; + } + + $data = self::pack(self::BIT_B32, $values['partition_id']); + $data .= self::pack(self::BIT_B64, $values['offset']); + $data .= self::pack(self::BIT_B32, $values['max_bytes']); + + return $data; + } + + // }}} + // {{{ protected static function _encodeFetchTopic() + + /** + * encode signal topic + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeFetchTopic($values) + { + if (!isset($values['topic_name'])) { + throw new \Kafka\Exception\Protocol('given fetch data invalid. `topic_name` is undefined.'); + } + + if (!isset($values['partitions']) || empty($values['partitions'])) { + throw new \Kafka\Exception\Protocol('given fetch data invalid. `partitions` is undefined.'); + } + + $topic = self::encodeString($values['topic_name'], self::PACK_INT16); + $partitions = self::encodeArray($values['partitions'], array(__CLASS__, '_encodeFetchPartion')); + + return $topic . $partitions; + } + + // }}} + // {{{ protected static function _encodeOffsetPartion() + + /** + * encode signal part + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeOffsetPartion($values) + { + if (!isset($values['partition_id'])) { + throw new \Kafka\Exception\Protocol('given offset data invalid. `partition_id` is undefined.'); + } + + if (!isset($values['time'])) { + $values['time'] = -1; // -1 + } + + if (!isset($values['max_offset'])) { + $values['max_offset'] = 100000; + } + + $data = self::pack(self::BIT_B32, $values['partition_id']); + $data .= self::pack(self::BIT_B64, $values['time']); + $data .= self::pack(self::BIT_B32, $values['max_offset']); + + return $data; + } + + // }}} + // {{{ protected static function _encodeOffsetTopic() + + /** + * encode signal topic + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeOffsetTopic($values) + { + if (!isset($values['topic_name'])) { + throw new \Kafka\Exception\Protocol('given offset data invalid. `topic_name` is undefined.'); + } + + if (!isset($values['partitions']) || empty($values['partitions'])) { + throw new \Kafka\Exception\Protocol('given offset data invalid. `partitions` is undefined.'); + } + + $topic = self::encodeString($values['topic_name'], self::PACK_INT16); + $partitions = self::encodeArray($values['partitions'], array(__CLASS__, '_encodeOffsetPartion')); + + return $topic . $partitions; + } + + // }}} + // {{{ protected static function _encodeCommitOffsetPartion() + + /** + * encode signal part + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeCommitOffsetPartion($values) + { + if (!isset($values['partition_id'])) { + throw new \Kafka\Exception\Protocol('given commit offset data invalid. `partition_id` is undefined.'); + } + + if (!isset($values['offset'])) { + throw new \Kafka\Exception\Protocol('given commit offset data invalid. `offset` is undefined.'); + } + + if (!isset($values['time'])) { + $values['time'] = -1; + } + + if (!isset($values['metadata'])) { + $values['metadata'] = 'm'; + } + + $data = self::pack(self::BIT_B32, $values['partition_id']); + $data .= self::pack(self::BIT_B64, $values['offset']); + $data .= self::pack(self::BIT_B64, $values['time']); + $data .= self::encodeString($values['metadata'], self::PACK_INT16); + + return $data; + } + + // }}} + // {{{ protected static function _encodeCommitOffset() + + /** + * encode signal topic + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeCommitOffset($values) + { + if (!isset($values['topic_name'])) { + throw new \Kafka\Exception\Protocol('given commit offset data invalid. `topic_name` is undefined.'); + } + + if (!isset($values['partitions']) || empty($values['partitions'])) { + throw new \Kafka\Exception\Protocol('given commit offset data invalid. `partitions` is undefined.'); + } + + $topic = self::encodeString($values['topic_name'], self::PACK_INT16); + $partitions = self::encodeArray($values['partitions'], array(__CLASS__, '_encodeCommitOffsetPartion')); + + return $topic . $partitions; + } + + // }}} + // {{{ protected static function _encodeFetchOffsetPartion() + + /** + * encode signal part + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeFetchOffsetPartion($values) + { + if (!isset($values['partition_id'])) { + throw new \Kafka\Exception\Protocol('given fetch offset data invalid. `partition_id` is undefined.'); + } + + $data = self::pack(self::BIT_B32, $values['partition_id']); + + return $data; + } + + // }}} + // {{{ protected static function _encodeFetchOffset() + + /** + * encode signal topic + * + * @param partions + * @static + * @access protected + * @return string + */ + protected static function _encodeFetchOffset($values) + { + if (!isset($values['topic_name'])) { + throw new \Kafka\Exception\Protocol('given fetch offset data invalid. `topic_name` is undefined.'); + } + + if (!isset($values['partitions']) || empty($values['partitions'])) { + throw new \Kafka\Exception\Protocol('given fetch offset data invalid. `partitions` is undefined.'); + } + + $topic = self::encodeString($values['topic_name'], self::PACK_INT16); + $partitions = self::encodeArray($values['partitions'], array(__CLASS__, '_encodeFetchOffsetPartion')); + + return $topic . $partitions; + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/CommitOffset.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/CommitOffset.php new file mode 100644 index 00000000..8424cf78 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/CommitOffset.php @@ -0,0 +1,119 @@ +client = $client; + } + + // }}} + // {{{ public function setGroup() + + /** + * set consumer group + * + * @access public + * @return void + */ + public function setGroup($group) + { + $this->group = $group; + } + + // }}} + // {{{ public function onStreamEof() + + /** + * on stream eof call + * + * @param string $streamKey + * @access public + * @return void + */ + public function onStreamEof($streamKey) + { + } + + // }}} + // {{{ public function onTopicEof() + + /** + * on topic eof call + * + * @param string $topicName + * @access public + * @return void + */ + public function onTopicEof($topicName) + { + } + + // }}} + // {{{ public function onPartitionEof() + + /** + * on partition eof call + * + * @param \Kafka\Protocol\Fetch\Partition $partition + * @access public + * @return void + */ + public function onPartitionEof($partition) + { + $partitionId = $partition->key(); + $topicName = $partition->getTopicName(); + $offset = $partition->getMessageOffset(); + $offsetObject = new \Kafka\Offset($this->client, $this->group, $topicName, $partitionId); + $offsetObject->setOffset($offset); + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Consumer.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Consumer.php new file mode 100644 index 00000000..acf0223e --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Consumer.php @@ -0,0 +1,39 @@ +consumer = $consumer; + } + + + public function onPartitionEof($partition) + { + $partitionId = $partition->key(); + $topicName = $partition->getTopicName(); + $offset = $partition->getMessageOffset(); + $this->consumer->setFromOffset(true); + $this->consumer->setPartition($topicName, $partitionId, ($offset +1)); + } + + public function onStreamEof($streamKey) + { + + } + + public function onTopicEof($topicName) + { + + } +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/FreeStream.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/FreeStream.php new file mode 100644 index 00000000..bba38dd6 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/FreeStream.php @@ -0,0 +1,117 @@ +client = $client; + } + + // }}} + // {{{ public function setStreams() + + /** + * set streams + * + * @access public + * @return void + */ + public function setStreams($streams) + { + $this->streams = $streams; + } + + // }}} + // {{{ public function onStreamEof() + + /** + * on stream eof call + * + * @param string $streamKey + * @access public + * @return void + */ + public function onStreamEof($streamKey) + { + if (isset($this->streams[$streamKey])) { + $this->client->freeStream($streamKey); + } + } + + // }}} + // {{{ public function onTopicEof() + + /** + * on topic eof call + * + * @param string $topicName + * @access public + * @return void + */ + public function onTopicEof($topicName) + { + } + + // }}} + // {{{ public function onPartitionEof() + + /** + * on partition eof call + * + * @param \Kafka\Protocol\Fetch\Partition $partition + * @access public + * @return void + */ + public function onPartitionEof($partition) + { + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Helper.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Helper.php new file mode 100644 index 00000000..4ec23926 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/Helper.php @@ -0,0 +1,160 @@ + $helper) { + if (method_exists($helper, 'onStreamEof')) { + $helper->onStreamEof($streamKey); + } + } + } + + // }}} + // {{{ public static function onTopicEof() + + /** + * on topic eof call + * + * @param string $topicName + * @static + * @access public + * @return void + */ + public static function onTopicEof($topicName) + { + if (empty(self::$helpers)) { + return false; + } + + foreach (self::$helpers as $key => $helper) { + if (method_exists($helper, 'onTopicEof')) { + $helper->onStreamEof($topicName); + } + } + } + + // }}} + // {{{ public static function onPartitionEof() + + /** + * on partition eof call + * + * @param \Kafka\Protocol\Fetch\Partition $partition + * @static + * @access public + * @return void + */ + public static function onPartitionEof($partition) + { + if (empty(self::$helpers)) { + return false; + } + + foreach (self::$helpers as $key => $helper) { + if (method_exists($helper, 'onPartitionEof')) { + $helper->onPartitionEof($partition); + } + } + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/HelperAbstract.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/HelperAbstract.php new file mode 100644 index 00000000..476f3da1 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Helper/HelperAbstract.php @@ -0,0 +1,71 @@ +crc = array_shift($crc); + $magic = Decoder::unpack(Decoder::BIT_B8, substr($msg, $offset, 1)); + $this->magic = array_shift($magic); + $offset += 1; + $attr = Decoder::unpack(Decoder::BIT_B8, substr($msg, $offset, 1)); + $this->attribute = array_shift($attr); + $offset += 1; + $keyLen = Decoder::unpack(Decoder::BIT_B32, substr($msg, $offset, 4)); + $keyLen = array_shift($keyLen); + $offset += 4; + if ($keyLen > 0 && $keyLen != 0xFFFFFFFF) { + $this->key = substr($msg, $offset, $keyLen); + $offset += $keyLen; + } + $messageSize = Decoder::unpack(Decoder::BIT_B32, substr($msg, $offset, 4)); + $messageSize = array_shift($messageSize); + $offset += 4; + if ($messageSize) { + $this->value = substr($msg, $offset, $messageSize); + } + } + + // }}} + // {{{ public function getMessage() + + /** + * get message data + * + * @access public + * @return string (raw) + */ + public function getMessage() + { + return $this->value; + } + + // }}} + // {{{ public function getMessageKey() + + /** + * get message key + * + * @access public + * @return string (raw) + */ + public function getMessageKey() + { + return $this->key; + } + + // }}} + // {{{ public function __toString() + + /** + * __toString + * + * @access public + * @return void + */ + public function __toString() + { + return $this->value; + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/MessageSet.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/MessageSet.php new file mode 100644 index 00000000..50413b67 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/MessageSet.php @@ -0,0 +1,269 @@ +stream = $partition->getStream(); + $this->partition = $partition; + $this->context = $context; + $this->messageSetSize = $this->getMessageSetSize(); + \Kafka\Log::log("messageSetSize: {$this->messageSetSize}", LOG_INFO); + } + + // }}} + // {{{ public function current() + + /** + * current + * + * @access public + * @return void + */ + public function current() + { + return $this->current; + } + + // }}} + // {{{ public function key() + + /** + * key + * + * @access public + * @return void + */ + public function key() + { + return $this->validByteCount; + } + + // }}} + // {{{ public function rewind() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function rewind() + { + $this->valid = $this->loadNextMessage(); + } + + // }}} + // {{{ public function valid() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function valid() + { + if (!$this->valid) { + $this->partition->setMessageOffset($this->offset); + + // one partition iterator end + \Kafka\Protocol\Fetch\Helper\Helper::onPartitionEof($this->partition); + } + + return $this->valid; + } + + // }}} + // {{{ public function next() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function next() + { + $this->valid = $this->loadNextMessage(); + } + + // }}} + // {{{ protected function getMessageSetSize() + + /** + * get message set size + * + * @access protected + * @return integer + */ + protected function getMessageSetSize() + { + // read message size + $data = $this->stream->read(4, true); + $data = Decoder::unpack(Decoder::BIT_B32, $data); + $size = array_shift($data); + if ($size <= 0) { + throw new \Kafka\Exception\OutOfRange($size . ' is not a valid message size'); + } + + return $size; + } + + // }}} + // {{{ public function loadNextMessage() + + /** + * load next message + * + * @access public + * @return void + */ + public function loadNextMessage() + { + if ($this->validByteCount >= $this->messageSetSize) { + return false; + } + + try { + if ($this->validByteCount + 12 > $this->messageSetSize) { + // read socket buffer dirty data + $this->stream->read($this->messageSetSize - $this->validByteCount); + return false; + } + $offset = $this->stream->read(8, true); + $this->offset = \Kafka\Protocol\Decoder::unpack(Decoder::BIT_B64, $offset); + $messageSize = $this->stream->read(4, true); + $messageSize = Decoder::unpack(Decoder::BIT_B32, $messageSize); + $messageSize = array_shift($messageSize); + $this->validByteCount += 12; + if (($this->validByteCount + $messageSize) > $this->messageSetSize) { + // read socket buffer dirty data + $this->stream->read($this->messageSetSize - $this->validByteCount); + return false; + } + $msg = $this->stream->read($messageSize, true); + $this->current = new Message($msg); + } catch (\Kafka\Exception $e) { + \Kafka\Log::log("already fetch: {$this->validByteCount}, {$e->getMessage()}", LOG_INFO); + return false; + } + + $this->validByteCount += $messageSize; + + return true; + } + + // }}} + // {{{ public function messageOffset() + + /** + * current message offset in producer + * + * @return void + */ + public function messageOffset() + { + return $this->offset; + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Partition.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Partition.php new file mode 100644 index 00000000..9f8578d5 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Partition.php @@ -0,0 +1,375 @@ +stream = $topic->getStream(); + $this->topicName = $topic->key(); + $this->context = $context; + $this->partitionCount = $this->getPartitionCount(); + } + + // }}} + // {{{ public function current() + + /** + * current + * + * @access public + * @return void + */ + public function current() + { + return $this->current; + } + + // }}} + // {{{ public function key() + + /** + * key + * + * @access public + * @return void + */ + public function key() + { + return $this->key; + } + + // }}} + // {{{ public function rewind() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function rewind() + { + $this->valid = $this->loadNextPartition(); + } + + // }}} + // {{{ public function valid() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function valid() + { + return $this->valid && $this->validCount <= $this->partitionCount; + } + + // }}} + // {{{ public function next() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function next() + { + $this->valid = $this->loadNextPartition(); + } + + // }}} + // {{{ public function count() + + /** + * implements Countable function + * + * @access public + * @return integer + */ + public function count() + { + return $this->partitionCount; + } + + // }}} + // {{{ public function getErrCode() + + /** + * get partition errcode + * + * @access public + * @return void + */ + public function getErrCode() + { + return $this->errCode; + } + + // }}} + // {{{ public function getHighOffset() + + /** + * get partition high offset + * + * @access public + * @return void + */ + public function getHighOffset() + { + return $this->offset; + } + + // }}} + // {{{ public function getTopicName() + + /** + * get partition topic name + * + * @access public + * @return void + */ + public function getTopicName() + { + return $this->topicName; + } + + // }}} + // {{{ public function getStream() + + /** + * get current stream + * + * @access public + * @return \Kafka\Socket + */ + public function getStream() + { + return $this->stream; + } + + // }}} + // {{{ protected function getPartitionCount() + + /** + * get message size + * only use to object init + * + * @access protected + * @return integer + */ + protected function getPartitionCount() + { + // read topic count + $data = $this->stream->read(4, true); + $data = Decoder::unpack(Decoder::BIT_B32, $data); + $count = array_shift($data); + if ($count <= 0) { + throw new \Kafka\Exception\OutOfRange($size . ' is not a valid partition count'); + } + + return $count; + } + + // }}} + // {{{ public function loadNextPartition() + + /** + * load next partition + * + * @access public + * @return void + */ + public function loadNextPartition() + { + if ($this->validCount >= $this->partitionCount) { + return false; + } + + try { + $partitionId = $this->stream->read(4, true); + $partitionId = Decoder::unpack(Decoder::BIT_B32, $partitionId); + $partitionId = array_shift($partitionId); + \Kafka\Log::log("kafka client:fetch partition:" . $partitionId, LOG_INFO); + + $errCode = $this->stream->read(2, true); + $errCode = Decoder::unpack(Decoder::BIT_B16, $errCode); + $this->errCode = array_shift($errCode); + if ($this->errCode != 0) { + throw new \Kafka\Exception(\Kafka\Protocol\Decoder::getError($this->errCode)); + } + $offset = $this->stream->read(8, true); + $this->offset = \Kafka\Protocol\Decoder::unpack(Decoder::BIT_B64, $offset); + + $this->key = $partitionId; + $this->current = new MessageSet($this, $this->context); + } catch (\Kafka\Exception $e) { + return false; + } + + $this->validCount++; + return true; + } + + // }}} + // {{{ public function setMessageOffset() + + /** + * set messageSet fetch offset current + * + * @param intger $offset + * @return void + */ + public function setMessageOffset($offset) + { + $this->currentOffset = $offset; + } + + // }}} + // {{{ public function getMessageOffset() + + /** + * get messageSet fetch offset current + * + * @return int + */ + public function getMessageOffset() + { + return $this->currentOffset; + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Topic.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Topic.php new file mode 100644 index 00000000..500e6b1f --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Fetch/Topic.php @@ -0,0 +1,345 @@ +streams = $streams; + $topicInfos = array(); + foreach ($context as $values) { + if (!isset($values['data'])) { + continue; + } + + foreach ($values['data'] as $value) { + if (!isset($value['topic_name']) || !isset($value['partitions'])) { + continue; + } + + $topicName = $value['topic_name']; + foreach ($value['partitions'] as $part) { + $topicInfos[$topicName][$part['partition_id']] = array( + 'offset' => $part['offset'], + ); + } + } + } + $this->context = $topicInfos; + $this->topicCount = $this->getTopicCount(); + } + + // }}} + // {{{ public function current() + + /** + * current + * + * @access public + * @return void + */ + public function current() + { + return $this->current; + } + + // }}} + // {{{ public function key() + + /** + * key + * + * @access public + * @return void + */ + public function key() + { + return $this->key; + } + + // }}} + // {{{ public function rewind() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function rewind() + { + $this->valid = $this->loadNextTopic(); + } + + // }}} + // {{{ public function valid() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function valid() + { + return $this->valid; + } + + // }}} + // {{{ public function next() + + /** + * implements Iterator function + * + * @access public + * @return integer + */ + public function next() + { + $this->valid = $this->loadNextTopic(); + } + + // }}} + // {{{ public function count() + + /** + * implements Countable function + * + * @access public + * @return integer + */ + public function count() + { + return $this->topicCount; + } + + // }}} + // {{{ protected function getTopicCount() + + /** + * get message size + * only use to object init + * + * @access protected + * @return integer + */ + protected function getTopicCount() + { + $count = 0; + foreach (array_values($this->streams) as $key => $stream) { + // read topic count + $stream->read(8, true); + $data = $stream->read(4, true); + $data = Decoder::unpack(Decoder::BIT_B32, $data); + $topicCount = array_shift($data); + $count += $topicCount; + $this->topicCounts[$key] = $topicCount; + if ($count <= 0) { + throw new \Kafka\Exception\OutOfRange($count . ' is not a valid topic count'); + } + } + + return $count; + } + + // }}} + // {{{ public function loadNextTopic() + + /** + * load next topic + * + * @access public + * @return void + */ + public function loadNextTopic() + { + if ($this->validCount >= $this->topicCount) { + \Kafka\Protocol\Fetch\Helper\Helper::onStreamEof($this->currentStreamLockKey); + return false; + } + + if ($this->currentStreamCount >= $this->topicCounts[$this->currentStreamKey]) { + \Kafka\Protocol\Fetch\Helper\Helper::onStreamEof($this->currentStreamLockKey); + $this->currentStreamKey++; + } + + $lockKeys = array_keys($this->streams); + $streams = array_values($this->streams); + if (!isset($streams[$this->currentStreamKey])) { + return false; + } + + $stream = $streams[$this->currentStreamKey]; + $this->currentStreamLockKey = $lockKeys[$this->currentStreamKey]; + + try { + $topicLen = $stream->read(2, true); + $topicLen = Decoder::unpack(Decoder::BIT_B16, $topicLen); + $topicLen = array_shift($topicLen); + if ($topicLen <= 0) { + return false; + } + + // topic name + $this->key = $stream->read($topicLen, true); + $this->current = new Partition($this, $this->context); + } catch (\Kafka\Exception $e) { + return false; + } + + $this->validCount++; + $this->currentStreamCount++; + + return true; + } + + // }}} + // {{{ public function getStream() + + /** + * get current stream + * + * @access public + * @return \Kafka\Socket + */ + public function getStream() + { + $streams = array_values($this->streams); + return $streams[$this->currentStreamKey]; + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Protocol/Protocol.php b/vendor/nmred/kafka-php/src/Kafka/Protocol/Protocol.php new file mode 100644 index 00000000..a31067b5 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Protocol/Protocol.php @@ -0,0 +1,230 @@ +stream = $stream; + } + + // }}} + // {{{ public static function Khex2bin() + + /** + * hex to bin + * + * @param string $string + * @static + * @access protected + * @return string (raw) + */ + public static function Khex2bin($string) + { + if (function_exists('\hex2bin')) { + return \hex2bin($string); + } else { + $bin = ''; + $len = strlen($string); + for ($i = 0; $i < $len; $i += 2) { + $bin .= pack('H*', substr($string, $i, 2)); + } + + return $bin; + } + } + + // }}} + // {{{ public static function unpack() + + /** + * Unpack a bit integer as big endian long + * + * @static + * @access public + * @return integer + */ + public static function unpack($type, $bytes) + { + self::checkLen($type, $bytes); + if ($type == self::BIT_B64) { + $set = unpack($type, $bytes); + $original = ($set[1] & 0xFFFFFFFF) << 32 | ($set[2] & 0xFFFFFFFF); + return $original; + } else { + return unpack($type, $bytes); + } + } + + // }}} + // {{{ public static function pack() + + /** + * pack a bit integer as big endian long + * + * @static + * @access public + * @return integer + */ + public static function pack($type, $data) + { + if ($type == self::BIT_B64) { + if ($data == -1) { // -1L + $data = self::Khex2bin('ffffffffffffffff'); + } elseif ($data == -2) { // -2L + $data = self::Khex2bin('fffffffffffffffe'); + } else { + $left = 0xffffffff00000000; + $right = 0x00000000ffffffff; + + $l = ($data & $left) >> 32; + $r = $data & $right; + $data = pack($type, $l, $r); + } + } else { + $data = pack($type, $data); + } + + return $data; + } + + // }}} + // {{{ protected static function checkLen() + + /** + * check unpack bit is valid + * + * @param string $type + * @param string(raw) $bytes + * @static + * @access protected + * @return void + */ + protected static function checkLen($type, $bytes) + { + $len = 0; + switch($type) { + case self::BIT_B64: + $len = 8; + break; + case self::BIT_B32: + $len = 4; + break; + case self::BIT_B16: + $len = 2; + break; + case self::BIT_B8: + $len = 1; + break; + } + + if (strlen($bytes) != $len) { + throw new \Kafka\Exception\Protocol('unpack failed. string(raw) length is ' . strlen($bytes) . ' , TO ' . $type); + } + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/Socket.php b/vendor/nmred/kafka-php/src/Kafka/Socket.php new file mode 100644 index 00000000..be7321f3 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/Socket.php @@ -0,0 +1,365 @@ +host = $host; + $this->port = $port; + $this->setRecvTimeoutSec($recvTimeoutSec); + $this->setRecvTimeoutUsec($recvTimeoutUsec); + $this->setSendTimeoutSec($sendTimeoutSec); + $this->setSendTimeoutUsec($sendTimeoutUsec); + } + + /** + * @param float $sendTimeoutSec + */ + public function setSendTimeoutSec($sendTimeoutSec) + { + $this->sendTimeoutSec = $sendTimeoutSec; + } + + /** + * @param float $sendTimeoutUsec + */ + public function setSendTimeoutUsec($sendTimeoutUsec) + { + $this->sendTimeoutUsec = $sendTimeoutUsec; + } + + /** + * @param float $recvTimeoutSec + */ + public function setRecvTimeoutSec($recvTimeoutSec) + { + $this->recvTimeoutSec = $recvTimeoutSec; + } + + /** + * @param float $recvTimeoutUsec + */ + public function setRecvTimeoutUsec($recvTimeoutUsec) + { + $this->recvTimeoutUsec = $recvTimeoutUsec; + } + + + + // }}} + // {{{ public static function createFromStream() + + /** + * Optional method to set the internal stream handle + * + * @static + * @access public + * @return void + */ + public static function createFromStream($stream) + { + $socket = new self('localhost', 0); + $socket->setStream($stream); + return $socket; + } + + // }}} + // {{{ public function setStream() + + /** + * Optional method to set the internal stream handle + * + * @param mixed $stream + * @access public + * @return void + */ + public function setStream($stream) + { + $this->stream = $stream; + } + + // }}} + // {{{ public function connect() + + /** + * Connects the socket + * + * @access public + * @return void + */ + public function connect() + { + if (is_resource($this->stream)) { + return false; + } + + if (empty($this->host)) { + throw new \Kafka\Exception('Cannot open null host.'); + } + if ($this->port <= 0) { + throw new \Kafka\Exception('Cannot open without port.'); + } + + $this->stream = @fsockopen( + $this->host, + $this->port, + $errno, + $errstr, + $this->sendTimeoutSec + ($this->sendTimeoutUsec / 1000000) + ); + + if ($this->stream == false) { + $error = 'Could not connect to ' + . $this->host . ':' . $this->port + . ' ('.$errstr.' ['.$errno.'])'; + throw new \Kafka\Exception\SocketConnect($error); + } + + stream_set_blocking($this->stream, 0); + } + + // }}} + // {{{ public function close() + + /** + * close the socket + * + * @access public + * @return void + */ + public function close() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } + } + + // }}} + // {{{ public function read() + + /** + * Read from the socket at most $len bytes. + * + * This method will not wait for all the requested data, it will return as + * soon as any data is received. + * + * @param integer $len Maximum number of bytes to read. + * @param boolean $verifyExactLength Throw an exception if the number of read bytes is less than $len + * + * @return string Binary data + * @throws Kafka_Exception_Socket + */ + public function read($len, $verifyExactLength = false) + { + if ($len > self::READ_MAX_LEN) { + throw new \Kafka\Exception\SocketEOF('Could not read '.$len.' bytes from stream, length too longer.'); + } + + $null = null; + $read = array($this->stream); + $readable = @stream_select($read, $null, $null, $this->recvTimeoutSec, $this->recvTimeoutUsec); + if ($readable > 0) { + $remainingBytes = $len; + $data = $chunk = ''; + while ($remainingBytes > 0) { + $chunk = fread($this->stream, $remainingBytes); + if ($chunk === false) { + $this->close(); + throw new \Kafka\Exception\SocketEOF('Could not read '.$len.' bytes from stream (no data)'); + } + if (strlen($chunk) === 0) { + // Zero bytes because of EOF? + if (feof($this->stream)) { + $this->close(); + throw new \Kafka\Exception\SocketEOF('Unexpected EOF while reading '.$len.' bytes from stream (no data)'); + } + // Otherwise wait for bytes + $readable = @stream_select($read, $null, $null, $this->recvTimeoutSec, $this->recvTimeoutUsec); + if ($readable !== 1) { + throw new \Kafka\Exception\SocketTimeout('Timed out reading socket while reading ' . $len . ' bytes with ' . $remainingBytes . ' bytes to go'); + } + continue; // attempt another read + } + $data .= $chunk; + $remainingBytes -= strlen($chunk); + } + if ($len === $remainingBytes || ($verifyExactLength && $len !== strlen($data))) { + // couldn't read anything at all OR reached EOF sooner than expected + $this->close(); + throw new \Kafka\Exception\SocketEOF('Read ' . strlen($data) . ' bytes instead of the requested ' . $len . ' bytes'); + } + + return $data; + } + if (false !== $readable) { + $res = stream_get_meta_data($this->stream); + if (!empty($res['timed_out'])) { + $this->close(); + throw new \Kafka\Exception\SocketTimeout('Timed out reading '.$len.' bytes from stream'); + } + } + $this->close(); + throw new \Kafka\Exception\SocketEOF('Could not read '.$len.' bytes from stream (not readable)'); + + } + + // }}} + // {{{ public function write() + + /** + * Write to the socket. + * + * @param string $buf The data to write + * + * @return integer + * @throws Kafka_Exception_Socket + */ + public function write($buf) + { + $null = null; + $write = array($this->stream); + + // fwrite to a socket may be partial, so loop until we + // are done with the entire buffer + $written = 0; + $buflen = strlen($buf); + while ( $written < $buflen ) { + // wait for stream to become available for writing + $writable = stream_select($null, $write, $null, $this->sendTimeoutSec, $this->sendTimeoutUsec); + if ($writable > 0) { + // write remaining buffer bytes to stream + $wrote = fwrite($this->stream, substr($buf, $written)); + if ($wrote === -1 || $wrote === false) { + throw new \Kafka\Exception\Socket('Could not write ' . strlen($buf) . ' bytes to stream, completed writing only ' . $written . ' bytes'); + } + $written += $wrote; + continue; + } + if (false !== $writable) { + $res = stream_get_meta_data($this->stream); + if (!empty($res['timed_out'])) { + throw new \Kafka\Exception\SocketTimeout('Timed out writing ' . strlen($buf) . ' bytes to stream after writing ' . $written . ' bytes'); + } + } + throw new \Kafka\Exception\Socket('Could not write ' . strlen($buf) . ' bytes to stream'); + } + return $written; + } + + // }}} + // {{{ public function rewind() + + /** + * Rewind the stream + * + * @return void + */ + public function rewind() + { + if (is_resource($this->stream)) { + rewind($this->stream); + } + } + + // }}} + // }}} +} diff --git a/vendor/nmred/kafka-php/src/Kafka/ZooKeeper.php b/vendor/nmred/kafka-php/src/Kafka/ZooKeeper.php new file mode 100644 index 00000000..f48b5cb9 --- /dev/null +++ b/vendor/nmred/kafka-php/src/Kafka/ZooKeeper.php @@ -0,0 +1,364 @@ +zookeeper = new \ZooKeeper($hostList, null, $timeout); + } else { + $this->zookeeper = new \ZooKeeper($hostList); + } + } + + // }}} + // {{{ public function listBrokers() + + /** + * get broker list using zookeeper + * + * @access public + * @return array + */ + public function listBrokers() + { + $result = array(); + $lists = $this->zookeeper->getChildren(self::BROKER_PATH); + if (!empty($lists)) { + foreach ($lists as $brokerId) { + $brokerDetail = $this->getBrokerDetail($brokerId); + if (!$brokerDetail) { + continue; + } + $result[$brokerId] = $brokerDetail; + } + } + + return $result; + } + + // }}} + // {{{ public function getBrokerDetail() + + /** + * get broker detail + * + * @param integer $brokerId + * @access public + * @return void + */ + public function getBrokerDetail($brokerId) + { + $result = array(); + $path = sprintf(self::BROKER_DETAIL_PATH, (int) $brokerId); + if ($this->zookeeper->exists($path)) { + $result = $this->zookeeper->get($path); + if (!$result) { + return false; + } + + $result = json_decode($result, true); + } + + return $result; + } + + // }}} + // {{{ public function getTopicDetail() + + /** + * get topic detail + * + * @param string $topicName + * @access public + * @return void + */ + public function getTopicDetail($topicName) + { + $result = array(); + $path = sprintf(self::TOPIC_PATCH, (string) $topicName); + if ($this->zookeeper->exists($path)) { + $result = $this->zookeeper->get($path); + if (!$result) { + return false; + } + $result = json_decode($result, true); + } + + return $result; + } + + // }}} + // {{{ public function getPartitionState() + + /** + * get partition state + * + * @param string $topicName + * @param integer $partitionId + * @access public + * @return void + */ + public function getPartitionState($topicName, $partitionId = 0) + { + $result = array(); + $path = sprintf(self::PARTITION_STATE, (string) $topicName, (int) $partitionId); + if ($this->zookeeper->exists($path)) { + $result = $this->zookeeper->get($path); + if (!$result) { + return false; + } + $result = json_decode($result, true); + } + + return $result; + } + + // }}} + // {{{ public function registerConsumer() + + /** + * register consumer + * + * @param string $topicName + * @param integer $partitionId + * @access public + * @return void + */ + public function registerConsumer($groupId, $consumerId, $topics = array()) + { + if (empty($topics)) { + return true; + } + + $path = sprintf(self::REG_CONSUMER, (string) $groupId, (string) $consumerId); + $subData = array(); + foreach ($topics as $topic) { + $subData[$topic] = 1; + } + $data = array( + 'version' => '1', + 'pattern' => 'white_list', + 'subscription' => $subData, + ); + if (!$this->zookeeper->exists($path)) { + $this->makeZkPath($path); + $this->makeZkNode($path, json_encode($data)); + } else { + $this->zookeeper->set($path, json_encode($data)); + } + } + + // }}} + // {{{ public function listConsumer() + + /** + * list consumer + * + * @param string $groupId + * @access public + * @return void + */ + public function listConsumer($groupId) + { + $path = sprintf(self::LIST_CONSUMER, (string) $groupId); + if (!$this->zookeeper->exists($path)) { + return array(); + } else { + return $this->zookeeper->getChildren($path); + } + } + + // }}} + // {{{ public function getConsumersPerTopic() + + /** + * get consumer per topic + * + * @param string $groupId + * @access public + * @return array + */ + public function getConsumersPerTopic($groupId) + { + $consumers = $this->listConsumer($groupId); + if (empty($consumers)) { + return array(); + } + + $topics = array(); + foreach ($consumers as $consumerId) { + $path = sprintf(self::REG_CONSUMER, (string) $groupId, (string) $consumerId); + if (!$this->zookeeper->exists($path)) { + continue; + } + + $info = $this->zookeeper->get($path); + $info = json_decode($info, true); + $subTopic = isset($info['subscription']) ? $info['subscription'] : array(); + foreach ($subTopic as $topic => $num) { + $topics[$topic] = $consumerId; + } + } + + return $topics; + } + + // }}} + // {{{ public function addPartitionOwner() + + /** + * add partition owner + * + * @param string $groupId + * @param string $topicName + * @param integer $partitionId + * @param string $consumerId + * @access public + * @return void + */ + public function addPartitionOwner($groupId, $topicName, $partitionId, $consumerId) + { + $path = sprintf(self::PARTITION_OWNER, (string) $groupId, $topicName, (string) $partitionId); + if (!$this->zookeeper->exists($path)) { + $this->makeZkPath($path); + $this->makeZkNode($path, $consumerId); + } else { + $this->zookeeper->set($path, $consumerId); + } + } + + // }}} + // {{{ protected function makeZkPath() + + /** + * Equivalent of "mkdir -p" on ZooKeeper + * + * @param string $path The path to the node + * @param mixed $value The value to assign to each new node along the path + * + * @return bool + */ + protected function makeZkPath($path, $value = 0) + { + $parts = explode('/', $path); + $parts = array_filter($parts); + $subpath = ''; + while (count($parts) > 1) { + $subpath .= '/' . array_shift($parts); + if (!$this->zookeeper->exists($subpath)) { + $this->makeZkNode($subpath, $value); + } + } + } + + // }}} + // {{{ protected function makeZkNode() + + /** + * Create a node on ZooKeeper at the given path + * + * @param string $path The path to the node + * @param mixed $value The value to assign to the new node + * + * @return bool + */ + protected function makeZkNode($path, $value) + { + $params = array( + array( + 'perms' => \Zookeeper::PERM_ALL, + 'scheme' => 'world', + 'id' => 'anyone', + ) + ); + return $this->zookeeper->create($path, $value, $params); + } + + // }}} + // }}} +} diff --git a/vendor/oojs/oojs-ui/.csscomb.json b/vendor/oojs/oojs-ui/.csscomb.json deleted file mode 100644 index c4e215ec..00000000 --- a/vendor/oojs/oojs-ui/.csscomb.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "remove-empty-rulesets": true, - "always-semicolon": true, - "color-case": "lower", - "block-indent": "\t", - "color-shorthand": false, - "element-case": "lower", - "eof-newline": true, - "leading-zero": true, - "quotes": "double", - "space-before-colon": "", - "space-after-colon": " ", - "space-before-combinator": " ", - "space-after-combinator": " ", - "space-between-declarations": "\n", - "space-before-opening-brace": " ", - "space-after-opening-brace": "\n", - "space-after-selector-delimiter": "\n", - "space-before-selector-delimiter": "", - "space-before-closing-brace": "\n", - "strip-spaces": true, - "unitless-zero": true, - "vendor-prefix-align": true -} diff --git a/vendor/oojs/oojs-ui/.csslintrc b/vendor/oojs/oojs-ui/.csslintrc deleted file mode 100644 index e777c7f3..00000000 --- a/vendor/oojs/oojs-ui/.csslintrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "adjoining-classes": false, - "box-model": false, - "box-sizing": false, - "fallback-colors": false, - "important": false, - "outline-none": false, - "qualified-headings": false, - "universal-selector": false, - "unqualified-attributes": false -} diff --git a/vendor/oojs/oojs-ui/.npmignore b/vendor/oojs/oojs-ui/.npmignore deleted file mode 100644 index 67aebbfc..00000000 --- a/vendor/oojs/oojs-ui/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -/docs -vendor diff --git a/vendor/oojs/oojs-ui/AUTHORS.txt b/vendor/oojs/oojs-ui/AUTHORS.txt index 6813d169..cc0970df 100644 --- a/vendor/oojs/oojs-ui/AUTHORS.txt +++ b/vendor/oojs/oojs-ui/AUTHORS.txt @@ -2,7 +2,7 @@ Principal Authors (major contributors, alphabetically) Bartosz Dziewoński Ed Sanders -James D. Forrester +James D. Forrester Kirsten Menger-Anderson Roan Kattouw Rob Moen @@ -24,6 +24,7 @@ Juliusz Gonera Kunal Mehta Kyle Florence May Tee-Galloway +Mr. Stradivarius Moriel Schottlender Niklas Laxström Ricordisamoa diff --git a/vendor/oojs/oojs-ui/Doxyfile b/vendor/oojs/oojs-ui/Doxyfile deleted file mode 100644 index cf831926..00000000 --- a/vendor/oojs/oojs-ui/Doxyfile +++ /dev/null @@ -1,33 +0,0 @@ -# Configuration file for Doxygen - -PROJECT_NAME = OOjs UI -PROJECT_BRIEF = Object-Oriented JavaScript – User Interface - -OUTPUT_DIRECTORY = docs -HTML_OUTPUT = php - -JAVADOC_AUTOBRIEF = YES -QT_AUTOBRIEF = YES - -WARN_NO_PARAMDOC = YES - -INPUT = README.md php/ -FILE_PATTERNS = *.php -RECURSIVE = YES -# Requires doxygen 1.8.3+ -USE_MDFILE_AS_MAINPAGE = README.md - -HTML_DYNAMIC_SECTIONS = YES -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 250 - -GENERATE_LATEX = NO - -HAVE_DOT = YES -DOT_FONTNAME = Helvetica -DOT_FONTSIZE = 10 -TEMPLATE_RELATIONS = YES -CALL_GRAPH = NO -CALLER_GRAPH = NO -# Makes dot run faster. Requires graphviz >1.8.10 -DOT_MULTI_TARGETS = YES diff --git a/vendor/oojs/oojs-ui/Gruntfile.js b/vendor/oojs/oojs-ui/Gruntfile.js deleted file mode 100644 index 0aa41e42..00000000 --- a/vendor/oojs/oojs-ui/Gruntfile.js +++ /dev/null @@ -1,401 +0,0 @@ -/*! - * Grunt file - */ - -/*jshint node:true */ -module.exports = function ( grunt ) { - grunt.loadNpmTasks( 'grunt-banana-checker' ); - grunt.loadNpmTasks( 'grunt-contrib-clean' ); - grunt.loadNpmTasks( 'grunt-contrib-concat-sourcemaps' ); - grunt.loadNpmTasks( 'grunt-contrib-copy' ); - grunt.loadNpmTasks( 'grunt-contrib-csslint' ); - grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); - grunt.loadNpmTasks( 'grunt-contrib-jshint' ); - grunt.loadNpmTasks( 'grunt-contrib-less' ); - grunt.loadNpmTasks( 'grunt-contrib-uglify' ); - grunt.loadNpmTasks( 'grunt-contrib-watch' ); - grunt.loadNpmTasks( 'grunt-csscomb' ); - grunt.loadNpmTasks( 'grunt-exec' ); - grunt.loadNpmTasks( 'grunt-file-exists' ); - grunt.loadNpmTasks( 'grunt-cssjanus' ); - grunt.loadNpmTasks( 'grunt-jscs' ); - grunt.loadNpmTasks( 'grunt-karma' ); - grunt.loadNpmTasks( 'grunt-svg2png' ); - grunt.loadTasks( 'build/tasks' ); - - var modules = grunt.file.readJSON( 'build/modules.json' ), - pgk = grunt.file.readJSON( 'package.json' ), - lessFiles = { - raster: {}, - vector: {}, - mixed: {} - }, - colorizeSvgFiles = {}, - requiredFiles = modules[ 'oojs-ui' ].scripts.slice(), - concatCssFiles = {}, - rtlFiles = {}, - minBanner = '/*! OOjs UI v<%= pkg.version %> | http://oojs.mit-license.org */'; - - ( function () { - var distFile, target, module, moduleStyleFiles; - function rtlPath( fileName ) { - return fileName.replace( /\.(\w+)$/, '.rtl.$1' ); - } - // Generate all task targets required to process given file into a pair of CSS files (for LTR - // and RTL), and return file name of LTR file. - function processFile( fileName ) { - var lessFileName, cssFileName, theme, path; - path = require( 'path' ); - if ( path.extname( fileName ) === '.json' ) { - lessFileName = fileName.replace( /\.json$/, '.less' ).replace( /^src/, 'dist/tmp' ); - theme = path.basename( path.dirname( fileName ) ); - - colorizeSvgFiles[ fileName.replace( /.+\/(\w+)\/([\w-]+)\.(?:json|less)$/, '$1-$2' ) ] = { - options: grunt.file.readJSON( fileName ), - srcDir: 'src/themes/' + theme, - destDir: 'dist/themes/' + theme, - // This should not be needed, but our dist directory structure is weird - cssPrependPath: 'themes/' + theme + '/', - destLessFile: { - ltr: lessFileName, - rtl: rtlPath( lessFileName ) - } - }; - - cssFileName = fileName.replace( /\.json$/, '.css' ).replace( /^src/, 'dist/tmp/' + target ); - lessFiles[ target ][ cssFileName ] = [ lessFileName ]; - lessFiles[ target ][ rtlPath( cssFileName ) ] = [ rtlPath( lessFileName ) ]; - } else { - cssFileName = fileName.replace( /\.less$/, '.css' ).replace( /^src/, 'dist/tmp/' + target ); - lessFiles[ target ][ cssFileName ] = [ fileName ]; - rtlFiles[ rtlPath( cssFileName ) ] = cssFileName; - } - return cssFileName; - } - for ( module in modules ) { - if ( modules[ module ].styles ) { - moduleStyleFiles = modules[ module ].styles; - for ( target in lessFiles ) { - requiredFiles.push.apply( requiredFiles, moduleStyleFiles ); - - distFile = 'dist/' + module + ( target !== 'mixed' ? '.' + target : '' ) + '.css'; - - concatCssFiles[ distFile ] = moduleStyleFiles.map( processFile ); - concatCssFiles[ rtlPath( distFile ) ] = concatCssFiles[ distFile ].map( rtlPath ); - } - } - } - }() ); - - function strip( str ) { - var path = require( 'path' ); - // http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically - // http://gruntjs.com/api/grunt.file#grunt.file.expandmapping - return function ( dest, src ) { - return path.join( dest, src.replace( str, '' ) ); - }; - } - - grunt.initConfig( { - pkg: pgk, - - // Build - clean: { - build: 'dist/*', - doc: 'docs/*', - tmp: 'dist/tmp' - }, - fileExists: { - src: requiredFiles - }, - typos: { - options: { - typos: 'build/typos.json' - }, - src: '{src,php}/**/*.{js,json,less,css}' - }, - concat: { - options: { - banner: grunt.file.read( 'build/banner.txt' ) - }, - js: { - files: { - 'dist/oojs-ui.js': modules[ 'oojs-ui' ].scripts, - 'dist/oojs-ui-apex.js': modules[ 'oojs-ui-apex' ].scripts, - 'dist/oojs-ui-mediawiki.js': modules[ 'oojs-ui-mediawiki' ].scripts - } - }, - css: { - files: concatCssFiles - }, - demoCss: { - options: { - banner: '/** This file is generated automatically. Do not modify it. */\n\n' - }, - files: { - 'demos/styles/demo.rtl.css': 'demos/styles/demo.rtl.css' - } - } - }, - - // Build – Code - uglify: { - options: { - banner: minBanner, - sourceMap: true, - sourceMapIncludeSources: true, - report: 'gzip' - }, - js: { - expand: true, - src: 'dist/*.js', - ext: '.min.js', - extDot: 'last' - } - }, - - // Build – Styling - less: { - distRaster: { - options: { - ieCompat: true, - report: 'gzip', - modifyVars: { - 'oo-ui-distribution': 'raster', - 'oo-ui-default-image-ext': 'png' - } - }, - files: lessFiles.raster - }, - distVector: { - options: { - ieCompat: false, - report: 'gzip', - modifyVars: { - 'oo-ui-distribution': 'vector', - 'oo-ui-default-image-ext': 'svg' - } - }, - files: lessFiles.vector - }, - distMixed: { - options: { - ieCompat: false, - report: 'gzip', - modifyVars: { - 'oo-ui-distribution': 'mixed', - 'oo-ui-default-image-ext': 'png' - } - }, - files: lessFiles.mixed - } - }, - cssjanus: { - options: { - generateExactDuplicates: true - }, - dist: { - files: rtlFiles - }, - demoCss: { - files: { - 'demos/styles/demo.rtl.css': 'demos/styles/demo.css' - } - } - }, - csscomb: { - dist: { - expand: true, - src: 'dist/*.css' - } - }, - copy: { - imagesCommon: { - src: 'src/styles/images/*.cur', - dest: 'dist/images/', - expand: true, - flatten: true - }, - imagesApex: { - src: 'src/themes/apex/images/**/*.{png,gif}', - dest: 'dist/themes/apex/images/', - expand: true, - rename: strip( 'src/themes/apex/images/' ) - }, - imagesMediaWiki: { - src: 'src/themes/mediawiki/images/**/*.{png,gif}', - dest: 'dist/themes/mediawiki/images/', - expand: true, - rename: strip( 'src/themes/mediawiki/images/' ) - }, - i18n: { - src: 'i18n/*.json', - expand: true, - dest: 'dist/' - }, - jsduck: { - // Don't publish devDependencies - src: '{dist,node_modules/{' + Object.keys( pgk.dependencies ).join( ',' ) + '}}/**/*', - dest: 'docs/', - expand: true - } - }, - colorizeSvg: colorizeSvgFiles, - svg2png: { - dist: { - src: 'dist/{images,themes}/**/*.svg' - } - }, - cssmin: { - options: { - keepSpecialComments: 0, - banner: minBanner, - compatibility: 'ie8', - report: 'gzip' - }, - dist: { - expand: true, - src: 'dist/*.css', - ext: '.min.css', - extDot: 'last' - } - }, - - // Lint – Code - jshint: { - options: { - jshintrc: true - }, - dev: [ - '*.js', - '{build,demos,src,tests}/**/*.js', - '!tests/JSPHP.test.js' - ] - }, - jscs: { - dev: [ - '<%= jshint.dev %>', - '!demos/dist/**' - ] - }, - - // Lint – Styling - csslint: { - options: { - csslintrc: '.csslintrc' - }, - all: [ - '{demos,src}/**/*.css', - '!demos/dist/**' - ] - }, - - // Lint – i18n - banana: { - all: 'i18n/' - }, - - // Test - exec: { - rubyTestSuiteGenerator: { - command: 'ruby bin/testsuitegenerator.rb src php > tests/JSPHP-suite.json' - }, - phpGenerateJSPHPForKarma: { - command: 'php ../bin/generate-JSPHP-for-karma.php > JSPHP.test.js', - cwd: './tests' - } - }, - karma: { - options: { - frameworks: [ 'qunit' ], - files: [ - 'node_modules/jquery/dist/jquery.js', - 'node_modules/oojs/dist/oojs.jquery.js', - 'dist/oojs-ui.js', - 'dist/oojs-ui-apex.js', - 'dist/oojs-ui-mediawiki.js', - 'tests/QUnit.assert.equalDomElement.js', - 'tests/**/*.test.js' - ], - reporters: [ 'dots' ], - singleRun: true, - browserDisconnectTimeout: 5000, - browserDisconnectTolerance: 2, - autoWatch: false - }, - main: { - browsers: [ 'Chrome' ], - preprocessors: { - 'dist/*.js': [ 'coverage' ] - }, - reporters: [ 'dots', 'coverage' ], - coverageReporter: { reporters: [ - { type: 'html', dir: 'coverage/' }, - { type: 'text-summary', dir: 'coverage/' } - ] } - }, - other: { - browsers: [ 'Firefox' ] - } - }, - - // Development - watch: { - files: [ - '<%= jshint.dev %>', - '<%= csslint.all %>', - '{demos,src}/**/*.less', - '.{csslintrc,jscsrc,jshintignore,jshintrc}' - ], - tasks: 'quick-build' - } - } ); - - grunt.registerTask( 'pre-test', function () { - // Only create Source maps when doing a git-build for testing and local - // development. Distributions for export should not, as the map would - // be pointing at "../src". - grunt.config.set( 'concat.js.options.sourceMap', true ); - grunt.config.set( 'concat.js.options.sourceMapStyle', 'link' ); - } ); - - grunt.registerTask( 'pre-git-build', function () { - var done = this.async(); - require( 'child_process' ).exec( 'git rev-parse HEAD', function ( err, stout, stderr ) { - if ( !stout || err || stderr ) { - grunt.log.err( err || stderr ); - done( false ); - return; - } - grunt.config.set( 'pkg.version', grunt.config( 'pkg.version' ) + '-pre (' + stout.slice( 0, 10 ) + ')' ); - grunt.verbose.writeln( 'Added git HEAD to pgk.version' ); - done(); - } ); - } ); - - grunt.registerTask( 'build-code', [ 'concat:js', 'uglify' ] ); - grunt.registerTask( 'build-styling', [ - 'colorizeSvg', 'less', 'cssjanus', - 'concat:css', 'concat:demoCss', 'csscomb', 'cssmin', - 'copy:imagesCommon', 'copy:imagesApex', 'copy:imagesMediaWiki', 'svg2png' - ] ); - grunt.registerTask( 'build-i18n', [ 'copy:i18n' ] ); - grunt.registerTask( 'build-tests', [ 'exec:rubyTestSuiteGenerator', 'exec:phpGenerateJSPHPForKarma' ] ); - grunt.registerTask( 'build', [ 'clean:build', 'fileExists', 'typos', 'build-code', 'build-styling', 'build-i18n', 'build-tests', 'clean:tmp' ] ); - - grunt.registerTask( 'git-build', [ 'pre-git-build', 'build' ] ); - - // Quickly build a no-frills vector-only ltr-only version for development - grunt.registerTask( 'quick-build', [ - 'pre-git-build', 'clean:build', 'fileExists', 'typos', - 'concat:js', - 'colorizeSvg', 'less:distVector', 'concat:css', - 'copy:imagesCommon', 'copy:imagesApex', 'copy:imagesMediaWiki', - 'build-i18n' - ] ); - - grunt.registerTask( 'lint', [ 'jshint', 'jscs', 'csslint', 'banana' ] ); - grunt.registerTask( 'test', [ 'lint', 'pre-test', 'git-build', 'karma:main', 'karma:other' ] ); - - grunt.registerTask( 'default', 'test' ); -}; diff --git a/vendor/oojs/oojs-ui/History.md b/vendor/oojs/oojs-ui/History.md index 905b6b11..d7d5fbc6 100644 --- a/vendor/oojs/oojs-ui/History.md +++ b/vendor/oojs/oojs-ui/History.md @@ -1,10 +1,420 @@ # OOjs UI Release History +## v0.12.12 / 2015-10-13 +### Features +* CapsuleMultiSelectWidget: When 'allowArbitrary' is true, don't require 'Enter' to confirm (Bartosz Dziewoński) +* SelectFileWidget: Add a focus method (Ed Sanders) + +### Styles +* CapsuleMultiSelectWidget: Set 'background-color' rather than 'background' (Bartosz Dziewoński) +* DropdownWidget: Fix vertical alignment of handle's text (Volker E) +* MediaWiki theme: Get transitions on ButtonWidget's `:hover` states in sync (Volker E) +* MediaWiki theme: Unbreak checkbox/radio 'cursor: pointer' (Bartosz Dziewoński) +* MediaWiki theme: Use inverted icon for 'active' buttons (Ed Sanders) + +### Code +* ButtonElement: Actually use 'active' property and add getter (Ed Sanders) +* Element: Document $element config option (Thalia) +* composer.json: Add author names & e-mails (Alangi Derick) +* demo: Correct some typos (Bartosz Dziewoński) + +## v0.12.11 / 2015-10-06 +### Styles +* MediaWiki theme: Make shadows translucent black instead of light grey (Ed Sanders) +* MediaWiki theme: Make PHP DropdownInputWidget look closer to JS version (Bartosz Dziewoński) + +### Code +* Follow-up I4acbe69420: BookletLayout: Fix focus of page switching (Ed Sanders) +* IndexLayout: Fix focus of panel switching (Ed Sanders) +* TextInputWidget: Remove 'autocomplete' attribute on page navigation (Bartosz Dziewoński) +* build: Bump es5-shim and various devDependencies to master (James D. Forrester) + +## v0.12.10 / 2015-09-29 +### Styles +* Fix icon/indicator padding on TextInputWidget/SelectFileWidget (Ed Sanders) + +### Code +* CapsuleItemWidget: Remove 'click' event preventing (Bartosz Dziewoński) +* FloatableElement: Don't try unbinding events before we bind them (Bartosz Dziewoński) +* SelectWidget: Ensure 'choose' never emits null (Ed Sanders) +* Remove old textInputWidget-decorated classes (Ed Sanders) +* build: Upgrade MediaWiki-Codesniffer to 0.4.0 (Kunal Mehta) + +## v0.12.9 / 2015-09-22 +### Features +* BookletLayout, IndexLayout: Make autoFocus and focussing more reliable (Bartosz Dziewoński) +* CapsuleMultiSelectWidget: Allow using CapsuleItemWidget subclasses (Bartosz Dziewoński) +* CardLayout: Add a 'label' config option (Ed Sanders) +* FloatableElement: Introduce mixin (Bartosz Dziewoński) +* FloatingMenuSelectWidget: Update position of menus within overlay while scrolling (Bartosz Dziewoński) +* IndexLayout: Add 'expanded' option, passed through to StackLayout (Ed Sanders) +* MenuLayout: Use child selectors to allow nesting menus (Ed Sanders) +* Re-attempt I31ab2bace4: Try to stop user from tabbing outside of open dialog box (Ed Sanders) + +### Styles +* SelectFileWidget: Move file type over to the right in secondary text colour (Ed Sanders) +* Fix focus styles on disabled widgets (Volker E) +* Apex, MediaWiki themes: Make most borders on table icon thinner (Ed Sanders) +* Apex, MediaWiki themes: Make picture icon border thinner (Ed Sanders) +* MediaWiki theme: Alter buttons' padding and position icons absolutely (nirzar) +* MediaWiki theme: Fix height of IndexLayout tab widget (Ed Sanders) +* MediaWiki theme: Unify box-shadows for PopupWidget and DropdownWidget (Volker E) + +### Code +* #isFocusableElement: Rewrite for performance and correctness (Ed Sanders) +* BookletLayout: Remove unnecessary JSHint override (Bartosz Dziewoński) +* DropdownWidget: Update example doc to show #getMenu usage (Ed Sanders) +* Follow-up bf1497be: Fix PopupToolGroup use of renamed Clippable property (Ed Sanders) +* PopupWidget: Add missing `@mixins` doc entry (Bartosz Dziewoński) +* SelectFileWidget: Fix DOM order of file type label (Ed Sanders) +* Widget: Fix docs for disable event (Ed Sanders) +* docs: Remove excess empty lines in comments (Bartosz Dziewoński) +* docs: Add quotes around PROJECT_BRIEF setting (Timo Tijhof) +* Update version requirement for mediawiki/at-ease: 1.0.0 → 1.1.0 (Ori Livneh) + +## v0.12.8.1 / 2015-09-18 special release +### Code +* build: Update version requirement for mediawiki/at-ease: 1.0.0 → 1.1.0 (Ori Livneh) + +## v0.12.8 / 2015-09-08 +### Styles +* SelectFileWidget: Overflow and ellipsis for label (Ed Sanders) +* Apex theme: Move transition timing to common variables (Prateek Saxena) +* MediaWiki theme: Move window transition to `@medium-ease` variable (Prateek Saxena) +* MediaWiki theme: Add missing `width` and `height` attributes to icons (Ed Sanders) +* Clean up CSS values in .oo-ui-transition calls (Timo Tijhof) +* Use 'ease' instead of 'ease-in-out' for CSS transitions (Timo Tijhof) + +### Code +* Toolbar: Prevent double initialization (Roan Kattouw) +* build: Bump grunt-contrib-jshint from 0.11.2 to 0.11.3 to fix upstream issue (James D. Forrester) +* build: Upgrade grunt-banana-checker to v0.3.0 (James D. Forrester) + +## v0.12.7 / 2015-09-01 +### Deprecations +* [DEPRECATING CHANGE] SelectFileWidget: Re-design to use a clearly clickable button (Ed Sanders) + +### Styles +* FieldLayout: Don't add `margin-bottom` when in a HorizontalLayout (Florian) +* SelectFileWidget: Use gray for hover and `@progressive-fade` for drop active (Prateek Saxena) +* Apex, MediaWiki themes: Fix scale of external link icon (Ed Sanders) +* Apex, MediaWiki themes: Re-crush all SVG files with SVGO (James D. Forrester) +* Apex, MediaWiki themes: Reduce size of 'close' icon by 1px (Ed Sanders) +* Apex, MediaWiki themes: Remove Inkscape-ism from SVG files (James D. Forrester) +* Apex, MediaWiki themes: Standardise XML prolog for SVG files (Bartosz Dziewoński) +* MediaWiki theme: Fix viewBox of arrow indicators (Ed Sanders) +* MediaWiki theme: Fix viewBox of several icons (James D. Forrester) + +### Code +* LookupElement: Really disallow editing of `readOnly` TextInputWidgets (Bartosz Dziewoński) +* SelectFileWidget: Fix drop and drop hover exception in Firefox (Ed Sanders) +* SelectFileWidget: Improve type checking (Ed Sanders) + +## v0.12.6 / 2015-08-25 +### Features +* AccessKeyedElement: Introduce (Florian) +* ButtonOptionWidget: Mixin TitledElement (Bartosz Dziewoński) +* ClippableElement: Allow $clippableContainer to be different from $clippable (Roan Kattouw) +* Dialog: Listen for Escape key on $element, not document (Roan Kattouw) +* InputWidget: Add TitledElement and AccessKeyedElement mixins (Florian) +* PopupWidget: Make it possible to add static footers (Moriel Schottlender) +* SelectFileWidget: Add drag drop UI as a config (Prateek Saxena) +* TextInputWidget: Add moveCursorToEnd() (Roan Kattouw) + +### Styles +* MenuToolGroup: Add some missing styles for tools' 'check' icons (Bartosz Dziewoński) +* PopupWidget: don't apply header styles to footer (Roan Kattouw) +* SelectFileWidget: Mute the drag and drop design (Ed Sanders) +* Add colour to neutral state of MW frameless buttons (Ed Sanders) +* Editing-advanced icon pack: Add 'calendar' (Bartosz Dziewoński) + +### Code +* DropdownInputWidget: Allow users to pass config options to DropdownWidget (Alex Monk) +* Theme: Add theme classes to $icon and $indicator only (Bartosz Dziewoński) +* Use OO.ui.debounce() for Element#updateThemeClasses (Roan Kattouw) +* Document browser-specific code with support comments (Timo Tijhof) +* Update OOjs to v1.1.9 (James D. Forrester) +* Fix file permissions (Southparkfan) +* Fix inArray test in drag handler (Ed Sanders) +* Prefer ES5 over jQuery methods (Bartosz Dziewoński) +* build: Enable jscs rule 'requireSpacesInsideBrackets' and make pass (James D. Forrester) +* build: Enable jscs rule 'requireVarDeclFirst' and make pass (James D. Forrester) +* build: Make `quick-build` build the 'mixed' distribution (James D. Forrester) +* build: Update jscs devDependency from 1.8.0 to 2.1.0 (James D. Forrester) +* build: Update various devDependencies to latest (James D. Forrester) +* core: Remove spurious "[description]" placeholder from documentation (Timo Tijhof) +* demos, tests: Use es5-shim for IE8 compatibility (Bartosz Dziewoński) +* phpcs.xml: Ignore JS demo files in the PHP distribution (James D. Forrester) +* testsuitegenerator: Do not generate nonsensical tests for 'maxLength' (Bartosz Dziewoński) + +## v0.12.5 / 2015-08-18 +### Features +* CapsuleMultiSelectWidget: Unbreak $overlay config option (Bartosz Dziewoński) +* FloatingMenuSelectWidget: Introduce, based on TextInputMenuSelectWidget (Bartosz Dziewoński) +* FieldLayout: Throw an error if no widget is provided (Prateek Saxena) +* MessageDialog: Focus primary action button when the dialog opens (Prateek Saxena) + +### Styles +* DropdownWidget: Remove additional vertical margin, for consistency (Bartosz Dziewoński) +* FieldLayout: Correct rendering of multiline messages in MediaWiki theme (Bartosz Dziewoński) +* Move base icon/indicator styles out of themes (Roan Kattouw) +* MediaWiki theme: Correct styling of nested buttons (Bartosz Dziewoński) + +### Code +* DropdownWidget: Add $overlay config option (Bartosz Dziewoński) +* IconElement, IndicatorElement: Apply base styles to the right selector (Bartosz Dziewoński) +* Add background-repeat: no-repeat; to default icon/indicator styles (Roan Kattouw) +* Remove redundant background rules for icons/indicators (Roan Kattouw) +* Revert "TextInputWidget: Update doc'ed requirements for validate function" (Prtksxna) +* Don't directly use #addEventListener for compatibility with IE 8 (Bartosz Dziewoński) +* demos: Add a demo of the $overlay config option of various widgets (Bartosz Dziewoński) + +## v0.12.4 / 2015-08-13 +### Styles +* CapsuleMultiSelectWidget: Style tweaks (Ed Sanders) + +### Code +* MenuSelectWidget: Call #updateItemVisibility in more cases (Bartosz Dziewoński) +* PopupWidget: Remove 'focusout' handling again, limit to CapsuleMultiSelectWidget (Bartosz Dziewoński) + +## v0.12.3 / 2015-08-11 +### Deprecations +* [DEPRECATING CHANGE] TextInputWidget: Add getValidity function, deprecate isValid (Prateek Saxena) + +### Features +* Add OO.ui.isSafeUrl() to make sure url targets are safe client-side (Kunal Mehta) +* CapsuleMultiSelectWidget: Introduce (Brad Jorsch) +* FieldLayout: Allow displaying errors or notices next to fields (Bartosz Dziewoński) +* HorizontalLayout: Introduce (Bartosz Dziewoński) +* If ProcessDialog#fitLabel is called before dialog is open, defer (Ed Sanders) +* Mixin TitledElement into DropdownInputWidget and FieldLayout (Florian) +* Preserve dynamic state of widgets when infusing (Bartosz Dziewoński) +* TextInputWidget: Don't forget to positionLabel() after it's been unset (Bartosz Dziewoński) + +### Styles +* FieldLayout: Kill 'list-style-image' too for messages list (Bartosz Dziewoński) +* PopupToolGroup: Handle popup position on very narrow screens (Ed Sanders) +* ToggleSwitchWidget: Update according to spec (Prateek Saxena) +* MediaWiki, Apex themes: Fix height of frameless toolbar button (Ed Sanders) +* Apex theme: Correct disabled iconed button tool's text colour (Ed Sanders) +* Revert "Dialog: Increase z-index of .oo-ui-dialog to 1000+" (Ed Sanders) + +### Code +* ButtonOptionWidget: Make it more difficult to set an inappropriate 'tabIndex' (Bartosz Dziewoński) +* TextInputWidget: Update doc'ed requirements for validate function (Prateek Saxena) +* TextInputWidget: Use getValidity in setValidityFlag (Prateek Saxena) +* Element: DWIM when repeatedly infusing the same node (Bartosz Dziewoński) +* Element: Preserve 'classes' config option through infusion (Bartosz Dziewoński) +* demo: Make compatible with IE 8 (Bartosz Dziewoński) +* build: Exclude irrelevant files from Composer PHP package (Timo Tijhof) +* build: Move phpcs config from composer.json to phpcs.xml (Timo Tijhof) +* build: Output doxygen to "doc" for consistency with other PHP libraries (Kunal Mehta) +* build: Switch svg2png to personal build which fixes long lines (James D. Forrester) +* demos, tests: Use `.parent` instead of `.super` (Bartosz Dziewoński) +* docparser: Add rudimentary error handling (Bartosz Dziewoński) +* doxygen: Use default directory for HTML_OUTPUT (Kunal Mehta) +* tests: Twist the time in comparison tests in a different manner (Bartosz Dziewoński) +* testsuitegenerator: Output the number of generated test cases (Bartosz Dziewoński) + +## v0.12.2 / 2015-07-28 + +### Styles +* Dialog: Increase z-index of .oo-ui-dialog to 1000+ (Prateek Saxena) +* MediaWiki theme: Create new 'accessibility' icon pack (Violetto) + +### Code +* SelectWidget: Fix @mixins documentation (Roan Kattouw) +* Update OOjs to v1.1.8 (James D. Forrester) + +## v0.12.1 / 2015-07-22 + +### Features +* PendingElement: Make this actually useful (Roan Kattouw) +* TextInputWidget: Handle required: true better (Bartosz Dziewoński) +* TextInputWidget: Handle type: 'search' better (Bartosz Dziewoński) + +### Styles +* PanelLayout: Add some vertical margin when 'padded' and 'framed' (Bartosz Dziewoński) +* MediaWiki, Apex themes: Add 'clear' indicator (Bartosz Dziewoński) +* MediaWiki theme: Align colour of toolbar and dropdown buttons (Prateek Saxena) + +### Code +* Window: Compute directionality only when needed (Roan Kattouw) +* Standardise some common comments (Bartosz Dziewoński) +* build: Add clean:demos task (Bartosz Dziewoński) +* build: Add clean:tests task (Bartosz Dziewoński) +* build: Have copyright header reference "OOjs UI" team (Kunal Mehta) +* build: Use new grunt-tyops package rather than local original (James D. Forrester) +* Gruntfile: Fix 'pgk' to 'pkg' and add to typos list (James D. Forrester) +* package.json: Use proper SPDX license notation (Derk-Jan Hartman) + +## v0.12.0 / 2015-07-13 +### Breaking changes +* [BREAKING CHANGE] SearchWidget: Remove deprecated event re-emission (Ed Sanders) + +### Features +* Allow infusion of widgets in other namespaces (Kunal Mehta) +* Only allow construction of classes that extend OO.ui.Element in infusion (Kunal Mehta) +* ButtonInputWidget: Disable generating `