upgraded dependencies
This commit is contained in:
195
.idea/community.iml
generated
195
.idea/community.iml
generated
@@ -5,125 +5,137 @@
|
||||
<sourceFolder url="file://$MODULE_DIR$/app" isTestSource="false" packagePrefix="App\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="false" packagePrefix="Tests\" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dom-crawler" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/debug" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/php-parallel-lint/php-console-color" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/php-parallel-lint/php-console-highlighter" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/aws/aws-sdk-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/aws/aws-crt-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/davejamesmiller/laravel-breadcrumbs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravelcollective/html" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-kernel" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/propaganistas/laravel-phone" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-iconv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nicolaslopezj/searchable" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/php-webdriver/webdriver" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/dragonmantank/cron-expression" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/thomaswelton/laravel-gravatar" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/thomaswelton/gravatarlib" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/swiftmailer/swiftmailer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/intervention/image" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nunomaduro/collision" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/maatwebsite/excel" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/yaml" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/php-diff" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/phpspec" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/lines-of-code" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/php-enum" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoffice/phpspreadsheet" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/matrix" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/mtdowling/jmespath.php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/dusk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/maennchen/zipstream-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/mockery/mockery" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoffice/phpspreadsheet" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/complex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/tinker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/matrix" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/maennchen/zipstream-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/vsmoraes/laravel-pdf" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/framework" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/fideloper/proxy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/giggsey/libphonenumber-for-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/unisharp/laravel-ckeditor" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/socialite" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/unisharp/laravel-filemanager" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/lcobucci/jwt" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/giggsey/locale" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/neitanod/forceutf8" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/bugsnag/bugsnag-psr-logger" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/gitonomy/gitlib" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/dnoegel/php-xdg-base-dir" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/unisharp/laravel-filemanager" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/hamcrest/hamcrest-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/bugsnag/bugsnag" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/bugsnag/bugsnag-laravel" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/lcobucci/jwt" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/fakerphp/faker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/torann/geoip" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/vlucas/phpdotenv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/gitonomy/gitlib" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/deprecations" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/scrivo/highlight.php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/event-manager" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/tedivm/fetch" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/predis/predis" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/event-manager" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dom-crawler" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php81" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-kernel" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-iconv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/yaml" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/php-diff" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/phpspec" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/php-enum" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/dusk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/mockery/mockery" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/framework" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/ui" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/socialite" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/tinker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/giggsey/locale" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/giggsey/libphonenumber-for-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/bugsnag/bugsnag-psr-logger" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/bugsnag/bugsnag" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/bugsnag/bugsnag-laravel" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/torann/geoip" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/vlucas/phpdotenv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/tedivm/fetch" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/predis/predis" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/collection" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/namshi/jose" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/league/commonmark" />
|
||||
@@ -138,25 +150,18 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/dompdf/dompdf" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ezyang/htmlpurifier" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/brozot/laravel-fcm" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/codacy/coverage" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/tymon/jwt-auth" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/yajra/laravel-datatables-oracle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/codacy/coverage" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phenx/php-font-lib" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/opis/closure" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/tymon/jwt-auth" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/mremi/url-shortener" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/opis/closure" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/voku/portable-ascii" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psy/psysh" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/aws/aws-crt-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/aws/aws-sdk-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
195
.idea/php.xml
generated
195
.idea/php.xml
generated
@@ -2,125 +2,137 @@
|
||||
<project version="4">
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/debug" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/php-parallel-lint/php-console-color" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||
<path value="$PROJECT_DIR$/vendor/php-parallel-lint/php-console-highlighter" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-client" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/container" />
|
||||
<path value="$PROJECT_DIR$/vendor/aws/aws-sdk-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/aws/aws-crt-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/composer" />
|
||||
<path value="$PROJECT_DIR$/vendor/davejamesmiller/laravel-breadcrumbs" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/console" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravelcollective/html" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
|
||||
<path value="$PROJECT_DIR$/vendor/propaganistas/laravel-phone" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-iconv" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/nicolaslopezj/searchable" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<path value="$PROJECT_DIR$/vendor/php-webdriver/webdriver" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||
<path value="$PROJECT_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
|
||||
<path value="$PROJECT_DIR$/vendor/dragonmantank/cron-expression" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
|
||||
<path value="$PROJECT_DIR$/vendor/thomaswelton/laravel-gravatar" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
|
||||
<path value="$PROJECT_DIR$/vendor/thomaswelton/gravatarlib" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
|
||||
<path value="$PROJECT_DIR$/vendor/swiftmailer/swiftmailer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/intervention/image" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/nunomaduro/collision" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
|
||||
<path value="$PROJECT_DIR$/vendor/maatwebsite/excel" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
|
||||
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
|
||||
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
|
||||
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/process" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpspec/php-diff" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpspec/phpspec" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
|
||||
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpoption/phpoption" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
|
||||
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
|
||||
<path value="$PROJECT_DIR$/vendor/myclabs/php-enum" />
|
||||
<path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
|
||||
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpoffice/phpspreadsheet" />
|
||||
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
|
||||
<path value="$PROJECT_DIR$/vendor/markbaker/matrix" />
|
||||
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
|
||||
<path value="$PROJECT_DIR$/vendor/mtdowling/jmespath.php" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/dusk" />
|
||||
<path value="$PROJECT_DIR$/vendor/maennchen/zipstream-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/mockery/mockery" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpoffice/phpspreadsheet" />
|
||||
<path value="$PROJECT_DIR$/vendor/markbaker/complex" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/tinker" />
|
||||
<path value="$PROJECT_DIR$/vendor/markbaker/matrix" />
|
||||
<path value="$PROJECT_DIR$/vendor/fruitcake/laravel-cors" />
|
||||
<path value="$PROJECT_DIR$/vendor/maennchen/zipstream-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/vsmoraes/laravel-pdf" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/framework" />
|
||||
<path value="$PROJECT_DIR$/vendor/fideloper/proxy" />
|
||||
<path value="$PROJECT_DIR$/vendor/giggsey/libphonenumber-for-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/unisharp/laravel-ckeditor" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/socialite" />
|
||||
<path value="$PROJECT_DIR$/vendor/unisharp/laravel-filemanager" />
|
||||
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
|
||||
<path value="$PROJECT_DIR$/vendor/lcobucci/jwt" />
|
||||
<path value="$PROJECT_DIR$/vendor/giggsey/locale" />
|
||||
<path value="$PROJECT_DIR$/vendor/neitanod/forceutf8" />
|
||||
<path value="$PROJECT_DIR$/vendor/bugsnag/bugsnag-psr-logger" />
|
||||
<path value="$PROJECT_DIR$/vendor/gitonomy/gitlib" />
|
||||
<path value="$PROJECT_DIR$/vendor/dnoegel/php-xdg-base-dir" />
|
||||
<path value="$PROJECT_DIR$/vendor/unisharp/laravel-filemanager" />
|
||||
<path value="$PROJECT_DIR$/vendor/hamcrest/hamcrest-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/bugsnag/bugsnag" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
|
||||
<path value="$PROJECT_DIR$/vendor/bugsnag/bugsnag-laravel" />
|
||||
<path value="$PROJECT_DIR$/vendor/lcobucci/jwt" />
|
||||
<path value="$PROJECT_DIR$/vendor/fakerphp/faker" />
|
||||
<path value="$PROJECT_DIR$/vendor/torann/geoip" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
|
||||
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
|
||||
<path value="$PROJECT_DIR$/vendor/gitonomy/gitlib" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/deprecations" />
|
||||
<path value="$PROJECT_DIR$/vendor/scrivo/highlight.php" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
|
||||
<path value="$PROJECT_DIR$/vendor/tedivm/fetch" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/predis/predis" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
|
||||
<path value="$PROJECT_DIR$/vendor/ramsey/uuid" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" />
|
||||
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/console" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php81" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-iconv" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/string" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/process" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpspec/php-diff" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpspec/phpspec" />
|
||||
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
|
||||
<path value="$PROJECT_DIR$/vendor/myclabs/php-enum" />
|
||||
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
|
||||
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
|
||||
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/dusk" />
|
||||
<path value="$PROJECT_DIR$/vendor/mockery/mockery" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/framework" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/ui" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/socialite" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/tinker" />
|
||||
<path value="$PROJECT_DIR$/vendor/giggsey/locale" />
|
||||
<path value="$PROJECT_DIR$/vendor/giggsey/libphonenumber-for-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/bugsnag/bugsnag-psr-logger" />
|
||||
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
|
||||
<path value="$PROJECT_DIR$/vendor/bugsnag/bugsnag" />
|
||||
<path value="$PROJECT_DIR$/vendor/bugsnag/bugsnag-laravel" />
|
||||
<path value="$PROJECT_DIR$/vendor/torann/geoip" />
|
||||
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
|
||||
<path value="$PROJECT_DIR$/vendor/ramsey/uuid" />
|
||||
<path value="$PROJECT_DIR$/vendor/tedivm/fetch" />
|
||||
<path value="$PROJECT_DIR$/vendor/predis/predis" />
|
||||
<path value="$PROJECT_DIR$/vendor/ramsey/collection" />
|
||||
<path value="$PROJECT_DIR$/vendor/namshi/jose" />
|
||||
<path value="$PROJECT_DIR$/vendor/nesbot/carbon" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/commonmark" />
|
||||
@@ -135,25 +147,18 @@
|
||||
<path value="$PROJECT_DIR$/vendor/facade/ignition" />
|
||||
<path value="$PROJECT_DIR$/vendor/dompdf/dompdf" />
|
||||
<path value="$PROJECT_DIR$/vendor/ezyang/htmlpurifier" />
|
||||
<path value="$PROJECT_DIR$/vendor/brozot/laravel-fcm" />
|
||||
<path value="$PROJECT_DIR$/vendor/codacy/coverage" />
|
||||
<path value="$PROJECT_DIR$/vendor/tymon/jwt-auth" />
|
||||
<path value="$PROJECT_DIR$/vendor/yajra/laravel-datatables-oracle" />
|
||||
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/codacy/coverage" />
|
||||
<path value="$PROJECT_DIR$/vendor/phenx/php-font-lib" />
|
||||
<path value="$PROJECT_DIR$/vendor/opis/closure" />
|
||||
<path value="$PROJECT_DIR$/vendor/tymon/jwt-auth" />
|
||||
<path value="$PROJECT_DIR$/vendor/mremi/url-shortener" />
|
||||
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/asm89/stack-cors" />
|
||||
<path value="$PROJECT_DIR$/vendor/brick/math" />
|
||||
<path value="$PROJECT_DIR$/vendor/opis/closure" />
|
||||
<path value="$PROJECT_DIR$/vendor/voku/portable-ascii" />
|
||||
<path value="$PROJECT_DIR$/vendor/psy/psysh" />
|
||||
<path value="$PROJECT_DIR$/vendor/filp/whoops" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-client" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/container" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
|
||||
<path value="$PROJECT_DIR$/vendor/aws/aws-crt-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/aws/aws-sdk-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/composer" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
|
||||
|
@@ -19,7 +19,6 @@
|
||||
"nicolaslopezj/searchable": "^1.13",
|
||||
"tymon/jwt-auth": "1.0.2",
|
||||
"davejamesmiller/laravel-breadcrumbs": "^5.3",
|
||||
"brozot/laravel-fcm": "^1.3",
|
||||
"aws/aws-sdk-php": "^3.18",
|
||||
"predis/predis": "~1.0",
|
||||
"mremi/url-shortener": "^1.0",
|
||||
@@ -27,7 +26,6 @@
|
||||
"laravel/socialite": "^4.2",
|
||||
"tedivm/fetch": "0.6.*",
|
||||
"unisharp/laravel-filemanager": "^2.0",
|
||||
"unisharp/laravel-ckeditor": "dev-master",
|
||||
"torann/geoip": "^1.2",
|
||||
"yajra/laravel-datatables-oracle": "9.10.0",
|
||||
"flowjs/flow-php-server": "^1.0",
|
||||
@@ -40,11 +38,10 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.8|^9.3.3",
|
||||
"phpspec/phpspec": "^4.0",
|
||||
"phpspec/phpspec": "^7.2.0",
|
||||
"symfony/dom-crawler": "^5.0",
|
||||
"symfony/css-selector": "^5.0",
|
||||
"laravel/dusk": "^5.5",
|
||||
"laravel/tinker": "^1.0",
|
||||
"codacy/coverage": "dev-master",
|
||||
"nunomaduro/collision": "^4.3",
|
||||
"mockery/mockery": "^1.3.1",
|
||||
|
2746
composer.lock
generated
2746
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,7 @@ return [
|
||||
| your application so that it is used when running Artisan tasks.
|
||||
|
|
||||
*/
|
||||
'url' => env('APP_URL'),
|
||||
'url' => env('APP_URL', 'http://localhost'),
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Timezone
|
||||
@@ -173,8 +173,6 @@ return [
|
||||
\Torann\GeoIP\GeoIPServiceProvider::class,
|
||||
Unisharp\Laravelfilemanager\LaravelFilemanagerServiceProvider::class,
|
||||
Intervention\Image\ImageServiceProvider::class,
|
||||
Unisharp\Ckeditor\ServiceProvider::class,
|
||||
LaravelFCM\FCMServiceProvider::class,
|
||||
//Collective\Bus\BusServiceProvider::class,
|
||||
Maatwebsite\Excel\ExcelServiceProvider::class,
|
||||
Laravel\Socialite\SocialiteServiceProvider::class,
|
||||
|
19
vendor/asm89/stack-cors/LICENSE
vendored
Normal file
19
vendor/asm89/stack-cors/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013-2017 Alexander <iam.asm89@gmail.com>
|
||||
|
||||
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.
|
83
vendor/asm89/stack-cors/README.md
vendored
Normal file
83
vendor/asm89/stack-cors/README.md
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
# Stack/Cors
|
||||
|
||||
Library and middleware enabling cross-origin resource sharing for your
|
||||
http-{foundation,kernel} using application. It attempts to implement the
|
||||
[W3C Recommendation] for cross-origin resource sharing.
|
||||
|
||||
[W3C Recommendation]: http://www.w3.org/TR/cors/
|
||||
|
||||
Build status: 
|
||||
|
||||
## Installation
|
||||
|
||||
Require `asm89/stack-cors` using composer.
|
||||
|
||||
## Usage
|
||||
|
||||
This package can be used as a library or as [stack middleware].
|
||||
|
||||
[stack middleware]: http://stackphp.com/
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Description | Default value |
|
||||
|------------------------|------------------------------------------------------------|---------------|
|
||||
| allowedMethods | Matches the request method. | `[]` |
|
||||
| allowedOrigins | Matches the request origin. | `[]` |
|
||||
| allowedOriginsPatterns | Matches the request origin with `preg_match`. | `[]` |
|
||||
| allowedHeaders | Sets the Access-Control-Allow-Headers response header. | `[]` |
|
||||
| exposedHeaders | Sets the Access-Control-Expose-Headers response header. | `false` |
|
||||
| maxAge | Sets the Access-Control-Max-Age response header. | `false` |
|
||||
| supportsCredentials | Sets the Access-Control-Allow-Credentials header. | `false` |
|
||||
|
||||
The _allowedMethods_ and _allowedHeaders_ options are case-insensitive.
|
||||
|
||||
You don't need to provide both _allowedOrigins_ and _allowedOriginsPatterns_. If one of the strings passed matches, it is considered a valid origin.
|
||||
|
||||
If `['*']` is provided to _allowedMethods_, _allowedOrigins_ or _allowedHeaders_ all methods / origins / headers are allowed.
|
||||
|
||||
### Example: using the library
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Asm89\Stack\CorsService;
|
||||
|
||||
$cors = new CorsService([
|
||||
'allowedHeaders' => ['x-allowed-header', 'x-other-allowed-header'],
|
||||
'allowedMethods' => ['DELETE', 'GET', 'POST', 'PUT'],
|
||||
'allowedOrigins' => ['http://localhost'],
|
||||
'allowedOriginsPatterns' => ['/localhost:\d/'],
|
||||
'exposedHeaders' => false,
|
||||
'maxAge' => false,
|
||||
'supportsCredentials' => false,
|
||||
]);
|
||||
|
||||
$cors->addActualRequestHeaders(Response $response, $origin);
|
||||
$cors->handlePreflightRequest(Request $request);
|
||||
$cors->isActualRequestAllowed(Request $request);
|
||||
$cors->isCorsRequest(Request $request);
|
||||
$cors->isPreflightRequest(Request $request);
|
||||
```
|
||||
|
||||
## Example: using the stack middleware
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Asm89\Stack\Cors;
|
||||
|
||||
$app = new Cors($app, [
|
||||
// you can use ['*'] to allow any headers
|
||||
'allowedHeaders' => ['x-allowed-header', 'x-other-allowed-header'],
|
||||
// you can use ['*'] to allow any methods
|
||||
'allowedMethods' => ['DELETE', 'GET', 'POST', 'PUT'],
|
||||
// you can use ['*'] to allow requests from any origin
|
||||
'allowedOrigins' => ['localhost'],
|
||||
// you can enter regexes that are matched to the origin request header
|
||||
'allowedOriginsPatterns' => ['/localhost:\d/'],
|
||||
'exposedHeaders' => false,
|
||||
'maxAge' => false,
|
||||
'supportsCredentials' => false,
|
||||
]);
|
||||
```
|
43
vendor/asm89/stack-cors/composer.json
vendored
Normal file
43
vendor/asm89/stack-cors/composer.json
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
"description": "Cross-origin resource sharing library and stack middleware",
|
||||
"keywords": ["stack", "cors"],
|
||||
"homepage": "https://github.com/asm89/stack-cors",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Alexander",
|
||||
"email": "iam.asm89@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2|^8.0",
|
||||
"symfony/http-foundation": "^4|^5|^6",
|
||||
"symfony/http-kernel": "^4|^5|^6"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7|^9",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Asm89\\Stack\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Asm89\\Stack\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit",
|
||||
"check-style": "phpcs -p --standard=PSR12 --exclude=Generic.Files.LineLength --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src",
|
||||
"fix-style": "phpcbf -p --standard=PSR12 --exclude=Generic.Files.LineLength --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1-dev"
|
||||
}
|
||||
}
|
||||
}
|
61
vendor/asm89/stack-cors/src/Cors.php
vendored
Normal file
61
vendor/asm89/stack-cors/src/Cors.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of asm89/stack-cors.
|
||||
*
|
||||
* (c) Alexander <iam.asm89@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Asm89\Stack;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class Cors implements HttpKernelInterface
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* @var \Asm89\Stack\CorsService
|
||||
*/
|
||||
private $cors;
|
||||
|
||||
private $defaultOptions = [
|
||||
'allowedHeaders' => [],
|
||||
'allowedMethods' => [],
|
||||
'allowedOrigins' => [],
|
||||
'allowedOriginsPatterns' => [],
|
||||
'exposedHeaders' => [],
|
||||
'maxAge' => 0,
|
||||
'supportsCredentials' => false,
|
||||
];
|
||||
|
||||
public function __construct(HttpKernelInterface $app, array $options = [])
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->cors = new CorsService(array_merge($this->defaultOptions, $options));
|
||||
}
|
||||
|
||||
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true): Response
|
||||
{
|
||||
if ($this->cors->isPreflightRequest($request)) {
|
||||
$response = $this->cors->handlePreflightRequest($request);
|
||||
return $this->cors->varyHeader($response, 'Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
$response = $this->app->handle($request, $type, $catch);
|
||||
|
||||
if ($request->getMethod() === 'OPTIONS') {
|
||||
$this->cors->varyHeader($response, 'Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
return $this->cors->addActualRequestHeaders($response, $request);
|
||||
}
|
||||
}
|
225
vendor/asm89/stack-cors/src/CorsService.php
vendored
Normal file
225
vendor/asm89/stack-cors/src/CorsService.php
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of asm89/stack-cors.
|
||||
*
|
||||
* (c) Alexander <iam.asm89@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Asm89\Stack;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CorsService
|
||||
{
|
||||
private $options;
|
||||
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
$this->options = $this->normalizeOptions($options);
|
||||
}
|
||||
|
||||
private function normalizeOptions(array $options = []): array
|
||||
{
|
||||
$options += [
|
||||
'allowedOrigins' => [],
|
||||
'allowedOriginsPatterns' => [],
|
||||
'supportsCredentials' => false,
|
||||
'allowedHeaders' => [],
|
||||
'exposedHeaders' => [],
|
||||
'allowedMethods' => [],
|
||||
'maxAge' => 0,
|
||||
];
|
||||
|
||||
// normalize array('*') to true
|
||||
if (in_array('*', $options['allowedOrigins'])) {
|
||||
$options['allowedOrigins'] = true;
|
||||
}
|
||||
if (in_array('*', $options['allowedHeaders'])) {
|
||||
$options['allowedHeaders'] = true;
|
||||
} else {
|
||||
$options['allowedHeaders'] = array_map('strtolower', $options['allowedHeaders']);
|
||||
}
|
||||
|
||||
if (in_array('*', $options['allowedMethods'])) {
|
||||
$options['allowedMethods'] = true;
|
||||
} else {
|
||||
$options['allowedMethods'] = array_map('strtoupper', $options['allowedMethods']);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use isOriginAllowed
|
||||
*/
|
||||
public function isActualRequestAllowed(Request $request): bool
|
||||
{
|
||||
return $this->isOriginAllowed($request);
|
||||
}
|
||||
|
||||
public function isCorsRequest(Request $request): bool
|
||||
{
|
||||
return $request->headers->has('Origin');
|
||||
}
|
||||
|
||||
public function isPreflightRequest(Request $request): bool
|
||||
{
|
||||
return $request->getMethod() === 'OPTIONS' && $request->headers->has('Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
public function handlePreflightRequest(Request $request): Response
|
||||
{
|
||||
$response = new Response();
|
||||
|
||||
$response->setStatusCode(204);
|
||||
|
||||
return $this->addPreflightRequestHeaders($response, $request);
|
||||
}
|
||||
|
||||
public function addPreflightRequestHeaders(Response $response, Request $request): Response
|
||||
{
|
||||
$this->configureAllowedOrigin($response, $request);
|
||||
|
||||
if ($response->headers->has('Access-Control-Allow-Origin')) {
|
||||
$this->configureAllowCredentials($response, $request);
|
||||
|
||||
$this->configureAllowedMethods($response, $request);
|
||||
|
||||
$this->configureAllowedHeaders($response, $request);
|
||||
|
||||
$this->configureMaxAge($response, $request);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function isOriginAllowed(Request $request): bool
|
||||
{
|
||||
if ($this->options['allowedOrigins'] === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$request->headers->has('Origin')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$origin = $request->headers->get('Origin');
|
||||
|
||||
if (in_array($origin, $this->options['allowedOrigins'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this->options['allowedOriginsPatterns'] as $pattern) {
|
||||
if (preg_match($pattern, $origin)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addActualRequestHeaders(Response $response, Request $request): Response
|
||||
{
|
||||
$this->configureAllowedOrigin($response, $request);
|
||||
|
||||
if ($response->headers->has('Access-Control-Allow-Origin')) {
|
||||
$this->configureAllowCredentials($response, $request);
|
||||
|
||||
$this->configureExposedHeaders($response, $request);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function configureAllowedOrigin(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['allowedOrigins'] === true && !$this->options['supportsCredentials']) {
|
||||
// Safe+cacheable, allow everything
|
||||
$response->headers->set('Access-Control-Allow-Origin', '*');
|
||||
} elseif ($this->isSingleOriginAllowed()) {
|
||||
// Single origins can be safely set
|
||||
$response->headers->set('Access-Control-Allow-Origin', array_values($this->options['allowedOrigins'])[0]);
|
||||
} else {
|
||||
// For dynamic headers, set the requested Origin header when set and allowed
|
||||
if ($this->isCorsRequest($request) && $this->isOriginAllowed($request)) {
|
||||
$response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin'));
|
||||
}
|
||||
|
||||
$this->varyHeader($response, 'Origin');
|
||||
}
|
||||
}
|
||||
|
||||
private function isSingleOriginAllowed(): bool
|
||||
{
|
||||
if ($this->options['allowedOrigins'] === true || !empty($this->options['allowedOriginsPatterns'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return count($this->options['allowedOrigins']) === 1;
|
||||
}
|
||||
|
||||
private function configureAllowedMethods(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['allowedMethods'] === true) {
|
||||
$allowMethods = strtoupper($request->headers->get('Access-Control-Request-Method'));
|
||||
$this->varyHeader($response, 'Access-Control-Request-Method');
|
||||
} else {
|
||||
$allowMethods = implode(', ', $this->options['allowedMethods']);
|
||||
}
|
||||
|
||||
$response->headers->set('Access-Control-Allow-Methods', $allowMethods);
|
||||
}
|
||||
|
||||
private function configureAllowedHeaders(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['allowedHeaders'] === true) {
|
||||
$allowHeaders = $request->headers->get('Access-Control-Request-Headers');
|
||||
$this->varyHeader($response, 'Access-Control-Request-Headers');
|
||||
} else {
|
||||
$allowHeaders = implode(', ', $this->options['allowedHeaders']);
|
||||
}
|
||||
$response->headers->set('Access-Control-Allow-Headers', $allowHeaders);
|
||||
}
|
||||
|
||||
private function configureAllowCredentials(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['supportsCredentials']) {
|
||||
$response->headers->set('Access-Control-Allow-Credentials', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
private function configureExposedHeaders(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['exposedHeaders']) {
|
||||
$response->headers->set('Access-Control-Expose-Headers', implode(', ', $this->options['exposedHeaders']));
|
||||
}
|
||||
}
|
||||
|
||||
private function configureMaxAge(Response $response, Request $request)
|
||||
{
|
||||
if ($this->options['maxAge'] !== null) {
|
||||
$response->headers->set('Access-Control-Max-Age', (int) $this->options['maxAge']);
|
||||
}
|
||||
}
|
||||
|
||||
public function varyHeader(Response $response, $header): Response
|
||||
{
|
||||
if (!$response->headers->has('Vary')) {
|
||||
$response->headers->set('Vary', $header);
|
||||
} elseif (!in_array($header, explode(', ', $response->headers->get('Vary')))) {
|
||||
$response->headers->set('Vary', $response->headers->get('Vary') . ', ' . $header);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function isSameHost(Request $request): bool
|
||||
{
|
||||
return $request->headers->get('Origin') === $request->getSchemeAndHttpHost();
|
||||
}
|
||||
}
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
@@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInite7140a2ec68f998789fab4fcb333821a::getLoader();
|
||||
return ComposerAutoloaderInit9da6744efcb5435630815fb416a6752c::getLoader();
|
||||
|
117
vendor/bin/patch-type-declarations
vendored
Executable file
117
vendor/bin/patch-type-declarations
vendored
Executable file
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../symfony/error-handler/Resources/bin/patch-type-declarations)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
|
||||
include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/error-handler/Resources/bin/patch-type-declarations');
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
include __DIR__ . '/..'.'/symfony/error-handler/Resources/bin/patch-type-declarations';
|
117
vendor/bin/yaml-lint
vendored
Executable file
117
vendor/bin/yaml-lint
vendored
Executable file
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../symfony/yaml/Resources/bin/yaml-lint)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
|
||||
include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint');
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
include __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint';
|
415
vendor/brick/math/CHANGELOG.md
vendored
Normal file
415
vendor/brick/math/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [0.9.3](https://github.com/brick/math/releases/tag/0.9.3) - 2021-08-15
|
||||
|
||||
🚀 **Compatibility with PHP 8.1**
|
||||
|
||||
- Support for custom object serialization; this removes a warning on PHP 8.1 due to the `Serializable` interface being deprecated (thanks @TRowbotham)
|
||||
|
||||
## [0.9.2](https://github.com/brick/math/releases/tag/0.9.2) - 2021-01-20
|
||||
|
||||
🐛 **Bug fix**
|
||||
|
||||
- Incorrect results could be returned when using the BCMath calculator, with a default scale set with `bcscale()`, on PHP >= 7.2 (#55).
|
||||
|
||||
## [0.9.1](https://github.com/brick/math/releases/tag/0.9.1) - 2020-08-19
|
||||
|
||||
✨ New features
|
||||
|
||||
- `BigInteger::not()` returns the bitwise `NOT` value
|
||||
|
||||
🐛 **Bug fixes**
|
||||
|
||||
- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers
|
||||
- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available
|
||||
|
||||
## [0.9.0](https://github.com/brick/math/releases/tag/0.9.0) - 2020-08-18
|
||||
|
||||
👌 **Improvements**
|
||||
|
||||
- `BigNumber::of()` now accepts `.123` and `123.` formats, both of which return a `BigDecimal`
|
||||
|
||||
💥 **Breaking changes**
|
||||
|
||||
- Deprecated method `BigInteger::powerMod()` has been removed - use `modPow()` instead
|
||||
- Deprecated method `BigInteger::parse()` has been removed - use `fromBase()` instead
|
||||
|
||||
## [0.8.17](https://github.com/brick/math/releases/tag/0.8.17) - 2020-08-19
|
||||
|
||||
🐛 **Bug fix**
|
||||
|
||||
- `BigInteger::toBytes()` could return an incorrect binary representation for some numbers
|
||||
- The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available
|
||||
|
||||
## [0.8.16](https://github.com/brick/math/releases/tag/0.8.16) - 2020-08-18
|
||||
|
||||
🚑 **Critical fix**
|
||||
|
||||
- This version reintroduces the deprecated `BigInteger::parse()` method, that has been removed by mistake in version `0.8.9` and should have lasted for the whole `0.8` release cycle.
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::modInverse()` calculates a modular multiplicative inverse
|
||||
- `BigInteger::fromBytes()` creates a `BigInteger` from a byte string
|
||||
- `BigInteger::toBytes()` converts a `BigInteger` to a byte string
|
||||
- `BigInteger::randomBits()` creates a pseudo-random `BigInteger` of a given bit length
|
||||
- `BigInteger::randomRange()` creates a pseudo-random `BigInteger` between two bounds
|
||||
|
||||
💩 **Deprecations**
|
||||
|
||||
- `BigInteger::powerMod()` is now deprecated in favour of `modPow()`
|
||||
|
||||
## [0.8.15](https://github.com/brick/math/releases/tag/0.8.15) - 2020-04-15
|
||||
|
||||
🐛 **Fixes**
|
||||
|
||||
- added missing `ext-json` requirement, due to `BigNumber` implementing `JsonSerializable`
|
||||
|
||||
⚡️ **Optimizations**
|
||||
|
||||
- additional optimization in `BigInteger::remainder()`
|
||||
|
||||
## [0.8.14](https://github.com/brick/math/releases/tag/0.8.14) - 2020-02-18
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::getLowestSetBit()` returns the index of the rightmost one bit
|
||||
|
||||
## [0.8.13](https://github.com/brick/math/releases/tag/0.8.13) - 2020-02-16
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::isEven()` tests whether the number is even
|
||||
- `BigInteger::isOdd()` tests whether the number is odd
|
||||
- `BigInteger::testBit()` tests if a bit is set
|
||||
- `BigInteger::getBitLength()` returns the number of bits in the minimal representation of the number
|
||||
|
||||
## [0.8.12](https://github.com/brick/math/releases/tag/0.8.12) - 2020-02-03
|
||||
|
||||
🛠️ **Maintenance release**
|
||||
|
||||
Classes are now annotated for better static analysis with [psalm](https://psalm.dev/).
|
||||
|
||||
This is a maintenance release: no bug fixes, no new features, no breaking changes.
|
||||
|
||||
## [0.8.11](https://github.com/brick/math/releases/tag/0.8.11) - 2020-01-23
|
||||
|
||||
✨ **New feature**
|
||||
|
||||
`BigInteger::powerMod()` performs a power-with-modulo operation. Useful for crypto.
|
||||
|
||||
## [0.8.10](https://github.com/brick/math/releases/tag/0.8.10) - 2020-01-21
|
||||
|
||||
✨ **New feature**
|
||||
|
||||
`BigInteger::mod()` returns the **modulo** of two numbers. The *modulo* differs from the *remainder* when the signs of the operands are different.
|
||||
|
||||
## [0.8.9](https://github.com/brick/math/releases/tag/0.8.9) - 2020-01-08
|
||||
|
||||
⚡️ **Performance improvements**
|
||||
|
||||
A few additional optimizations in `BigInteger` and `BigDecimal` when one of the operands can be returned as is. Thanks to @tomtomsen in #24.
|
||||
|
||||
## [0.8.8](https://github.com/brick/math/releases/tag/0.8.8) - 2019-04-25
|
||||
|
||||
🐛 **Bug fixes**
|
||||
|
||||
- `BigInteger::toBase()` could return an empty string for zero values (BCMath & Native calculators only, GMP calculator unaffected)
|
||||
|
||||
✨ **New features**
|
||||
|
||||
- `BigInteger::toArbitraryBase()` converts a number to an arbitrary base, using a custom alphabet
|
||||
- `BigInteger::fromArbitraryBase()` converts a string in an arbitrary base, using a custom alphabet, back to a number
|
||||
|
||||
These methods can be used as the foundation to convert strings between different bases/alphabets, using BigInteger as an intermediate representation.
|
||||
|
||||
💩 **Deprecations**
|
||||
|
||||
- `BigInteger::parse()` is now deprecated in favour of `fromBase()`
|
||||
|
||||
`BigInteger::fromBase()` works the same way as `parse()`, with 2 minor differences:
|
||||
|
||||
- the `$base` parameter is required, it does not default to `10`
|
||||
- it throws a `NumberFormatException` instead of an `InvalidArgumentException` when the number is malformed
|
||||
|
||||
## [0.8.7](https://github.com/brick/math/releases/tag/0.8.7) - 2019-04-20
|
||||
|
||||
**Improvements**
|
||||
|
||||
- Safer conversion from `float` when using custom locales
|
||||
- **Much faster** `NativeCalculator` implementation 🚀
|
||||
|
||||
You can expect **at least a 3x performance improvement** for common arithmetic operations when using the library on systems without GMP or BCMath; it gets exponentially faster on multiplications with a high number of digits. This is due to calculations now being performed on whole blocks of digits (the block size depending on the platform, 32-bit or 64-bit) instead of digit-by-digit as before.
|
||||
|
||||
## [0.8.6](https://github.com/brick/math/releases/tag/0.8.6) - 2019-04-11
|
||||
|
||||
**New method**
|
||||
|
||||
`BigNumber::sum()` returns the sum of one or more numbers.
|
||||
|
||||
## [0.8.5](https://github.com/brick/math/releases/tag/0.8.5) - 2019-02-12
|
||||
|
||||
**Bug fix**: `of()` factory methods could fail when passing a `float` in environments using a `LC_NUMERIC` locale with a decimal separator other than `'.'` (#20).
|
||||
|
||||
Thanks @manowark 👍
|
||||
|
||||
## [0.8.4](https://github.com/brick/math/releases/tag/0.8.4) - 2018-12-07
|
||||
|
||||
**New method**
|
||||
|
||||
`BigDecimal::sqrt()` calculates the square root of a decimal number, to a given scale.
|
||||
|
||||
## [0.8.3](https://github.com/brick/math/releases/tag/0.8.3) - 2018-12-06
|
||||
|
||||
**New method**
|
||||
|
||||
`BigInteger::sqrt()` calculates the square root of a number (thanks @peter279k).
|
||||
|
||||
**New exception**
|
||||
|
||||
`NegativeNumberException` is thrown when calling `sqrt()` on a negative number.
|
||||
|
||||
## [0.8.2](https://github.com/brick/math/releases/tag/0.8.2) - 2018-11-08
|
||||
|
||||
**Performance update**
|
||||
|
||||
- Further improvement of `toInt()` performance
|
||||
- `NativeCalculator` can now perform some multiplications more efficiently
|
||||
|
||||
## [0.8.1](https://github.com/brick/math/releases/tag/0.8.1) - 2018-11-07
|
||||
|
||||
Performance optimization of `toInt()` methods.
|
||||
|
||||
## [0.8.0](https://github.com/brick/math/releases/tag/0.8.0) - 2018-10-13
|
||||
|
||||
**Breaking changes**
|
||||
|
||||
The following deprecated methods have been removed. Use the new method name instead:
|
||||
|
||||
| Method removed | Replacement method |
|
||||
| --- | --- |
|
||||
| `BigDecimal::getIntegral()` | `BigDecimal::getIntegralPart()` |
|
||||
| `BigDecimal::getFraction()` | `BigDecimal::getFractionalPart()` |
|
||||
|
||||
---
|
||||
|
||||
**New features**
|
||||
|
||||
`BigInteger` has been augmented with 5 new methods for bitwise operations:
|
||||
|
||||
| New method | Description |
|
||||
| --- | --- |
|
||||
| `and()` | performs a bitwise `AND` operation on two numbers |
|
||||
| `or()` | performs a bitwise `OR` operation on two numbers |
|
||||
| `xor()` | performs a bitwise `XOR` operation on two numbers |
|
||||
| `shiftedLeft()` | returns the number shifted left by a number of bits |
|
||||
| `shiftedRight()` | returns the number shifted right by a number of bits |
|
||||
|
||||
Thanks to @DASPRiD 👍
|
||||
|
||||
## [0.7.3](https://github.com/brick/math/releases/tag/0.7.3) - 2018-08-20
|
||||
|
||||
**New method:** `BigDecimal::hasNonZeroFractionalPart()`
|
||||
|
||||
**Renamed/deprecated methods:**
|
||||
|
||||
- `BigDecimal::getIntegral()` has been renamed to `getIntegralPart()` and is now deprecated
|
||||
- `BigDecimal::getFraction()` has been renamed to `getFractionalPart()` and is now deprecated
|
||||
|
||||
## [0.7.2](https://github.com/brick/math/releases/tag/0.7.2) - 2018-07-21
|
||||
|
||||
**Performance update**
|
||||
|
||||
`BigInteger::parse()` and `toBase()` now use GMP's built-in base conversion features when available.
|
||||
|
||||
## [0.7.1](https://github.com/brick/math/releases/tag/0.7.1) - 2018-03-01
|
||||
|
||||
This is a maintenance release, no code has been changed.
|
||||
|
||||
- When installed with `--no-dev`, the autoloader does not autoload tests anymore
|
||||
- Tests and other files unnecessary for production are excluded from the dist package
|
||||
|
||||
This will help make installations more compact.
|
||||
|
||||
## [0.7.0](https://github.com/brick/math/releases/tag/0.7.0) - 2017-10-02
|
||||
|
||||
Methods renamed:
|
||||
|
||||
- `BigNumber:sign()` has been renamed to `getSign()`
|
||||
- `BigDecimal::unscaledValue()` has been renamed to `getUnscaledValue()`
|
||||
- `BigDecimal::scale()` has been renamed to `getScale()`
|
||||
- `BigDecimal::integral()` has been renamed to `getIntegral()`
|
||||
- `BigDecimal::fraction()` has been renamed to `getFraction()`
|
||||
- `BigRational::numerator()` has been renamed to `getNumerator()`
|
||||
- `BigRational::denominator()` has been renamed to `getDenominator()`
|
||||
|
||||
Classes renamed:
|
||||
|
||||
- `ArithmeticException` has been renamed to `MathException`
|
||||
|
||||
## [0.6.2](https://github.com/brick/math/releases/tag/0.6.2) - 2017-10-02
|
||||
|
||||
The base class for all exceptions is now `MathException`.
|
||||
`ArithmeticException` has been deprecated, and will be removed in 0.7.0.
|
||||
|
||||
## [0.6.1](https://github.com/brick/math/releases/tag/0.6.1) - 2017-10-02
|
||||
|
||||
A number of methods have been renamed:
|
||||
|
||||
- `BigNumber:sign()` is deprecated; use `getSign()` instead
|
||||
- `BigDecimal::unscaledValue()` is deprecated; use `getUnscaledValue()` instead
|
||||
- `BigDecimal::scale()` is deprecated; use `getScale()` instead
|
||||
- `BigDecimal::integral()` is deprecated; use `getIntegral()` instead
|
||||
- `BigDecimal::fraction()` is deprecated; use `getFraction()` instead
|
||||
- `BigRational::numerator()` is deprecated; use `getNumerator()` instead
|
||||
- `BigRational::denominator()` is deprecated; use `getDenominator()` instead
|
||||
|
||||
The old methods will be removed in version 0.7.0.
|
||||
|
||||
## [0.6.0](https://github.com/brick/math/releases/tag/0.6.0) - 2017-08-25
|
||||
|
||||
- Minimum PHP version is now [7.1](https://gophp71.org/); for PHP 5.6 and PHP 7.0 support, use version `0.5`
|
||||
- Deprecated method `BigDecimal::withScale()` has been removed; use `toScale()` instead
|
||||
- Method `BigNumber::toInteger()` has been renamed to `toInt()`
|
||||
|
||||
## [0.5.4](https://github.com/brick/math/releases/tag/0.5.4) - 2016-10-17
|
||||
|
||||
`BigNumber` classes now implement [JsonSerializable](http://php.net/manual/en/class.jsonserializable.php).
|
||||
The JSON output is always a string.
|
||||
|
||||
## [0.5.3](https://github.com/brick/math/releases/tag/0.5.3) - 2016-03-31
|
||||
|
||||
This is a bugfix release. Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
||||
|
||||
## [0.5.2](https://github.com/brick/math/releases/tag/0.5.2) - 2015-08-06
|
||||
|
||||
The `$scale` parameter of `BigDecimal::dividedBy()` is now optional again.
|
||||
|
||||
## [0.5.1](https://github.com/brick/math/releases/tag/0.5.1) - 2015-07-05
|
||||
|
||||
**New method: `BigNumber::toScale()`**
|
||||
|
||||
This allows to convert any `BigNumber` to a `BigDecimal` with a given scale, using rounding if necessary.
|
||||
|
||||
## [0.5.0](https://github.com/brick/math/releases/tag/0.5.0) - 2015-07-04
|
||||
|
||||
**New features**
|
||||
- Common `BigNumber` interface for all classes, with the following methods:
|
||||
- `sign()` and derived methods (`isZero()`, `isPositive()`, ...)
|
||||
- `compareTo()` and derived methods (`isEqualTo()`, `isGreaterThan()`, ...) that work across different `BigNumber` types
|
||||
- `toBigInteger()`, `toBigDecimal()`, `toBigRational`() conversion methods
|
||||
- `toInteger()` and `toFloat()` conversion methods to native types
|
||||
- Unified `of()` behaviour: every class now accepts any type of number, provided that it can be safely converted to the current type
|
||||
- New method: `BigDecimal::exactlyDividedBy()`; this method automatically computes the scale of the result, provided that the division yields a finite number of digits
|
||||
- New methods: `BigRational::quotient()` and `remainder()`
|
||||
- Fine-grained exceptions: `DivisionByZeroException`, `RoundingNecessaryException`, `NumberFormatException`
|
||||
- Factory methods `zero()`, `one()` and `ten()` available in all classes
|
||||
- Rounding mode reintroduced in `BigInteger::dividedBy()`
|
||||
|
||||
This release also comes with many performance improvements.
|
||||
|
||||
---
|
||||
|
||||
**Breaking changes**
|
||||
- `BigInteger`:
|
||||
- `getSign()` is renamed to `sign()`
|
||||
- `toString()` is renamed to `toBase()`
|
||||
- `BigInteger::dividedBy()` now throws an exception by default if the remainder is not zero; use `quotient()` to get the previous behaviour
|
||||
- `BigDecimal`:
|
||||
- `getSign()` is renamed to `sign()`
|
||||
- `getUnscaledValue()` is renamed to `unscaledValue()`
|
||||
- `getScale()` is renamed to `scale()`
|
||||
- `getIntegral()` is renamed to `integral()`
|
||||
- `getFraction()` is renamed to `fraction()`
|
||||
- `divideAndRemainder()` is renamed to `quotientAndRemainder()`
|
||||
- `dividedBy()` now takes a **mandatory** `$scale` parameter **before** the rounding mode
|
||||
- `toBigInteger()` does not accept a `$roundingMode` parameter any more
|
||||
- `toBigRational()` does not simplify the fraction any more; explicitly add `->simplified()` to get the previous behaviour
|
||||
- `BigRational`:
|
||||
- `getSign()` is renamed to `sign()`
|
||||
- `getNumerator()` is renamed to `numerator()`
|
||||
- `getDenominator()` is renamed to `denominator()`
|
||||
- `of()` is renamed to `nd()`, while `parse()` is renamed to `of()`
|
||||
- Miscellaneous:
|
||||
- `ArithmeticException` is moved to an `Exception\` sub-namespace
|
||||
- `of()` factory methods now throw `NumberFormatException` instead of `InvalidArgumentException`
|
||||
|
||||
## [0.4.3](https://github.com/brick/math/releases/tag/0.4.3) - 2016-03-31
|
||||
|
||||
Backport of two bug fixes from the 0.5 branch:
|
||||
- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected
|
||||
- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
||||
|
||||
## [0.4.2](https://github.com/brick/math/releases/tag/0.4.2) - 2015-06-16
|
||||
|
||||
New method: `BigDecimal::stripTrailingZeros()`
|
||||
|
||||
## [0.4.1](https://github.com/brick/math/releases/tag/0.4.1) - 2015-06-12
|
||||
|
||||
Introducing a `BigRational` class, to perform calculations on fractions of any size.
|
||||
|
||||
## [0.4.0](https://github.com/brick/math/releases/tag/0.4.0) - 2015-06-12
|
||||
|
||||
Rounding modes have been removed from `BigInteger`, and are now a concept specific to `BigDecimal`.
|
||||
|
||||
`BigInteger::dividedBy()` now always returns the quotient of the division.
|
||||
|
||||
## [0.3.5](https://github.com/brick/math/releases/tag/0.3.5) - 2016-03-31
|
||||
|
||||
Backport of two bug fixes from the 0.5 branch:
|
||||
|
||||
- `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected
|
||||
- Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6.
|
||||
|
||||
## [0.3.4](https://github.com/brick/math/releases/tag/0.3.4) - 2015-06-11
|
||||
|
||||
New methods:
|
||||
- `BigInteger::remainder()` returns the remainder of a division only
|
||||
- `BigInteger::gcd()` returns the greatest common divisor of two numbers
|
||||
|
||||
## [0.3.3](https://github.com/brick/math/releases/tag/0.3.3) - 2015-06-07
|
||||
|
||||
Fix `toString()` not handling negative numbers.
|
||||
|
||||
## [0.3.2](https://github.com/brick/math/releases/tag/0.3.2) - 2015-06-07
|
||||
|
||||
`BigInteger` and `BigDecimal` now have a `getSign()` method that returns:
|
||||
- `-1` if the number is negative
|
||||
- `0` if the number is zero
|
||||
- `1` if the number is positive
|
||||
|
||||
## [0.3.1](https://github.com/brick/math/releases/tag/0.3.1) - 2015-06-05
|
||||
|
||||
Minor performance improvements
|
||||
|
||||
## [0.3.0](https://github.com/brick/math/releases/tag/0.3.0) - 2015-06-04
|
||||
|
||||
The `$roundingMode` and `$scale` parameters have been swapped in `BigDecimal::dividedBy()`.
|
||||
|
||||
## [0.2.2](https://github.com/brick/math/releases/tag/0.2.2) - 2015-06-04
|
||||
|
||||
Stronger immutability guarantee for `BigInteger` and `BigDecimal`.
|
||||
|
||||
So far, it would have been possible to break immutability of these classes by calling the `unserialize()` internal function. This release fixes that.
|
||||
|
||||
## [0.2.1](https://github.com/brick/math/releases/tag/0.2.1) - 2015-06-02
|
||||
|
||||
Added `BigDecimal::divideAndRemainder()`
|
||||
|
||||
## [0.2.0](https://github.com/brick/math/releases/tag/0.2.0) - 2015-05-22
|
||||
|
||||
- `min()` and `max()` do not accept an `array` any more, but a variable number of parameters
|
||||
- **minimum PHP version is now 5.6**
|
||||
- continuous integration with PHP 7
|
||||
|
||||
## [0.1.1](https://github.com/brick/math/releases/tag/0.1.1) - 2014-09-01
|
||||
|
||||
- Added `BigInteger::power()`
|
||||
- Added HHVM support
|
||||
|
||||
## [0.1.0](https://github.com/brick/math/releases/tag/0.1.0) - 2014-08-31
|
||||
|
||||
First beta release.
|
||||
|
20
vendor/brick/math/LICENSE
vendored
Normal file
20
vendor/brick/math/LICENSE
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-present Benjamin Morel
|
||||
|
||||
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.
|
17
vendor/brick/math/SECURITY.md
vendored
Normal file
17
vendor/brick/math/SECURITY.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Only the last two release streams are supported.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.9.x | :white_check_mark: |
|
||||
| 0.8.x | :white_check_mark: |
|
||||
| < 0.8 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a security vulnerability, please use the
|
||||
[Tidelift security contact](https://tidelift.com/security).
|
||||
Tidelift will coordinate the fix and disclosure.
|
35
vendor/brick/math/composer.json
vendored
Normal file
35
vendor/brick/math/composer.json
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "brick/math",
|
||||
"description": "Arbitrary-precision arithmetic library",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"Brick",
|
||||
"Math",
|
||||
"Arbitrary-precision",
|
||||
"Arithmetic",
|
||||
"BigInteger",
|
||||
"BigDecimal",
|
||||
"BigRational",
|
||||
"Bignum"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0",
|
||||
"php-coveralls/php-coveralls": "^2.2",
|
||||
"vimeo/psalm": "4.9.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Brick\\Math\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Brick\\Math\\Tests\\": "tests/"
|
||||
}
|
||||
}
|
||||
}
|
895
vendor/brick/math/src/BigDecimal.php
vendored
Normal file
895
vendor/brick/math/src/BigDecimal.php
vendored
Normal file
@@ -0,0 +1,895 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NegativeNumberException;
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
/**
|
||||
* Immutable, arbitrary-precision signed decimal numbers.
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class BigDecimal extends BigNumber
|
||||
{
|
||||
/**
|
||||
* The unscaled value of this decimal number.
|
||||
*
|
||||
* This is a string of digits with an optional leading minus sign.
|
||||
* No leading zero must be present.
|
||||
* No leading minus sign must be present if the value is 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* The scale (number of digits after the decimal point) of this decimal number.
|
||||
*
|
||||
* This must be zero or more.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $scale;
|
||||
|
||||
/**
|
||||
* Protected constructor. Use a factory method to obtain an instance.
|
||||
*
|
||||
* @param string $value The unscaled value, validated.
|
||||
* @param int $scale The scale, validated.
|
||||
*/
|
||||
protected function __construct(string $value, int $scale = 0)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->scale = $scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigDecimal of the given value.
|
||||
*
|
||||
* @param BigNumber|int|float|string $value
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws MathException If the value cannot be converted to a BigDecimal.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function of($value) : BigNumber
|
||||
{
|
||||
return parent::of($value)->toBigDecimal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigDecimal from an unscaled value and a scale.
|
||||
*
|
||||
* Example: `(12345, 3)` will result in the BigDecimal `12.345`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $value The unscaled value. Must be convertible to a BigInteger.
|
||||
* @param int $scale The scale of the number, positive or zero.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws \InvalidArgumentException If the scale is negative.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function ofUnscaledValue($value, int $scale = 0) : BigDecimal
|
||||
{
|
||||
if ($scale < 0) {
|
||||
throw new \InvalidArgumentException('The scale cannot be negative.');
|
||||
}
|
||||
|
||||
return new BigDecimal((string) BigInteger::of($value), $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing zero, with a scale of zero.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function zero() : BigDecimal
|
||||
{
|
||||
/**
|
||||
* @psalm-suppress ImpureStaticVariable
|
||||
* @var BigDecimal|null $zero
|
||||
*/
|
||||
static $zero;
|
||||
|
||||
if ($zero === null) {
|
||||
$zero = new BigDecimal('0');
|
||||
}
|
||||
|
||||
return $zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing one, with a scale of zero.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function one() : BigDecimal
|
||||
{
|
||||
/**
|
||||
* @psalm-suppress ImpureStaticVariable
|
||||
* @var BigDecimal|null $one
|
||||
*/
|
||||
static $one;
|
||||
|
||||
if ($one === null) {
|
||||
$one = new BigDecimal('1');
|
||||
}
|
||||
|
||||
return $one;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing ten, with a scale of zero.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function ten() : BigDecimal
|
||||
{
|
||||
/**
|
||||
* @psalm-suppress ImpureStaticVariable
|
||||
* @var BigDecimal|null $ten
|
||||
*/
|
||||
static $ten;
|
||||
|
||||
if ($ten === null) {
|
||||
$ten = new BigDecimal('10');
|
||||
}
|
||||
|
||||
return $ten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws MathException If the number is not valid, or is not convertible to a BigDecimal.
|
||||
*/
|
||||
public function plus($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0' && $that->scale <= $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->value === '0' && $this->scale <= $that->scale) {
|
||||
return $that;
|
||||
}
|
||||
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$value = Calculator::get()->add($a, $b);
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws MathException If the number is not valid, or is not convertible to a BigDecimal.
|
||||
*/
|
||||
public function minus($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0' && $that->scale <= $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$value = Calculator::get()->sub($a, $b);
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `$this->scale + $that->scale`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws MathException If the multiplier is not a valid number, or is not convertible to a BigDecimal.
|
||||
*/
|
||||
public function multipliedBy($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '1' && $that->scale === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->value === '1' && $this->scale === 0) {
|
||||
return $that;
|
||||
}
|
||||
|
||||
$value = Calculator::get()->mul($this->value, $that->value);
|
||||
$scale = $this->scale + $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of the division of this number by the given one, at the given scale.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor.
|
||||
* @param int|null $scale The desired scale, or null to use the scale of this number.
|
||||
* @param int $roundingMode An optional rounding mode.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws \InvalidArgumentException If the scale or rounding mode is invalid.
|
||||
* @throws MathException If the number is invalid, is zero, or rounding was necessary.
|
||||
*/
|
||||
public function dividedBy($that, ?int $scale = null, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
if ($scale === null) {
|
||||
$scale = $this->scale;
|
||||
} elseif ($scale < 0) {
|
||||
throw new \InvalidArgumentException('Scale cannot be negative.');
|
||||
}
|
||||
|
||||
if ($that->value === '1' && $that->scale === 0 && $scale === $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale + $scale);
|
||||
$q = $that->valueWithMinScale($this->scale - $scale);
|
||||
|
||||
$result = Calculator::get()->divRound($p, $q, $roundingMode);
|
||||
|
||||
return new BigDecimal($result, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exact result of the division of this number by the given one.
|
||||
*
|
||||
* The scale of the result is automatically calculated to fit all the fraction digits.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid number, is not convertible to a BigDecimal, is zero,
|
||||
* or the result yields an infinite number of digits.
|
||||
*/
|
||||
public function exactlyDividedBy($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0') {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
[, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$d = \rtrim($b, '0');
|
||||
$scale = \strlen($b) - \strlen($d);
|
||||
|
||||
$calculator = Calculator::get();
|
||||
|
||||
foreach ([5, 2] as $prime) {
|
||||
for (;;) {
|
||||
$lastDigit = (int) $d[-1];
|
||||
|
||||
if ($lastDigit % $prime !== 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
$d = $calculator->divQ($d, (string) $prime);
|
||||
$scale++;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->dividedBy($that, $scale)->stripTrailingZeros();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this number exponentiated to the given value.
|
||||
*
|
||||
* The result has a scale of `$this->scale * $exponent`.
|
||||
*
|
||||
* @param int $exponent The exponent.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
|
||||
*/
|
||||
public function power(int $exponent) : BigDecimal
|
||||
{
|
||||
if ($exponent === 0) {
|
||||
return BigDecimal::one();
|
||||
}
|
||||
|
||||
if ($exponent === 1) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($exponent < 0 || $exponent > Calculator::MAX_POWER) {
|
||||
throw new \InvalidArgumentException(\sprintf(
|
||||
'The exponent %d is not in the range 0 to %d.',
|
||||
$exponent,
|
||||
Calculator::MAX_POWER
|
||||
));
|
||||
}
|
||||
|
||||
return new BigDecimal(Calculator::get()->pow($this->value, $exponent), $this->scale * $exponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of this number by this given one.
|
||||
*
|
||||
* The quotient has a scale of `0`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The quotient.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*/
|
||||
public function quotient($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
$quotient = Calculator::get()->divQ($p, $q);
|
||||
|
||||
return new BigDecimal($quotient, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of this number by this given one.
|
||||
*
|
||||
* The remainder has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The remainder.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*/
|
||||
public function remainder($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
$remainder = Calculator::get()->divR($p, $q);
|
||||
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($remainder, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of this number by the given one.
|
||||
*
|
||||
* The quotient has a scale of `0`, and the remainder has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal[] An array containing the quotient and the remainder.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*/
|
||||
public function quotientAndRemainder($that) : array
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
[$quotient, $remainder] = Calculator::get()->divQR($p, $q);
|
||||
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
$quotient = new BigDecimal($quotient, 0);
|
||||
$remainder = new BigDecimal($remainder, $scale);
|
||||
|
||||
return [$quotient, $remainder];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square root of this number, rounded down to the given number of decimals.
|
||||
*
|
||||
* @param int $scale
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws \InvalidArgumentException If the scale is negative.
|
||||
* @throws NegativeNumberException If this number is negative.
|
||||
*/
|
||||
public function sqrt(int $scale) : BigDecimal
|
||||
{
|
||||
if ($scale < 0) {
|
||||
throw new \InvalidArgumentException('Scale cannot be negative.');
|
||||
}
|
||||
|
||||
if ($this->value === '0') {
|
||||
return new BigDecimal('0', $scale);
|
||||
}
|
||||
|
||||
if ($this->value[0] === '-') {
|
||||
throw new NegativeNumberException('Cannot calculate the square root of a negative number.');
|
||||
}
|
||||
|
||||
$value = $this->value;
|
||||
$addDigits = 2 * $scale - $this->scale;
|
||||
|
||||
if ($addDigits > 0) {
|
||||
// add zeros
|
||||
$value .= \str_repeat('0', $addDigits);
|
||||
} elseif ($addDigits < 0) {
|
||||
// trim digits
|
||||
if (-$addDigits >= \strlen($this->value)) {
|
||||
// requesting a scale too low, will always yield a zero result
|
||||
return new BigDecimal('0', $scale);
|
||||
}
|
||||
|
||||
$value = \substr($value, 0, $addDigits);
|
||||
}
|
||||
|
||||
$value = Calculator::get()->sqrt($value);
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with the decimal point moved $n places to the left.
|
||||
*
|
||||
* @param int $n
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function withPointMovedLeft(int $n) : BigDecimal
|
||||
{
|
||||
if ($n === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($n < 0) {
|
||||
return $this->withPointMovedRight(-$n);
|
||||
}
|
||||
|
||||
return new BigDecimal($this->value, $this->scale + $n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with the decimal point moved $n places to the right.
|
||||
*
|
||||
* @param int $n
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function withPointMovedRight(int $n) : BigDecimal
|
||||
{
|
||||
if ($n === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($n < 0) {
|
||||
return $this->withPointMovedLeft(-$n);
|
||||
}
|
||||
|
||||
$value = $this->value;
|
||||
$scale = $this->scale - $n;
|
||||
|
||||
if ($scale < 0) {
|
||||
if ($value !== '0') {
|
||||
$value .= \str_repeat('0', -$scale);
|
||||
}
|
||||
$scale = 0;
|
||||
}
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with any trailing zeros removed from the fractional part.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function stripTrailingZeros() : BigDecimal
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$trimmedValue = \rtrim($this->value, '0');
|
||||
|
||||
if ($trimmedValue === '') {
|
||||
return BigDecimal::zero();
|
||||
}
|
||||
|
||||
$trimmableZeros = \strlen($this->value) - \strlen($trimmedValue);
|
||||
|
||||
if ($trimmableZeros === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($trimmableZeros > $this->scale) {
|
||||
$trimmableZeros = $this->scale;
|
||||
}
|
||||
|
||||
$value = \substr($this->value, 0, -$trimmableZeros);
|
||||
$scale = $this->scale - $trimmableZeros;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this number.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function abs() : BigDecimal
|
||||
{
|
||||
return $this->isNegative() ? $this->negated() : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the negated value of this number.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function negated() : BigDecimal
|
||||
{
|
||||
return new BigDecimal(Calculator::get()->neg($this->value), $this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compareTo($that) : int
|
||||
{
|
||||
$that = BigNumber::of($that);
|
||||
|
||||
if ($that instanceof BigInteger) {
|
||||
$that = $that->toBigDecimal();
|
||||
}
|
||||
|
||||
if ($that instanceof BigDecimal) {
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
return Calculator::get()->cmp($a, $b);
|
||||
}
|
||||
|
||||
return - $that->compareTo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSign() : int
|
||||
{
|
||||
return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function getUnscaledValue() : BigInteger
|
||||
{
|
||||
return BigInteger::create($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getScale() : int
|
||||
{
|
||||
return $this->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing the integral part of this decimal number.
|
||||
*
|
||||
* Example: `-123.456` => `-123`.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIntegralPart() : string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
return \substr($value, 0, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing the fractional part of this decimal number.
|
||||
*
|
||||
* If the scale is zero, an empty string is returned.
|
||||
*
|
||||
* Examples: `-123.456` => '456', `123` => ''.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFractionalPart() : string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
return \substr($value, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this decimal number has a non-zero fractional part.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNonZeroFractionalPart() : bool
|
||||
{
|
||||
return $this->getFractionalPart() !== \str_repeat('0', $this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigInteger() : BigInteger
|
||||
{
|
||||
$zeroScaleDecimal = $this->scale === 0 ? $this : $this->dividedBy(1, 0);
|
||||
|
||||
return BigInteger::create($zeroScaleDecimal->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigDecimal() : BigDecimal
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigRational() : BigRational
|
||||
{
|
||||
$numerator = BigInteger::create($this->value);
|
||||
$denominator = BigInteger::create('1' . \str_repeat('0', $this->scale));
|
||||
|
||||
return BigRational::create($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
||||
{
|
||||
if ($scale === $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toInt() : int
|
||||
{
|
||||
return $this->toBigInteger()->toInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toFloat() : float
|
||||
{
|
||||
return (float) (string) $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString() : string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
return \substr($value, 0, -$this->scale) . '.' . \substr($value, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required for serializing the object and SHOULD NOT be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return array{value: string, scale: int}
|
||||
*/
|
||||
public function __serialize(): array
|
||||
{
|
||||
return ['value' => $this->value, 'scale' => $this->scale];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only here to allow unserializing the object and cannot be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
* @psalm-suppress RedundantPropertyInitializationCheck
|
||||
*
|
||||
* @param array{value: string, scale: int} $data
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
if (isset($this->value)) {
|
||||
throw new \LogicException('__unserialize() is an internal function, it must not be called directly.');
|
||||
}
|
||||
|
||||
$this->value = $data['value'];
|
||||
$this->scale = $data['scale'];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by interface Serializable and SHOULD NOT be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize() : string
|
||||
{
|
||||
return $this->value . ':' . $this->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only here to implement interface Serializable and cannot be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
* @psalm-suppress RedundantPropertyInitializationCheck
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function unserialize($value) : void
|
||||
{
|
||||
if (isset($this->value)) {
|
||||
throw new \LogicException('unserialize() is an internal function, it must not be called directly.');
|
||||
}
|
||||
|
||||
[$value, $scale] = \explode(':', $value);
|
||||
|
||||
$this->value = $value;
|
||||
$this->scale = (int) $scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the internal values of the given decimal numbers on the same scale.
|
||||
*
|
||||
* @param BigDecimal $x The first decimal number.
|
||||
* @param BigDecimal $y The second decimal number.
|
||||
*
|
||||
* @return array{string, string} The scaled integer values of $x and $y.
|
||||
*/
|
||||
private function scaleValues(BigDecimal $x, BigDecimal $y) : array
|
||||
{
|
||||
$a = $x->value;
|
||||
$b = $y->value;
|
||||
|
||||
if ($b !== '0' && $x->scale > $y->scale) {
|
||||
$b .= \str_repeat('0', $x->scale - $y->scale);
|
||||
} elseif ($a !== '0' && $x->scale < $y->scale) {
|
||||
$a .= \str_repeat('0', $y->scale - $x->scale);
|
||||
}
|
||||
|
||||
return [$a, $b];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $scale
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function valueWithMinScale(int $scale) : string
|
||||
{
|
||||
$value = $this->value;
|
||||
|
||||
if ($this->value !== '0' && $scale > $this->scale) {
|
||||
$value .= \str_repeat('0', $scale - $this->scale);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds leading zeros if necessary to the unscaled value to represent the full decimal number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getUnscaledValueWithLeadingZeros() : string
|
||||
{
|
||||
$value = $this->value;
|
||||
$targetLength = $this->scale + 1;
|
||||
$negative = ($value[0] === '-');
|
||||
$length = \strlen($value);
|
||||
|
||||
if ($negative) {
|
||||
$length--;
|
||||
}
|
||||
|
||||
if ($length >= $targetLength) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
if ($negative) {
|
||||
$value = \substr($value, 1);
|
||||
}
|
||||
|
||||
$value = \str_pad($value, $targetLength, '0', STR_PAD_LEFT);
|
||||
|
||||
if ($negative) {
|
||||
$value = '-' . $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
1184
vendor/brick/math/src/BigInteger.php
vendored
Normal file
1184
vendor/brick/math/src/BigInteger.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
572
vendor/brick/math/src/BigNumber.php
vendored
Normal file
572
vendor/brick/math/src/BigNumber.php
vendored
Normal file
@@ -0,0 +1,572 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NumberFormatException;
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
|
||||
/**
|
||||
* Common interface for arbitrary-precision rational numbers.
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
abstract class BigNumber implements \Serializable, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* The regular expression used to parse integer, decimal and rational numbers.
|
||||
*/
|
||||
private const PARSE_REGEXP =
|
||||
'/^' .
|
||||
'(?<sign>[\-\+])?' .
|
||||
'(?:' .
|
||||
'(?:' .
|
||||
'(?<integral>[0-9]+)?' .
|
||||
'(?<point>\.)?' .
|
||||
'(?<fractional>[0-9]+)?' .
|
||||
'(?:[eE](?<exponent>[\-\+]?[0-9]+))?' .
|
||||
')|(?:' .
|
||||
'(?<numerator>[0-9]+)' .
|
||||
'\/?' .
|
||||
'(?<denominator>[0-9]+)' .
|
||||
')' .
|
||||
')' .
|
||||
'$/';
|
||||
|
||||
/**
|
||||
* Creates a BigNumber of the given value.
|
||||
*
|
||||
* The concrete return type is dependent on the given value, with the following rules:
|
||||
*
|
||||
* - BigNumber instances are returned as is
|
||||
* - integer numbers are returned as BigInteger
|
||||
* - floating point numbers are converted to a string then parsed as such
|
||||
* - strings containing a `/` character are returned as BigRational
|
||||
* - strings containing a `.` character or using an exponential notation are returned as BigDecimal
|
||||
* - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger
|
||||
*
|
||||
* @param BigNumber|int|float|string $value
|
||||
*
|
||||
* @return BigNumber
|
||||
*
|
||||
* @throws NumberFormatException If the format of the number is not valid.
|
||||
* @throws DivisionByZeroException If the value represents a rational number with a denominator of zero.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function of($value) : BigNumber
|
||||
{
|
||||
if ($value instanceof BigNumber) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (\is_int($value)) {
|
||||
return new BigInteger((string) $value);
|
||||
}
|
||||
|
||||
/** @psalm-suppress RedundantCastGivenDocblockType We cannot trust the untyped $value here! */
|
||||
$value = \is_float($value) ? self::floatToString($value) : (string) $value;
|
||||
|
||||
$throw = static function() use ($value) : void {
|
||||
throw new NumberFormatException(\sprintf(
|
||||
'The given value "%s" does not represent a valid number.',
|
||||
$value
|
||||
));
|
||||
};
|
||||
|
||||
if (\preg_match(self::PARSE_REGEXP, $value, $matches) !== 1) {
|
||||
$throw();
|
||||
}
|
||||
|
||||
$getMatch = static function(string $value) use ($matches) : ?string {
|
||||
return isset($matches[$value]) && $matches[$value] !== '' ? $matches[$value] : null;
|
||||
};
|
||||
|
||||
$sign = $getMatch('sign');
|
||||
$numerator = $getMatch('numerator');
|
||||
$denominator = $getMatch('denominator');
|
||||
|
||||
if ($numerator !== null) {
|
||||
assert($denominator !== null);
|
||||
|
||||
if ($sign !== null) {
|
||||
$numerator = $sign . $numerator;
|
||||
}
|
||||
|
||||
$numerator = self::cleanUp($numerator);
|
||||
$denominator = self::cleanUp($denominator);
|
||||
|
||||
if ($denominator === '0') {
|
||||
throw DivisionByZeroException::denominatorMustNotBeZero();
|
||||
}
|
||||
|
||||
return new BigRational(
|
||||
new BigInteger($numerator),
|
||||
new BigInteger($denominator),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
$point = $getMatch('point');
|
||||
$integral = $getMatch('integral');
|
||||
$fractional = $getMatch('fractional');
|
||||
$exponent = $getMatch('exponent');
|
||||
|
||||
if ($integral === null && $fractional === null) {
|
||||
$throw();
|
||||
}
|
||||
|
||||
if ($integral === null) {
|
||||
$integral = '0';
|
||||
}
|
||||
|
||||
if ($point !== null || $exponent !== null) {
|
||||
$fractional = ($fractional ?? '');
|
||||
$exponent = ($exponent !== null) ? (int) $exponent : 0;
|
||||
|
||||
if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) {
|
||||
throw new NumberFormatException('Exponent too large.');
|
||||
}
|
||||
|
||||
$unscaledValue = self::cleanUp(($sign ?? ''). $integral . $fractional);
|
||||
|
||||
$scale = \strlen($fractional) - $exponent;
|
||||
|
||||
if ($scale < 0) {
|
||||
if ($unscaledValue !== '0') {
|
||||
$unscaledValue .= \str_repeat('0', - $scale);
|
||||
}
|
||||
$scale = 0;
|
||||
}
|
||||
|
||||
return new BigDecimal($unscaledValue, $scale);
|
||||
}
|
||||
|
||||
$integral = self::cleanUp(($sign ?? '') . $integral);
|
||||
|
||||
return new BigInteger($integral);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely converts float to string, avoiding locale-dependent issues.
|
||||
*
|
||||
* @see https://github.com/brick/math/pull/20
|
||||
*
|
||||
* @param float $float
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @psalm-pure
|
||||
* @psalm-suppress ImpureFunctionCall
|
||||
*/
|
||||
private static function floatToString(float $float) : string
|
||||
{
|
||||
$currentLocale = \setlocale(LC_NUMERIC, '0');
|
||||
\setlocale(LC_NUMERIC, 'C');
|
||||
|
||||
$result = (string) $float;
|
||||
|
||||
\setlocale(LC_NUMERIC, $currentLocale);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy method to access protected constructors from sibling classes.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param mixed ...$args The arguments to the constructor.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @psalm-pure
|
||||
* @psalm-suppress TooManyArguments
|
||||
* @psalm-suppress UnsafeInstantiation
|
||||
*/
|
||||
protected static function create(... $args) : BigNumber
|
||||
{
|
||||
return new static(... $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum of the given values.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible
|
||||
* to an instance of the class this method is called on.
|
||||
*
|
||||
* @return static The minimum value.
|
||||
*
|
||||
* @throws \InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @psalm-suppress LessSpecificReturnStatement
|
||||
* @psalm-suppress MoreSpecificReturnType
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function min(...$values) : BigNumber
|
||||
{
|
||||
$min = null;
|
||||
|
||||
foreach ($values as $value) {
|
||||
$value = static::of($value);
|
||||
|
||||
if ($min === null || $value->isLessThan($min)) {
|
||||
$min = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($min === null) {
|
||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
return $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum of the given values.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible
|
||||
* to an instance of the class this method is called on.
|
||||
*
|
||||
* @return static The maximum value.
|
||||
*
|
||||
* @throws \InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @psalm-suppress LessSpecificReturnStatement
|
||||
* @psalm-suppress MoreSpecificReturnType
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function max(...$values) : BigNumber
|
||||
{
|
||||
$max = null;
|
||||
|
||||
foreach ($values as $value) {
|
||||
$value = static::of($value);
|
||||
|
||||
if ($max === null || $value->isGreaterThan($max)) {
|
||||
$max = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($max === null) {
|
||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
return $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of the given values.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The numbers to add. All the numbers need to be convertible
|
||||
* to an instance of the class this method is called on.
|
||||
*
|
||||
* @return static The sum.
|
||||
*
|
||||
* @throws \InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @psalm-suppress LessSpecificReturnStatement
|
||||
* @psalm-suppress MoreSpecificReturnType
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function sum(...$values) : BigNumber
|
||||
{
|
||||
/** @var BigNumber|null $sum */
|
||||
$sum = null;
|
||||
|
||||
foreach ($values as $value) {
|
||||
$value = static::of($value);
|
||||
|
||||
$sum = $sum === null ? $value : self::add($sum, $value);
|
||||
}
|
||||
|
||||
if ($sum === null) {
|
||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two BigNumber instances in the correct order to avoid a RoundingNecessaryException.
|
||||
*
|
||||
* @todo This could be better resolved by creating an abstract protected method in BigNumber, and leaving to
|
||||
* concrete classes the responsibility to perform the addition themselves or delegate it to the given number,
|
||||
* depending on their ability to perform the operation. This will also require a version bump because we're
|
||||
* potentially breaking custom BigNumber implementations (if any...)
|
||||
*
|
||||
* @param BigNumber $a
|
||||
* @param BigNumber $b
|
||||
*
|
||||
* @return BigNumber
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
private static function add(BigNumber $a, BigNumber $b) : BigNumber
|
||||
{
|
||||
if ($a instanceof BigRational) {
|
||||
return $a->plus($b);
|
||||
}
|
||||
|
||||
if ($b instanceof BigRational) {
|
||||
return $b->plus($a);
|
||||
}
|
||||
|
||||
if ($a instanceof BigDecimal) {
|
||||
return $a->plus($b);
|
||||
}
|
||||
|
||||
if ($b instanceof BigDecimal) {
|
||||
return $b->plus($a);
|
||||
}
|
||||
|
||||
/** @var BigInteger $a */
|
||||
|
||||
return $a->plus($b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes optional leading zeros and + sign from the given number.
|
||||
*
|
||||
* @param string $number The number, validated as a non-empty string of digits with optional leading sign.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
private static function cleanUp(string $number) : string
|
||||
{
|
||||
$firstChar = $number[0];
|
||||
|
||||
if ($firstChar === '+' || $firstChar === '-') {
|
||||
$number = \substr($number, 1);
|
||||
}
|
||||
|
||||
$number = \ltrim($number, '0');
|
||||
|
||||
if ($number === '') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if ($firstChar === '-') {
|
||||
return '-' . $number;
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is equal to the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEqualTo($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly lower than the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLessThan($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is lower than or equal to the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLessThanOrEqualTo($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly greater than the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreaterThan($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is greater than or equal to the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreaterThanOrEqualTo($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number equals zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isZero() : bool
|
||||
{
|
||||
return $this->getSign() === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly negative.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNegative() : bool
|
||||
{
|
||||
return $this->getSign() < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is negative or zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNegativeOrZero() : bool
|
||||
{
|
||||
return $this->getSign() <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly positive.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPositive() : bool
|
||||
{
|
||||
return $this->getSign() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is positive or zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPositiveOrZero() : bool
|
||||
{
|
||||
return $this->getSign() >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sign of this number.
|
||||
*
|
||||
* @return int -1 if the number is negative, 0 if zero, 1 if positive.
|
||||
*/
|
||||
abstract public function getSign() : int;
|
||||
|
||||
/**
|
||||
* Compares this number to the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return int [-1,0,1] If `$this` is lower than, equal to, or greater than `$that`.
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*/
|
||||
abstract public function compareTo($that) : int;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigInteger.
|
||||
*
|
||||
* @return BigInteger The converted number.
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding.
|
||||
*/
|
||||
abstract public function toBigInteger() : BigInteger;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The converted number.
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding.
|
||||
*/
|
||||
abstract public function toBigDecimal() : BigDecimal;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigRational.
|
||||
*
|
||||
* @return BigRational The converted number.
|
||||
*/
|
||||
abstract public function toBigRational() : BigRational;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigDecimal with the given scale, using rounding if necessary.
|
||||
*
|
||||
* @param int $scale The scale of the resulting `BigDecimal`.
|
||||
* @param int $roundingMode A `RoundingMode` constant.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding.
|
||||
* This only applies when RoundingMode::UNNECESSARY is used.
|
||||
*/
|
||||
abstract public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal;
|
||||
|
||||
/**
|
||||
* Returns the exact value of this number as a native integer.
|
||||
*
|
||||
* If this number cannot be converted to a native integer without losing precision, an exception is thrown.
|
||||
* Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit.
|
||||
*
|
||||
* @return int The converted value.
|
||||
*
|
||||
* @throws MathException If this number cannot be exactly converted to a native integer.
|
||||
*/
|
||||
abstract public function toInt() : int;
|
||||
|
||||
/**
|
||||
* Returns an approximation of this number as a floating-point value.
|
||||
*
|
||||
* Note that this method can discard information as the precision of a floating-point value
|
||||
* is inherently limited.
|
||||
*
|
||||
* If the number is greater than the largest representable floating point number, positive infinity is returned.
|
||||
* If the number is less than the smallest representable floating point number, negative infinity is returned.
|
||||
*
|
||||
* @return float The converted value.
|
||||
*/
|
||||
abstract public function toFloat() : float;
|
||||
|
||||
/**
|
||||
* Returns a string representation of this number.
|
||||
*
|
||||
* The output of this method can be parsed by the `of()` factory method;
|
||||
* this will yield an object equal to this one, without any information loss.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function __toString() : string;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function jsonSerialize() : string
|
||||
{
|
||||
return $this->__toString();
|
||||
}
|
||||
}
|
523
vendor/brick/math/src/BigRational.php
vendored
Normal file
523
vendor/brick/math/src/BigRational.php
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NumberFormatException;
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
|
||||
/**
|
||||
* An arbitrarily large rational number.
|
||||
*
|
||||
* This class is immutable.
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class BigRational extends BigNumber
|
||||
{
|
||||
/**
|
||||
* The numerator.
|
||||
*
|
||||
* @var BigInteger
|
||||
*/
|
||||
private $numerator;
|
||||
|
||||
/**
|
||||
* The denominator. Always strictly positive.
|
||||
*
|
||||
* @var BigInteger
|
||||
*/
|
||||
private $denominator;
|
||||
|
||||
/**
|
||||
* Protected constructor. Use a factory method to obtain an instance.
|
||||
*
|
||||
* @param BigInteger $numerator The numerator.
|
||||
* @param BigInteger $denominator The denominator.
|
||||
* @param bool $checkDenominator Whether to check the denominator for negative and zero.
|
||||
*
|
||||
* @throws DivisionByZeroException If the denominator is zero.
|
||||
*/
|
||||
protected function __construct(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator)
|
||||
{
|
||||
if ($checkDenominator) {
|
||||
if ($denominator->isZero()) {
|
||||
throw DivisionByZeroException::denominatorMustNotBeZero();
|
||||
}
|
||||
|
||||
if ($denominator->isNegative()) {
|
||||
$numerator = $numerator->negated();
|
||||
$denominator = $denominator->negated();
|
||||
}
|
||||
}
|
||||
|
||||
$this->numerator = $numerator;
|
||||
$this->denominator = $denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigRational of the given value.
|
||||
*
|
||||
* @param BigNumber|int|float|string $value
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws MathException If the value cannot be converted to a BigRational.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function of($value) : BigNumber
|
||||
{
|
||||
return parent::of($value)->toBigRational();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigRational out of a numerator and a denominator.
|
||||
*
|
||||
* If the denominator is negative, the signs of both the numerator and the denominator
|
||||
* will be inverted to ensure that the denominator is always positive.
|
||||
*
|
||||
* @param BigNumber|int|float|string $numerator The numerator. Must be convertible to a BigInteger.
|
||||
* @param BigNumber|int|float|string $denominator The denominator. Must be convertible to a BigInteger.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws NumberFormatException If an argument does not represent a valid number.
|
||||
* @throws RoundingNecessaryException If an argument represents a non-integer number.
|
||||
* @throws DivisionByZeroException If the denominator is zero.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function nd($numerator, $denominator) : BigRational
|
||||
{
|
||||
$numerator = BigInteger::of($numerator);
|
||||
$denominator = BigInteger::of($denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing zero.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function zero() : BigRational
|
||||
{
|
||||
/**
|
||||
* @psalm-suppress ImpureStaticVariable
|
||||
* @var BigRational|null $zero
|
||||
*/
|
||||
static $zero;
|
||||
|
||||
if ($zero === null) {
|
||||
$zero = new BigRational(BigInteger::zero(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing one.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function one() : BigRational
|
||||
{
|
||||
/**
|
||||
* @psalm-suppress ImpureStaticVariable
|
||||
* @var BigRational|null $one
|
||||
*/
|
||||
static $one;
|
||||
|
||||
if ($one === null) {
|
||||
$one = new BigRational(BigInteger::one(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $one;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing ten.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function ten() : BigRational
|
||||
{
|
||||
/**
|
||||
* @psalm-suppress ImpureStaticVariable
|
||||
* @var BigRational|null $ten
|
||||
*/
|
||||
static $ten;
|
||||
|
||||
if ($ten === null) {
|
||||
$ten = new BigRational(BigInteger::ten(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $ten;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function getNumerator() : BigInteger
|
||||
{
|
||||
return $this->numerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function getDenominator() : BigInteger
|
||||
{
|
||||
return $this->denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of the numerator by the denominator.
|
||||
*
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function quotient() : BigInteger
|
||||
{
|
||||
return $this->numerator->quotient($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of the numerator by the denominator.
|
||||
*
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function remainder() : BigInteger
|
||||
{
|
||||
return $this->numerator->remainder($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of the numerator by the denominator.
|
||||
*
|
||||
* @return BigInteger[]
|
||||
*/
|
||||
public function quotientAndRemainder() : array
|
||||
{
|
||||
return $this->numerator->quotientAndRemainder($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to add.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*/
|
||||
public function plus($that) : BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator));
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to subtract.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*/
|
||||
public function minus($that) : BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator));
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The multiplier.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws MathException If the multiplier is not a valid number.
|
||||
*/
|
||||
public function multipliedBy($that) : BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->numerator);
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of the division of this number by the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid number, or is zero.
|
||||
*/
|
||||
public function dividedBy($that) : BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$denominator = $this->denominator->multipliedBy($that->numerator);
|
||||
|
||||
return new BigRational($numerator, $denominator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this number exponentiated to the given value.
|
||||
*
|
||||
* @param int $exponent The exponent.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
|
||||
*/
|
||||
public function power(int $exponent) : BigRational
|
||||
{
|
||||
if ($exponent === 0) {
|
||||
$one = BigInteger::one();
|
||||
|
||||
return new BigRational($one, $one, false);
|
||||
}
|
||||
|
||||
if ($exponent === 1) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new BigRational(
|
||||
$this->numerator->power($exponent),
|
||||
$this->denominator->power($exponent),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reciprocal of this BigRational.
|
||||
*
|
||||
* The reciprocal has the numerator and denominator swapped.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws DivisionByZeroException If the numerator is zero.
|
||||
*/
|
||||
public function reciprocal() : BigRational
|
||||
{
|
||||
return new BigRational($this->denominator, $this->numerator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function abs() : BigRational
|
||||
{
|
||||
return new BigRational($this->numerator->abs(), $this->denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the negated value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function negated() : BigRational
|
||||
{
|
||||
return new BigRational($this->numerator->negated(), $this->denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the simplified value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function simplified() : BigRational
|
||||
{
|
||||
$gcd = $this->numerator->gcd($this->denominator);
|
||||
|
||||
$numerator = $this->numerator->quotient($gcd);
|
||||
$denominator = $this->denominator->quotient($gcd);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compareTo($that) : int
|
||||
{
|
||||
return $this->minus($that)->getSign();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSign() : int
|
||||
{
|
||||
return $this->numerator->getSign();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigInteger() : BigInteger
|
||||
{
|
||||
$simplified = $this->simplified();
|
||||
|
||||
if (! $simplified->denominator->isEqualTo(1)) {
|
||||
throw new RoundingNecessaryException('This rational number cannot be represented as an integer value without rounding.');
|
||||
}
|
||||
|
||||
return $simplified->numerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigDecimal() : BigDecimal
|
||||
{
|
||||
return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigRational() : BigRational
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
||||
{
|
||||
return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toInt() : int
|
||||
{
|
||||
return $this->toBigInteger()->toInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toFloat() : float
|
||||
{
|
||||
return $this->numerator->toFloat() / $this->denominator->toFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString() : string
|
||||
{
|
||||
$numerator = (string) $this->numerator;
|
||||
$denominator = (string) $this->denominator;
|
||||
|
||||
if ($denominator === '1') {
|
||||
return $numerator;
|
||||
}
|
||||
|
||||
return $this->numerator . '/' . $this->denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required for serializing the object and SHOULD NOT be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return array{numerator: BigInteger, denominator: BigInteger}
|
||||
*/
|
||||
public function __serialize(): array
|
||||
{
|
||||
return ['numerator' => $this->numerator, 'denominator' => $this->denominator];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only here to allow unserializing the object and cannot be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
* @psalm-suppress RedundantPropertyInitializationCheck
|
||||
*
|
||||
* @param array{numerator: BigInteger, denominator: BigInteger} $data
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
if (isset($this->numerator)) {
|
||||
throw new \LogicException('__unserialize() is an internal function, it must not be called directly.');
|
||||
}
|
||||
|
||||
$this->numerator = $data['numerator'];
|
||||
$this->denominator = $data['denominator'];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by interface Serializable and SHOULD NOT be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize() : string
|
||||
{
|
||||
return $this->numerator . '/' . $this->denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only here to implement interface Serializable and cannot be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
* @psalm-suppress RedundantPropertyInitializationCheck
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function unserialize($value) : void
|
||||
{
|
||||
if (isset($this->numerator)) {
|
||||
throw new \LogicException('unserialize() is an internal function, it must not be called directly.');
|
||||
}
|
||||
|
||||
[$numerator, $denominator] = \explode('/', $value);
|
||||
|
||||
$this->numerator = BigInteger::of($numerator);
|
||||
$this->denominator = BigInteger::of($denominator);
|
||||
}
|
||||
}
|
41
vendor/brick/math/src/Exception/DivisionByZeroException.php
vendored
Normal file
41
vendor/brick/math/src/Exception/DivisionByZeroException.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a division by zero occurs.
|
||||
*/
|
||||
class DivisionByZeroException extends MathException
|
||||
{
|
||||
/**
|
||||
* @return DivisionByZeroException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function divisionByZero() : DivisionByZeroException
|
||||
{
|
||||
return new self('Division by zero.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DivisionByZeroException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function modulusMustNotBeZero() : DivisionByZeroException
|
||||
{
|
||||
return new self('The modulus must not be zero.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DivisionByZeroException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function denominatorMustNotBeZero() : DivisionByZeroException
|
||||
{
|
||||
return new self('The denominator of a rational number cannot be zero.');
|
||||
}
|
||||
}
|
27
vendor/brick/math/src/Exception/IntegerOverflowException.php
vendored
Normal file
27
vendor/brick/math/src/Exception/IntegerOverflowException.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
use Brick\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Exception thrown when an integer overflow occurs.
|
||||
*/
|
||||
class IntegerOverflowException extends MathException
|
||||
{
|
||||
/**
|
||||
* @param BigInteger $value
|
||||
*
|
||||
* @return IntegerOverflowException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function toIntOverflow(BigInteger $value) : IntegerOverflowException
|
||||
{
|
||||
$message = '%s is out of range %d to %d and cannot be represented as an integer.';
|
||||
|
||||
return new self(\sprintf($message, (string) $value, PHP_INT_MIN, PHP_INT_MAX));
|
||||
}
|
||||
}
|
14
vendor/brick/math/src/Exception/MathException.php
vendored
Normal file
14
vendor/brick/math/src/Exception/MathException.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Base class for all math exceptions.
|
||||
*
|
||||
* This class is abstract to ensure that only fine-grained exceptions are thrown throughout the code.
|
||||
*/
|
||||
class MathException extends \RuntimeException
|
||||
{
|
||||
}
|
12
vendor/brick/math/src/Exception/NegativeNumberException.php
vendored
Normal file
12
vendor/brick/math/src/Exception/NegativeNumberException.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when attempting to perform an unsupported operation, such as a square root, on a negative number.
|
||||
*/
|
||||
class NegativeNumberException extends MathException
|
||||
{
|
||||
}
|
35
vendor/brick/math/src/Exception/NumberFormatException.php
vendored
Normal file
35
vendor/brick/math/src/Exception/NumberFormatException.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when attempting to create a number from a string with an invalid format.
|
||||
*/
|
||||
class NumberFormatException extends MathException
|
||||
{
|
||||
/**
|
||||
* @param string $char The failing character.
|
||||
*
|
||||
* @return NumberFormatException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function charNotInAlphabet(string $char) : self
|
||||
{
|
||||
$ord = \ord($char);
|
||||
|
||||
if ($ord < 32 || $ord > 126) {
|
||||
$char = \strtoupper(\dechex($ord));
|
||||
|
||||
if ($ord < 10) {
|
||||
$char = '0' . $char;
|
||||
}
|
||||
} else {
|
||||
$char = '"' . $char . '"';
|
||||
}
|
||||
|
||||
return new self(sprintf('Char %s is not a valid character in the given alphabet.', $char));
|
||||
}
|
||||
}
|
21
vendor/brick/math/src/Exception/RoundingNecessaryException.php
vendored
Normal file
21
vendor/brick/math/src/Exception/RoundingNecessaryException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a number cannot be represented at the requested scale without rounding.
|
||||
*/
|
||||
class RoundingNecessaryException extends MathException
|
||||
{
|
||||
/**
|
||||
* @return RoundingNecessaryException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function roundingNecessary() : RoundingNecessaryException
|
||||
{
|
||||
return new self('Rounding is necessary to represent the result of the operation at this scale.');
|
||||
}
|
||||
}
|
756
vendor/brick/math/src/Internal/Calculator.php
vendored
Normal file
756
vendor/brick/math/src/Internal/Calculator.php
vendored
Normal file
@@ -0,0 +1,756 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal;
|
||||
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
use Brick\Math\RoundingMode;
|
||||
|
||||
/**
|
||||
* Performs basic operations on arbitrary size integers.
|
||||
*
|
||||
* Unless otherwise specified, all parameters must be validated as non-empty strings of digits,
|
||||
* without leading zero, and with an optional leading minus sign if the number is not zero.
|
||||
*
|
||||
* Any other parameter format will lead to undefined behaviour.
|
||||
* All methods must return strings respecting this format, unless specified otherwise.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
abstract class Calculator
|
||||
{
|
||||
/**
|
||||
* The maximum exponent value allowed for the pow() method.
|
||||
*/
|
||||
public const MAX_POWER = 1000000;
|
||||
|
||||
/**
|
||||
* The alphabet for converting from and to base 2 to 36, lowercase.
|
||||
*/
|
||||
public const ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
/**
|
||||
* The Calculator instance in use.
|
||||
*
|
||||
* @var Calculator|null
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* Sets the Calculator instance to use.
|
||||
*
|
||||
* An instance is typically set only in unit tests: the autodetect is usually the best option.
|
||||
*
|
||||
* @param Calculator|null $calculator The calculator instance, or NULL to revert to autodetect.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
final public static function set(?Calculator $calculator) : void
|
||||
{
|
||||
self::$instance = $calculator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Calculator instance to use.
|
||||
*
|
||||
* If none has been explicitly set, the fastest available implementation will be returned.
|
||||
*
|
||||
* @return Calculator
|
||||
*
|
||||
* @psalm-pure
|
||||
* @psalm-suppress ImpureStaticProperty
|
||||
*/
|
||||
final public static function get() : Calculator
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
/** @psalm-suppress ImpureMethodCall */
|
||||
self::$instance = self::detect();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fastest available Calculator implementation.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return Calculator
|
||||
*/
|
||||
private static function detect() : Calculator
|
||||
{
|
||||
if (\extension_loaded('gmp')) {
|
||||
return new Calculator\GmpCalculator();
|
||||
}
|
||||
|
||||
if (\extension_loaded('bcmath')) {
|
||||
return new Calculator\BcMathCalculator();
|
||||
}
|
||||
|
||||
return new Calculator\NativeCalculator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the sign & digits of the operands.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return array{bool, bool, string, string} Whether $a and $b are negative, followed by their digits.
|
||||
*/
|
||||
final protected function init(string $a, string $b) : array
|
||||
{
|
||||
return [
|
||||
$aNeg = ($a[0] === '-'),
|
||||
$bNeg = ($b[0] === '-'),
|
||||
|
||||
$aNeg ? \substr($a, 1) : $a,
|
||||
$bNeg ? \substr($b, 1) : $b,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a number.
|
||||
*
|
||||
* @param string $n The number.
|
||||
*
|
||||
* @return string The absolute value.
|
||||
*/
|
||||
final public function abs(string $n) : string
|
||||
{
|
||||
return ($n[0] === '-') ? \substr($n, 1) : $n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Negates a number.
|
||||
*
|
||||
* @param string $n The number.
|
||||
*
|
||||
* @return string The negated value.
|
||||
*/
|
||||
final public function neg(string $n) : string
|
||||
{
|
||||
if ($n === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if ($n[0] === '-') {
|
||||
return \substr($n, 1);
|
||||
}
|
||||
|
||||
return '-' . $n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two numbers.
|
||||
*
|
||||
* @param string $a The first number.
|
||||
* @param string $b The second number.
|
||||
*
|
||||
* @return int [-1, 0, 1] If the first number is less than, equal to, or greater than the second number.
|
||||
*/
|
||||
final public function cmp(string $a, string $b) : int
|
||||
{
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
if ($aNeg && ! $bNeg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($bNeg && ! $aNeg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$aLen = \strlen($aDig);
|
||||
$bLen = \strlen($bDig);
|
||||
|
||||
if ($aLen < $bLen) {
|
||||
$result = -1;
|
||||
} elseif ($aLen > $bLen) {
|
||||
$result = 1;
|
||||
} else {
|
||||
$result = $aDig <=> $bDig;
|
||||
}
|
||||
|
||||
return $aNeg ? -$result : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two numbers.
|
||||
*
|
||||
* @param string $a The augend.
|
||||
* @param string $b The addend.
|
||||
*
|
||||
* @return string The sum.
|
||||
*/
|
||||
abstract public function add(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Subtracts two numbers.
|
||||
*
|
||||
* @param string $a The minuend.
|
||||
* @param string $b The subtrahend.
|
||||
*
|
||||
* @return string The difference.
|
||||
*/
|
||||
abstract public function sub(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Multiplies two numbers.
|
||||
*
|
||||
* @param string $a The multiplicand.
|
||||
* @param string $b The multiplier.
|
||||
*
|
||||
* @return string The product.
|
||||
*/
|
||||
abstract public function mul(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return string The quotient.
|
||||
*/
|
||||
abstract public function divQ(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return string The remainder.
|
||||
*/
|
||||
abstract public function divR(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return string[] An array containing the quotient and remainder.
|
||||
*/
|
||||
abstract public function divQR(string $a, string $b) : array;
|
||||
|
||||
/**
|
||||
* Exponentiates a number.
|
||||
*
|
||||
* @param string $a The base number.
|
||||
* @param int $e The exponent, validated as an integer between 0 and MAX_POWER.
|
||||
*
|
||||
* @return string The power.
|
||||
*/
|
||||
abstract public function pow(string $a, int $e) : string;
|
||||
|
||||
/**
|
||||
* @param string $a
|
||||
* @param string $b The modulus; must not be zero.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mod(string $a, string $b) : string
|
||||
{
|
||||
return $this->divR($this->add($this->divR($a, $b), $b), $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the modular multiplicative inverse of $x modulo $m.
|
||||
*
|
||||
* If $x has no multiplicative inverse mod m, this method must return null.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library has built-in support.
|
||||
*
|
||||
* @param string $x
|
||||
* @param string $m The modulus; must not be negative or zero.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function modInverse(string $x, string $m) : ?string
|
||||
{
|
||||
if ($m === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$modVal = $x;
|
||||
|
||||
if ($x[0] === '-' || ($this->cmp($this->abs($x), $m) >= 0)) {
|
||||
$modVal = $this->mod($x, $m);
|
||||
}
|
||||
|
||||
$x = '0';
|
||||
$y = '0';
|
||||
$g = $this->gcdExtended($modVal, $m, $x, $y);
|
||||
|
||||
if ($g !== '1') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->mod($this->add($this->mod($x, $m), $m), $m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raises a number into power with modulo.
|
||||
*
|
||||
* @param string $base The base number; must be positive or zero.
|
||||
* @param string $exp The exponent; must be positive or zero.
|
||||
* @param string $mod The modulus; must be strictly positive.
|
||||
*
|
||||
* @return string The power.
|
||||
*/
|
||||
abstract public function modPow(string $base, string $exp, string $mod) : string;
|
||||
|
||||
/**
|
||||
* Returns the greatest common divisor of the two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for GCD calculations.
|
||||
*
|
||||
* @param string $a The first number.
|
||||
* @param string $b The second number.
|
||||
*
|
||||
* @return string The GCD, always positive, or zero if both arguments are zero.
|
||||
*/
|
||||
public function gcd(string $a, string $b) : string
|
||||
{
|
||||
if ($a === '0') {
|
||||
return $this->abs($b);
|
||||
}
|
||||
|
||||
if ($b === '0') {
|
||||
return $this->abs($a);
|
||||
}
|
||||
|
||||
return $this->gcd($b, $this->divR($a, $b));
|
||||
}
|
||||
|
||||
private function gcdExtended(string $a, string $b, string &$x, string &$y) : string
|
||||
{
|
||||
if ($a === '0') {
|
||||
$x = '0';
|
||||
$y = '1';
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
$x1 = '0';
|
||||
$y1 = '0';
|
||||
|
||||
$gcd = $this->gcdExtended($this->mod($b, $a), $a, $x1, $y1);
|
||||
|
||||
$x = $this->sub($y1, $this->mul($this->divQ($b, $a), $x1));
|
||||
$y = $x1;
|
||||
|
||||
return $gcd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square root of the given number, rounded down.
|
||||
*
|
||||
* The result is the largest x such that x² ≤ n.
|
||||
* The input MUST NOT be negative.
|
||||
*
|
||||
* @param string $n The number.
|
||||
*
|
||||
* @return string The square root.
|
||||
*/
|
||||
abstract public function sqrt(string $n) : string;
|
||||
|
||||
/**
|
||||
* Converts a number from an arbitrary base.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for base conversion.
|
||||
*
|
||||
* @param string $number The number, positive or zero, non-empty, case-insensitively validated for the given base.
|
||||
* @param int $base The base of the number, validated from 2 to 36.
|
||||
*
|
||||
* @return string The converted number, following the Calculator conventions.
|
||||
*/
|
||||
public function fromBase(string $number, int $base) : string
|
||||
{
|
||||
return $this->fromArbitraryBase(\strtolower($number), self::ALPHABET, $base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number to an arbitrary base.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for base conversion.
|
||||
*
|
||||
* @param string $number The number to convert, following the Calculator conventions.
|
||||
* @param int $base The base to convert to, validated from 2 to 36.
|
||||
*
|
||||
* @return string The converted number, lowercase.
|
||||
*/
|
||||
public function toBase(string $number, int $base) : string
|
||||
{
|
||||
$negative = ($number[0] === '-');
|
||||
|
||||
if ($negative) {
|
||||
$number = \substr($number, 1);
|
||||
}
|
||||
|
||||
$number = $this->toArbitraryBase($number, self::ALPHABET, $base);
|
||||
|
||||
if ($negative) {
|
||||
return '-' . $number;
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a non-negative number in an arbitrary base using a custom alphabet, to base 10.
|
||||
*
|
||||
* @param string $number The number to convert, validated as a non-empty string,
|
||||
* containing only chars in the given alphabet/base.
|
||||
* @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum.
|
||||
* @param int $base The base of the number, validated from 2 to alphabet length.
|
||||
*
|
||||
* @return string The number in base 10, following the Calculator conventions.
|
||||
*/
|
||||
final public function fromArbitraryBase(string $number, string $alphabet, int $base) : string
|
||||
{
|
||||
// remove leading "zeros"
|
||||
$number = \ltrim($number, $alphabet[0]);
|
||||
|
||||
if ($number === '') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// optimize for "one"
|
||||
if ($number === $alphabet[1]) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
$result = '0';
|
||||
$power = '1';
|
||||
|
||||
$base = (string) $base;
|
||||
|
||||
for ($i = \strlen($number) - 1; $i >= 0; $i--) {
|
||||
$index = \strpos($alphabet, $number[$i]);
|
||||
|
||||
if ($index !== 0) {
|
||||
$result = $this->add($result, ($index === 1)
|
||||
? $power
|
||||
: $this->mul($power, (string) $index)
|
||||
);
|
||||
}
|
||||
|
||||
if ($i !== 0) {
|
||||
$power = $this->mul($power, $base);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a non-negative number to an arbitrary base using a custom alphabet.
|
||||
*
|
||||
* @param string $number The number to convert, positive or zero, following the Calculator conventions.
|
||||
* @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum.
|
||||
* @param int $base The base to convert to, validated from 2 to alphabet length.
|
||||
*
|
||||
* @return string The converted number in the given alphabet.
|
||||
*/
|
||||
final public function toArbitraryBase(string $number, string $alphabet, int $base) : string
|
||||
{
|
||||
if ($number === '0') {
|
||||
return $alphabet[0];
|
||||
}
|
||||
|
||||
$base = (string) $base;
|
||||
$result = '';
|
||||
|
||||
while ($number !== '0') {
|
||||
[$number, $remainder] = $this->divQR($number, $base);
|
||||
$remainder = (int) $remainder;
|
||||
|
||||
$result .= $alphabet[$remainder];
|
||||
}
|
||||
|
||||
return \strrev($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a rounded division.
|
||||
*
|
||||
* Rounding is performed when the remainder of the division is not zero.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
* @param int $roundingMode The rounding mode.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException If the rounding mode is invalid.
|
||||
* @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary.
|
||||
*/
|
||||
final public function divRound(string $a, string $b, int $roundingMode) : string
|
||||
{
|
||||
[$quotient, $remainder] = $this->divQR($a, $b);
|
||||
|
||||
$hasDiscardedFraction = ($remainder !== '0');
|
||||
$isPositiveOrZero = ($a[0] === '-') === ($b[0] === '-');
|
||||
|
||||
$discardedFractionSign = function() use ($remainder, $b) : int {
|
||||
$r = $this->abs($this->mul($remainder, '2'));
|
||||
$b = $this->abs($b);
|
||||
|
||||
return $this->cmp($r, $b);
|
||||
};
|
||||
|
||||
$increment = false;
|
||||
|
||||
switch ($roundingMode) {
|
||||
case RoundingMode::UNNECESSARY:
|
||||
if ($hasDiscardedFraction) {
|
||||
throw RoundingNecessaryException::roundingNecessary();
|
||||
}
|
||||
break;
|
||||
|
||||
case RoundingMode::UP:
|
||||
$increment = $hasDiscardedFraction;
|
||||
break;
|
||||
|
||||
case RoundingMode::DOWN:
|
||||
break;
|
||||
|
||||
case RoundingMode::CEILING:
|
||||
$increment = $hasDiscardedFraction && $isPositiveOrZero;
|
||||
break;
|
||||
|
||||
case RoundingMode::FLOOR:
|
||||
$increment = $hasDiscardedFraction && ! $isPositiveOrZero;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_UP:
|
||||
$increment = $discardedFractionSign() >= 0;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_DOWN:
|
||||
$increment = $discardedFractionSign() > 0;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_CEILING:
|
||||
$increment = $isPositiveOrZero ? $discardedFractionSign() >= 0 : $discardedFractionSign() > 0;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_FLOOR:
|
||||
$increment = $isPositiveOrZero ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_EVEN:
|
||||
$lastDigit = (int) $quotient[-1];
|
||||
$lastDigitIsEven = ($lastDigit % 2 === 0);
|
||||
$increment = $lastDigitIsEven ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid rounding mode.');
|
||||
}
|
||||
|
||||
if ($increment) {
|
||||
return $this->add($quotient, $isPositiveOrZero ? '1' : '-1');
|
||||
}
|
||||
|
||||
return $quotient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise AND of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function and(string $a, string $b) : string
|
||||
{
|
||||
return $this->bitwise('and', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise OR of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function or(string $a, string $b) : string
|
||||
{
|
||||
return $this->bitwise('or', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise XOR of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function xor(string $a, string $b) : string
|
||||
{
|
||||
return $this->bitwise('xor', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a bitwise operation on a decimal number.
|
||||
*
|
||||
* @param string $operator The operator to use, must be "and", "or" or "xor".
|
||||
* @param string $a The left operand.
|
||||
* @param string $b The right operand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function bitwise(string $operator, string $a, string $b) : string
|
||||
{
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
$aBin = $this->toBinary($aDig);
|
||||
$bBin = $this->toBinary($bDig);
|
||||
|
||||
$aLen = \strlen($aBin);
|
||||
$bLen = \strlen($bBin);
|
||||
|
||||
if ($aLen > $bLen) {
|
||||
$bBin = \str_repeat("\x00", $aLen - $bLen) . $bBin;
|
||||
} elseif ($bLen > $aLen) {
|
||||
$aBin = \str_repeat("\x00", $bLen - $aLen) . $aBin;
|
||||
}
|
||||
|
||||
if ($aNeg) {
|
||||
$aBin = $this->twosComplement($aBin);
|
||||
}
|
||||
if ($bNeg) {
|
||||
$bBin = $this->twosComplement($bBin);
|
||||
}
|
||||
|
||||
switch ($operator) {
|
||||
case 'and':
|
||||
$value = $aBin & $bBin;
|
||||
$negative = ($aNeg and $bNeg);
|
||||
break;
|
||||
|
||||
case 'or':
|
||||
$value = $aBin | $bBin;
|
||||
$negative = ($aNeg or $bNeg);
|
||||
break;
|
||||
|
||||
case 'xor':
|
||||
$value = $aBin ^ $bBin;
|
||||
$negative = ($aNeg xor $bNeg);
|
||||
break;
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid bitwise operator.');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
if ($negative) {
|
||||
$value = $this->twosComplement($value);
|
||||
}
|
||||
|
||||
$result = $this->toDecimal($value);
|
||||
|
||||
return $negative ? $this->neg($result) : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $number A positive, binary number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function twosComplement(string $number) : string
|
||||
{
|
||||
$xor = \str_repeat("\xff", \strlen($number));
|
||||
|
||||
$number ^= $xor;
|
||||
|
||||
for ($i = \strlen($number) - 1; $i >= 0; $i--) {
|
||||
$byte = \ord($number[$i]);
|
||||
|
||||
if (++$byte !== 256) {
|
||||
$number[$i] = \chr($byte);
|
||||
break;
|
||||
}
|
||||
|
||||
$number[$i] = "\x00";
|
||||
|
||||
if ($i === 0) {
|
||||
$number = "\x01" . $number;
|
||||
}
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a decimal number to a binary string.
|
||||
*
|
||||
* @param string $number The number to convert, positive or zero, only digits.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function toBinary(string $number) : string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
while ($number !== '0') {
|
||||
[$number, $remainder] = $this->divQR($number, '256');
|
||||
$result .= \chr((int) $remainder);
|
||||
}
|
||||
|
||||
return \strrev($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the positive decimal representation of a binary number.
|
||||
*
|
||||
* @param string $bytes The bytes representing the number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function toDecimal(string $bytes) : string
|
||||
{
|
||||
$result = '0';
|
||||
$power = '1';
|
||||
|
||||
for ($i = \strlen($bytes) - 1; $i >= 0; $i--) {
|
||||
$index = \ord($bytes[$i]);
|
||||
|
||||
if ($index !== 0) {
|
||||
$result = $this->add($result, ($index === 1)
|
||||
? $power
|
||||
: $this->mul($power, (string) $index)
|
||||
);
|
||||
}
|
||||
|
||||
if ($i !== 0) {
|
||||
$power = $this->mul($power, '256');
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
116
vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php
vendored
Normal file
116
vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
/**
|
||||
* Calculator implementation built around the bcmath library.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class BcMathCalculator extends Calculator
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(string $a, string $b) : string
|
||||
{
|
||||
return \bcadd($a, $b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sub(string $a, string $b) : string
|
||||
{
|
||||
return \bcsub($a, $b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function mul(string $a, string $b) : string
|
||||
{
|
||||
return \bcmul($a, $b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @psalm-suppress InvalidNullableReturnType
|
||||
* @psalm-suppress NullableReturnStatement
|
||||
*/
|
||||
public function divQ(string $a, string $b) : string
|
||||
{
|
||||
return \bcdiv($a, $b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @psalm-suppress InvalidNullableReturnType
|
||||
* @psalm-suppress NullableReturnStatement
|
||||
*/
|
||||
public function divR(string $a, string $b) : string
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '7.2') >= 0) {
|
||||
return \bcmod($a, $b, 0);
|
||||
}
|
||||
|
||||
return \bcmod($a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQR(string $a, string $b) : array
|
||||
{
|
||||
$q = \bcdiv($a, $b, 0);
|
||||
|
||||
if (version_compare(PHP_VERSION, '7.2') >= 0) {
|
||||
$r = \bcmod($a, $b, 0);
|
||||
} else {
|
||||
$r = \bcmod($a, $b);
|
||||
}
|
||||
|
||||
assert($q !== null);
|
||||
assert($r !== null);
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function pow(string $a, int $e) : string
|
||||
{
|
||||
return \bcpow($a, (string) $e, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @psalm-suppress InvalidNullableReturnType
|
||||
* @psalm-suppress NullableReturnStatement
|
||||
*/
|
||||
public function modPow(string $base, string $exp, string $mod) : string
|
||||
{
|
||||
return \bcpowmod($base, $exp, $mod, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-suppress NullableReturnStatement
|
||||
* @psalm-suppress InvalidNullableReturnType
|
||||
*/
|
||||
public function sqrt(string $n) : string
|
||||
{
|
||||
return \bcsqrt($n, 0);
|
||||
}
|
||||
}
|
156
vendor/brick/math/src/Internal/Calculator/GmpCalculator.php
vendored
Normal file
156
vendor/brick/math/src/Internal/Calculator/GmpCalculator.php
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
/**
|
||||
* Calculator implementation built around the GMP library.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class GmpCalculator extends Calculator
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_add($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sub(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_sub($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function mul(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_mul($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQ(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_div_q($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divR(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_div_r($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQR(string $a, string $b) : array
|
||||
{
|
||||
[$q, $r] = \gmp_div_qr($a, $b);
|
||||
|
||||
return [
|
||||
\gmp_strval($q),
|
||||
\gmp_strval($r)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function pow(string $a, int $e) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_pow($a, $e));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function modInverse(string $x, string $m) : ?string
|
||||
{
|
||||
$result = \gmp_invert($x, $m);
|
||||
|
||||
if ($result === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return \gmp_strval($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function modPow(string $base, string $exp, string $mod) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_powm($base, $exp, $mod));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function gcd(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_gcd($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fromBase(string $number, int $base) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_init($number, $base));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBase(string $number, int $base) : string
|
||||
{
|
||||
return \gmp_strval($number, $base);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function and(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_and($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function or(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_or($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function xor(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_xor($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function sqrt(string $n) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_sqrt($n));
|
||||
}
|
||||
}
|
634
vendor/brick/math/src/Internal/Calculator/NativeCalculator.php
vendored
Normal file
634
vendor/brick/math/src/Internal/Calculator/NativeCalculator.php
vendored
Normal file
@@ -0,0 +1,634 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
/**
|
||||
* Calculator implementation using only native PHP code.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class NativeCalculator extends Calculator
|
||||
{
|
||||
/**
|
||||
* The max number of digits the platform can natively add, subtract, multiply or divide without overflow.
|
||||
* For multiplication, this represents the max sum of the lengths of both operands.
|
||||
*
|
||||
* For addition, it is assumed that an extra digit can hold a carry (1) without overflowing.
|
||||
* Example: 32-bit: max number 1,999,999,999 (9 digits + carry)
|
||||
* 64-bit: max number 1,999,999,999,999,999,999 (18 digits + carry)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $maxDigits;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
switch (PHP_INT_SIZE) {
|
||||
case 4:
|
||||
$this->maxDigits = 9;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
$this->maxDigits = 18;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(string $a, string $b) : string
|
||||
{
|
||||
/**
|
||||
* @psalm-var numeric-string $a
|
||||
* @psalm-var numeric-string $b
|
||||
*/
|
||||
$result = $a + $b;
|
||||
|
||||
if (is_int($result)) {
|
||||
return (string) $result;
|
||||
}
|
||||
|
||||
if ($a === '0') {
|
||||
return $b;
|
||||
}
|
||||
|
||||
if ($b === '0') {
|
||||
return $a;
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
$result = $aNeg === $bNeg ? $this->doAdd($aDig, $bDig) : $this->doSub($aDig, $bDig);
|
||||
|
||||
if ($aNeg) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sub(string $a, string $b) : string
|
||||
{
|
||||
return $this->add($a, $this->neg($b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function mul(string $a, string $b) : string
|
||||
{
|
||||
/**
|
||||
* @psalm-var numeric-string $a
|
||||
* @psalm-var numeric-string $b
|
||||
*/
|
||||
$result = $a * $b;
|
||||
|
||||
if (is_int($result)) {
|
||||
return (string) $result;
|
||||
}
|
||||
|
||||
if ($a === '0' || $b === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if ($a === '1') {
|
||||
return $b;
|
||||
}
|
||||
|
||||
if ($b === '1') {
|
||||
return $a;
|
||||
}
|
||||
|
||||
if ($a === '-1') {
|
||||
return $this->neg($b);
|
||||
}
|
||||
|
||||
if ($b === '-1') {
|
||||
return $this->neg($a);
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
$result = $this->doMul($aDig, $bDig);
|
||||
|
||||
if ($aNeg !== $bNeg) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQ(string $a, string $b) : string
|
||||
{
|
||||
return $this->divQR($a, $b)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divR(string $a, string $b): string
|
||||
{
|
||||
return $this->divQR($a, $b)[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQR(string $a, string $b) : array
|
||||
{
|
||||
if ($a === '0') {
|
||||
return ['0', '0'];
|
||||
}
|
||||
|
||||
if ($a === $b) {
|
||||
return ['1', '0'];
|
||||
}
|
||||
|
||||
if ($b === '1') {
|
||||
return [$a, '0'];
|
||||
}
|
||||
|
||||
if ($b === '-1') {
|
||||
return [$this->neg($a), '0'];
|
||||
}
|
||||
|
||||
/** @psalm-var numeric-string $a */
|
||||
$na = $a * 1; // cast to number
|
||||
|
||||
if (is_int($na)) {
|
||||
/** @psalm-var numeric-string $b */
|
||||
$nb = $b * 1;
|
||||
|
||||
if (is_int($nb)) {
|
||||
// the only division that may overflow is PHP_INT_MIN / -1,
|
||||
// which cannot happen here as we've already handled a divisor of -1 above.
|
||||
$r = $na % $nb;
|
||||
$q = ($na - $r) / $nb;
|
||||
|
||||
assert(is_int($q));
|
||||
|
||||
return [
|
||||
(string) $q,
|
||||
(string) $r
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
[$q, $r] = $this->doDiv($aDig, $bDig);
|
||||
|
||||
if ($aNeg !== $bNeg) {
|
||||
$q = $this->neg($q);
|
||||
}
|
||||
|
||||
if ($aNeg) {
|
||||
$r = $this->neg($r);
|
||||
}
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function pow(string $a, int $e) : string
|
||||
{
|
||||
if ($e === 0) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
if ($e === 1) {
|
||||
return $a;
|
||||
}
|
||||
|
||||
$odd = $e % 2;
|
||||
$e -= $odd;
|
||||
|
||||
$aa = $this->mul($a, $a);
|
||||
|
||||
/** @psalm-suppress PossiblyInvalidArgument We're sure that $e / 2 is an int now */
|
||||
$result = $this->pow($aa, $e / 2);
|
||||
|
||||
if ($odd === 1) {
|
||||
$result = $this->mul($result, $a);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Algorithm from: https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function modPow(string $base, string $exp, string $mod) : string
|
||||
{
|
||||
// special case: the algorithm below fails with 0 power 0 mod 1 (returns 1 instead of 0)
|
||||
if ($base === '0' && $exp === '0' && $mod === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// special case: the algorithm below fails with power 0 mod 1 (returns 1 instead of 0)
|
||||
if ($exp === '0' && $mod === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$x = $base;
|
||||
|
||||
$res = '1';
|
||||
|
||||
// numbers are positive, so we can use remainder instead of modulo
|
||||
$x = $this->divR($x, $mod);
|
||||
|
||||
while ($exp !== '0') {
|
||||
if (in_array($exp[-1], ['1', '3', '5', '7', '9'])) { // odd
|
||||
$res = $this->divR($this->mul($res, $x), $mod);
|
||||
}
|
||||
|
||||
$exp = $this->divQ($exp, '2');
|
||||
$x = $this->divR($this->mul($x, $x), $mod);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapted from https://cp-algorithms.com/num_methods/roots_newton.html
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function sqrt(string $n) : string
|
||||
{
|
||||
if ($n === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// initial approximation
|
||||
$x = \str_repeat('9', \intdiv(\strlen($n), 2) ?: 1);
|
||||
|
||||
$decreased = false;
|
||||
|
||||
for (;;) {
|
||||
$nx = $this->divQ($this->add($x, $this->divQ($n, $x)), '2');
|
||||
|
||||
if ($x === $nx || $this->cmp($nx, $x) > 0 && $decreased) {
|
||||
break;
|
||||
}
|
||||
|
||||
$decreased = $this->cmp($nx, $x) < 0;
|
||||
$x = $nx;
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the addition of two non-signed large integers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function doAdd(string $a, string $b) : string
|
||||
{
|
||||
[$a, $b, $length] = $this->pad($a, $b);
|
||||
|
||||
$carry = 0;
|
||||
$result = '';
|
||||
|
||||
for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) {
|
||||
$blockLength = $this->maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockLength += $i;
|
||||
/** @psalm-suppress LoopInvalidation */
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
/** @psalm-var numeric-string $blockA */
|
||||
$blockA = \substr($a, $i, $blockLength);
|
||||
|
||||
/** @psalm-var numeric-string $blockB */
|
||||
$blockB = \substr($b, $i, $blockLength);
|
||||
|
||||
$sum = (string) ($blockA + $blockB + $carry);
|
||||
$sumLength = \strlen($sum);
|
||||
|
||||
if ($sumLength > $blockLength) {
|
||||
$sum = \substr($sum, 1);
|
||||
$carry = 1;
|
||||
} else {
|
||||
if ($sumLength < $blockLength) {
|
||||
$sum = \str_repeat('0', $blockLength - $sumLength) . $sum;
|
||||
}
|
||||
$carry = 0;
|
||||
}
|
||||
|
||||
$result = $sum . $result;
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($carry === 1) {
|
||||
$result = '1' . $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the subtraction of two non-signed large integers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function doSub(string $a, string $b) : string
|
||||
{
|
||||
if ($a === $b) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// Ensure that we always subtract to a positive result: biggest minus smallest.
|
||||
$cmp = $this->doCmp($a, $b);
|
||||
|
||||
$invert = ($cmp === -1);
|
||||
|
||||
if ($invert) {
|
||||
$c = $a;
|
||||
$a = $b;
|
||||
$b = $c;
|
||||
}
|
||||
|
||||
[$a, $b, $length] = $this->pad($a, $b);
|
||||
|
||||
$carry = 0;
|
||||
$result = '';
|
||||
|
||||
$complement = 10 ** $this->maxDigits;
|
||||
|
||||
for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) {
|
||||
$blockLength = $this->maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockLength += $i;
|
||||
/** @psalm-suppress LoopInvalidation */
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
/** @psalm-var numeric-string $blockA */
|
||||
$blockA = \substr($a, $i, $blockLength);
|
||||
|
||||
/** @psalm-var numeric-string $blockB */
|
||||
$blockB = \substr($b, $i, $blockLength);
|
||||
|
||||
$sum = $blockA - $blockB - $carry;
|
||||
|
||||
if ($sum < 0) {
|
||||
$sum += $complement;
|
||||
$carry = 1;
|
||||
} else {
|
||||
$carry = 0;
|
||||
}
|
||||
|
||||
$sum = (string) $sum;
|
||||
$sumLength = \strlen($sum);
|
||||
|
||||
if ($sumLength < $blockLength) {
|
||||
$sum = \str_repeat('0', $blockLength - $sumLength) . $sum;
|
||||
}
|
||||
|
||||
$result = $sum . $result;
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Carry cannot be 1 when the loop ends, as a > b
|
||||
assert($carry === 0);
|
||||
|
||||
$result = \ltrim($result, '0');
|
||||
|
||||
if ($invert) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the multiplication of two non-signed large integers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function doMul(string $a, string $b) : string
|
||||
{
|
||||
$x = \strlen($a);
|
||||
$y = \strlen($b);
|
||||
|
||||
$maxDigits = \intdiv($this->maxDigits, 2);
|
||||
$complement = 10 ** $maxDigits;
|
||||
|
||||
$result = '0';
|
||||
|
||||
for ($i = $x - $maxDigits;; $i -= $maxDigits) {
|
||||
$blockALength = $maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockALength += $i;
|
||||
/** @psalm-suppress LoopInvalidation */
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
$blockA = (int) \substr($a, $i, $blockALength);
|
||||
|
||||
$line = '';
|
||||
$carry = 0;
|
||||
|
||||
for ($j = $y - $maxDigits;; $j -= $maxDigits) {
|
||||
$blockBLength = $maxDigits;
|
||||
|
||||
if ($j < 0) {
|
||||
$blockBLength += $j;
|
||||
/** @psalm-suppress LoopInvalidation */
|
||||
$j = 0;
|
||||
}
|
||||
|
||||
$blockB = (int) \substr($b, $j, $blockBLength);
|
||||
|
||||
$mul = $blockA * $blockB + $carry;
|
||||
$value = $mul % $complement;
|
||||
$carry = ($mul - $value) / $complement;
|
||||
|
||||
$value = (string) $value;
|
||||
$value = \str_pad($value, $maxDigits, '0', STR_PAD_LEFT);
|
||||
|
||||
$line = $value . $line;
|
||||
|
||||
if ($j === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($carry !== 0) {
|
||||
$line = $carry . $line;
|
||||
}
|
||||
|
||||
$line = \ltrim($line, '0');
|
||||
|
||||
if ($line !== '') {
|
||||
$line .= \str_repeat('0', $x - $blockALength - $i);
|
||||
$result = $this->add($result, $line);
|
||||
}
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the division of two non-signed large integers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return string[] The quotient and remainder.
|
||||
*/
|
||||
private function doDiv(string $a, string $b) : array
|
||||
{
|
||||
$cmp = $this->doCmp($a, $b);
|
||||
|
||||
if ($cmp === -1) {
|
||||
return ['0', $a];
|
||||
}
|
||||
|
||||
$x = \strlen($a);
|
||||
$y = \strlen($b);
|
||||
|
||||
// we now know that a >= b && x >= y
|
||||
|
||||
$q = '0'; // quotient
|
||||
$r = $a; // remainder
|
||||
$z = $y; // focus length, always $y or $y+1
|
||||
|
||||
for (;;) {
|
||||
$focus = \substr($a, 0, $z);
|
||||
|
||||
$cmp = $this->doCmp($focus, $b);
|
||||
|
||||
if ($cmp === -1) {
|
||||
if ($z === $x) { // remainder < dividend
|
||||
break;
|
||||
}
|
||||
|
||||
$z++;
|
||||
}
|
||||
|
||||
$zeros = \str_repeat('0', $x - $z);
|
||||
|
||||
$q = $this->add($q, '1' . $zeros);
|
||||
$a = $this->sub($a, $b . $zeros);
|
||||
|
||||
$r = $a;
|
||||
|
||||
if ($r === '0') { // remainder == 0
|
||||
break;
|
||||
}
|
||||
|
||||
$x = \strlen($a);
|
||||
|
||||
if ($x < $y) { // remainder < dividend
|
||||
break;
|
||||
}
|
||||
|
||||
$z = $y;
|
||||
}
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two non-signed large numbers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return int [-1, 0, 1]
|
||||
*/
|
||||
private function doCmp(string $a, string $b) : int
|
||||
{
|
||||
$x = \strlen($a);
|
||||
$y = \strlen($b);
|
||||
|
||||
$cmp = $x <=> $y;
|
||||
|
||||
if ($cmp !== 0) {
|
||||
return $cmp;
|
||||
}
|
||||
|
||||
return \strcmp($a, $b) <=> 0; // enforce [-1, 0, 1]
|
||||
}
|
||||
|
||||
/**
|
||||
* Pads the left of one of the given numbers with zeros if necessary to make both numbers the same length.
|
||||
*
|
||||
* The numbers must only consist of digits, without leading minus sign.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return array{string, string, int}
|
||||
*/
|
||||
private function pad(string $a, string $b) : array
|
||||
{
|
||||
$x = \strlen($a);
|
||||
$y = \strlen($b);
|
||||
|
||||
if ($x > $y) {
|
||||
$b = \str_repeat('0', $x - $y) . $b;
|
||||
|
||||
return [$a, $b, $x];
|
||||
}
|
||||
|
||||
if ($x < $y) {
|
||||
$a = \str_repeat('0', $y - $x) . $a;
|
||||
|
||||
return [$a, $b, $y];
|
||||
}
|
||||
|
||||
return [$a, $b, $x];
|
||||
}
|
||||
}
|
107
vendor/brick/math/src/RoundingMode.php
vendored
Normal file
107
vendor/brick/math/src/RoundingMode.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
/**
|
||||
* Specifies a rounding behavior for numerical operations capable of discarding precision.
|
||||
*
|
||||
* Each rounding mode indicates how the least significant returned digit of a rounded result
|
||||
* is to be calculated. If fewer digits are returned than the digits needed to represent the
|
||||
* exact numerical result, the discarded digits will be referred to as the discarded fraction
|
||||
* regardless the digits' contribution to the value of the number. In other words, considered
|
||||
* as a numerical value, the discarded fraction could have an absolute value greater than one.
|
||||
*/
|
||||
final class RoundingMode
|
||||
{
|
||||
/**
|
||||
* Private constructor. This class is not instantiable.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the requested operation has an exact result, hence no rounding is necessary.
|
||||
*
|
||||
* If this rounding mode is specified on an operation that yields a result that
|
||||
* cannot be represented at the requested scale, a RoundingNecessaryException is thrown.
|
||||
*/
|
||||
public const UNNECESSARY = 0;
|
||||
|
||||
/**
|
||||
* Rounds away from zero.
|
||||
*
|
||||
* Always increments the digit prior to a nonzero discarded fraction.
|
||||
* Note that this rounding mode never decreases the magnitude of the calculated value.
|
||||
*/
|
||||
public const UP = 1;
|
||||
|
||||
/**
|
||||
* Rounds towards zero.
|
||||
*
|
||||
* Never increments the digit prior to a discarded fraction (i.e., truncates).
|
||||
* Note that this rounding mode never increases the magnitude of the calculated value.
|
||||
*/
|
||||
public const DOWN = 2;
|
||||
|
||||
/**
|
||||
* Rounds towards positive infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for UP; if negative, behaves as for DOWN.
|
||||
* Note that this rounding mode never decreases the calculated value.
|
||||
*/
|
||||
public const CEILING = 3;
|
||||
|
||||
/**
|
||||
* Rounds towards negative infinity.
|
||||
*
|
||||
* If the result is positive, behave as for DOWN; if negative, behave as for UP.
|
||||
* Note that this rounding mode never increases the calculated value.
|
||||
*/
|
||||
public const FLOOR = 4;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
|
||||
*
|
||||
* Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves as for DOWN.
|
||||
* Note that this is the rounding mode commonly taught at school.
|
||||
*/
|
||||
public const HALF_UP = 5;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
|
||||
*
|
||||
* Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN.
|
||||
*/
|
||||
public const HALF_DOWN = 6;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN.
|
||||
*/
|
||||
public const HALF_CEILING = 7;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP.
|
||||
*/
|
||||
public const HALF_FLOOR = 8;
|
||||
|
||||
/**
|
||||
* Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor.
|
||||
*
|
||||
* Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd;
|
||||
* behaves as for HALF_DOWN if it's even.
|
||||
*
|
||||
* Note that this is the rounding mode that statistically minimizes
|
||||
* cumulative error when applied repeatedly over a sequence of calculations.
|
||||
* It is sometimes known as "Banker's rounding", and is chiefly used in the USA.
|
||||
*/
|
||||
public const HALF_EVEN = 9;
|
||||
}
|
26
vendor/brozot/laravel-fcm/.gitignore
vendored
26
vendor/brozot/laravel-fcm/.gitignore
vendored
@@ -1,26 +0,0 @@
|
||||
# General
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Project
|
||||
.env
|
||||
composer.phar
|
||||
vendor
|
||||
build
|
||||
node_modules
|
||||
resources/assets/bower
|
||||
Homestead.yaml
|
||||
Homestead.json
|
||||
storage/debugbar
|
||||
doc/generated/*
|
||||
generatedoc.sh
|
||||
phpdoc.xml
|
||||
build/*
|
||||
|
||||
# Editors
|
||||
.sublime-workspace
|
||||
.idea
|
||||
.idea/*
|
||||
.idea/workspace.xml
|
||||
*.iml
|
||||
_ide_helper.php
|
14
vendor/brozot/laravel-fcm/.travis.yml
vendored
14
vendor/brozot/laravel-fcm/.travis.yml
vendored
@@ -1,14 +0,0 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.6
|
||||
|
||||
before_script:
|
||||
- composer self-update
|
||||
- composer install --no-interaction
|
||||
|
||||
script:
|
||||
- phpunit --coverage-clover build/logs/clover.xml
|
||||
|
||||
after_success:
|
||||
- travis_retry php vendor/bin/coveralls
|
21
vendor/brozot/laravel-fcm/LICENSE
vendored
21
vendor/brozot/laravel-fcm/LICENSE
vendored
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Nicolas Brosy
|
||||
|
||||
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.
|
446
vendor/brozot/laravel-fcm/README.md
vendored
446
vendor/brozot/laravel-fcm/README.md
vendored
@@ -1,446 +0,0 @@
|
||||
# Laravel-FCM
|
||||
|
||||
[](https://travis-ci.org/brozot/Laravel-FCM) [](https://coveralls.io/github/brozot/Laravel-FCM?branch=master) [](https://packagist.org/packages/brozot/laravel-fcm) [](https://packagist.org/packages/brozot/laravel-fcm)
|
||||
[](https://packagist.org/packages/brozot/laravel-fcm)
|
||||
|
||||
## Introduction
|
||||
|
||||
Laravel-FCM is an easy to use package working with both Laravel and Lumen for sending push notification with [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/) (FCM).
|
||||
|
||||
It currently **only supports HTTP protocol** for :
|
||||
|
||||
- sending a downstream message to one or multiple devices
|
||||
- managing groups and sending message to a group
|
||||
- sending topics messages
|
||||
|
||||
> Note: The XMPP protocol is not currently supported.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
To get the latest version of Laravel-FCM on your project, require it from "composer":
|
||||
|
||||
|
||||
$ composer require brozot/laravel-fcm
|
||||
|
||||
|
||||
Or you can add it directly in your composer.json file:
|
||||
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"brozot/laravel-fcm": "1.3.*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Laravel
|
||||
|
||||
Register the provider directly in your app configuration file config/app.php `config/app.php`:
|
||||
|
||||
Laravel >= 5.5 provides package auto-discovery, thanks to rasmuscnielsen and luiztessadri who help to implement this feature in Laravel-FCM, the registration of the provider and the facades should not be necessary anymore.
|
||||
|
||||
```php
|
||||
'providers' => [
|
||||
// ...
|
||||
|
||||
LaravelFCM\FCMServiceProvider::class,
|
||||
]
|
||||
```
|
||||
|
||||
Add the facade aliases in the same file:
|
||||
|
||||
```php
|
||||
'aliases' => [
|
||||
...
|
||||
'FCM' => LaravelFCM\Facades\FCM::class,
|
||||
'FCMGroup' => LaravelFCM\Facades\FCMGroup::class, // Optional
|
||||
]
|
||||
```
|
||||
|
||||
> Note: The `FCMGroup` facade is needed only if you want to manage groups messages in your application.
|
||||
|
||||
Publish the package config file using the following command:
|
||||
|
||||
|
||||
$ php artisan vendor:publish --provider="LaravelFCM\FCMServiceProvider"
|
||||
|
||||
|
||||
### Lumen
|
||||
|
||||
Register the provider in your bootstrap app file ```boostrap/app.php```
|
||||
|
||||
Add the following line in the "Register Service Providers" section at the bottom of the file.
|
||||
|
||||
```php
|
||||
$app->register(LaravelFCM\FCMServiceProvider::class);
|
||||
```
|
||||
|
||||
For facades, add the following lines in the section "Create The Application" . FCMGroup facade is only necessary if you want to use groups message in your application.
|
||||
|
||||
```php
|
||||
class_alias(\LaravelFCM\Facades\FCM::class, 'FCM');
|
||||
class_alias(\LaravelFCM\Facades\FCMGroup::class, 'FCMGroup');
|
||||
```
|
||||
|
||||
Copy the config file ```fcm.php``` manually from the directory ```/vendor/brozot/laravel-fcm/config``` to the directory ```/config ``` (you may need to create this directory).
|
||||
|
||||
|
||||
### Package Configuration
|
||||
|
||||
In your `.env` file, add the server key and the secret key for the Firebase Cloud Messaging:
|
||||
|
||||
```php
|
||||
FCM_SERVER_KEY=my_secret_server_key
|
||||
FCM_SENDER_ID=my_secret_sender_id
|
||||
```
|
||||
|
||||
To get these keys, you must create a new application on the [firebase cloud messaging console](https://console.firebase.google.com/).
|
||||
|
||||
After the creation of your application on Firebase, you can find keys in `project settings -> cloud messaging`.
|
||||
|
||||
|
||||
## Basic Usage
|
||||
|
||||
Two types of messages can be sent using Laravel-FCM:
|
||||
|
||||
- Notification messages, sometimes thought of as "display messages"
|
||||
- Data messages, which are handled by the client app
|
||||
|
||||
More information is available in the [official documentation](https://firebase.google.com/docs/cloud-messaging/concept-options).
|
||||
|
||||
|
||||
### Downstream Messages
|
||||
|
||||
A downstream message is a notification message, a data message, or both, that you send to a target device or to multiple target devices using its registration_Ids.
|
||||
|
||||
The following use statements are required for the examples below:
|
||||
|
||||
```php
|
||||
use LaravelFCM\Message\OptionsBuilder;
|
||||
use LaravelFCM\Message\PayloadDataBuilder;
|
||||
use LaravelFCM\Message\PayloadNotificationBuilder;
|
||||
use FCM;
|
||||
```
|
||||
|
||||
#### Sending a Downstream Message to a Device
|
||||
|
||||
```php
|
||||
$optionBuilder = new OptionsBuilder();
|
||||
$optionBuilder->setTimeToLive(60*20);
|
||||
|
||||
$notificationBuilder = new PayloadNotificationBuilder('my title');
|
||||
$notificationBuilder->setBody('Hello world')
|
||||
->setSound('default');
|
||||
|
||||
$dataBuilder = new PayloadDataBuilder();
|
||||
$dataBuilder->addData(['a_data' => 'my_data']);
|
||||
|
||||
$option = $optionBuilder->build();
|
||||
$notification = $notificationBuilder->build();
|
||||
$data = $dataBuilder->build();
|
||||
|
||||
$token = "a_registration_from_your_database";
|
||||
|
||||
$downstreamResponse = FCM::sendTo($token, $option, $notification, $data);
|
||||
|
||||
$downstreamResponse->numberSuccess();
|
||||
$downstreamResponse->numberFailure();
|
||||
$downstreamResponse->numberModification();
|
||||
|
||||
// return Array - you must remove all this tokens in your database
|
||||
$downstreamResponse->tokensToDelete();
|
||||
|
||||
// return Array (key : oldToken, value : new token - you must change the token in your database)
|
||||
$downstreamResponse->tokensToModify();
|
||||
|
||||
// return Array - you should try to resend the message to the tokens in the array
|
||||
$downstreamResponse->tokensToRetry();
|
||||
|
||||
// return Array (key:token, value:error) - in production you should remove from your database the tokens
|
||||
$downstreamResponse->tokensWithError();
|
||||
```
|
||||
|
||||
#### Sending a Downstream Message to Multiple Devices
|
||||
|
||||
```php
|
||||
$optionBuilder = new OptionsBuilder();
|
||||
$optionBuilder->setTimeToLive(60*20);
|
||||
|
||||
$notificationBuilder = new PayloadNotificationBuilder('my title');
|
||||
$notificationBuilder->setBody('Hello world')
|
||||
->setSound('default');
|
||||
|
||||
$dataBuilder = new PayloadDataBuilder();
|
||||
$dataBuilder->addData(['a_data' => 'my_data']);
|
||||
|
||||
$option = $optionBuilder->build();
|
||||
$notification = $notificationBuilder->build();
|
||||
$data = $dataBuilder->build();
|
||||
|
||||
// You must change it to get your tokens
|
||||
$tokens = MYDATABASE::pluck('fcm_token')->toArray();
|
||||
|
||||
$downstreamResponse = FCM::sendTo($tokens, $option, $notification, $data);
|
||||
|
||||
$downstreamResponse->numberSuccess();
|
||||
$downstreamResponse->numberFailure();
|
||||
$downstreamResponse->numberModification();
|
||||
|
||||
// return Array - you must remove all this tokens in your database
|
||||
$downstreamResponse->tokensToDelete();
|
||||
|
||||
// return Array (key : oldToken, value : new token - you must change the token in your database)
|
||||
$downstreamResponse->tokensToModify();
|
||||
|
||||
// return Array - you should try to resend the message to the tokens in the array
|
||||
$downstreamResponse->tokensToRetry();
|
||||
|
||||
// return Array (key:token, value:error) - in production you should remove from your database the tokens present in this array
|
||||
$downstreamResponse->tokensWithError();
|
||||
```
|
||||
|
||||
> Kindly refer [Downstream message error response codes](https://firebase.google.com/docs/cloud-messaging/http-server-ref#error-codes) documentation for more information.
|
||||
|
||||
### Topics Messages
|
||||
|
||||
A topics message is a notification message, data message, or both, that you send to all the devices registered to this topic.
|
||||
|
||||
> Note: Topic names must be managed by your app and known by your server. The Laravel-FCM package or fcm doesn't provide an easy way to do that.
|
||||
|
||||
The following use statement is required for the examples below:
|
||||
|
||||
```php
|
||||
use LaravelFCM\Message\Topics;
|
||||
```
|
||||
|
||||
#### Sending a Message to a Topic
|
||||
|
||||
```php
|
||||
$notificationBuilder = new PayloadNotificationBuilder('my title');
|
||||
$notificationBuilder->setBody('Hello world')
|
||||
->setSound('default');
|
||||
|
||||
$notification = $notificationBuilder->build();
|
||||
|
||||
$topic = new Topics();
|
||||
$topic->topic('news');
|
||||
|
||||
$topicResponse = FCM::sendToTopic($topic, null, $notification, null);
|
||||
|
||||
$topicResponse->isSuccess();
|
||||
$topicResponse->shouldRetry();
|
||||
$topicResponse->error();
|
||||
```
|
||||
|
||||
#### Sending a Message to Multiple Topics
|
||||
|
||||
It sends notification to devices registered at the following topics:
|
||||
|
||||
- news and economic
|
||||
- news and cultural
|
||||
|
||||
> Note : Conditions for topics support two operators per expression
|
||||
|
||||
```php
|
||||
$notificationBuilder = new PayloadNotificationBuilder('my title');
|
||||
$notificationBuilder->setBody('Hello world')
|
||||
->setSound('default');
|
||||
|
||||
$notification = $notificationBuilder->build();
|
||||
|
||||
$topic = new Topics();
|
||||
$topic->topic('news')->andTopic(function($condition) {
|
||||
|
||||
$condition->topic('economic')->orTopic('cultural');
|
||||
|
||||
});
|
||||
|
||||
$topicResponse = FCM::sendToTopic($topic, null, $notification, null);
|
||||
|
||||
$topicResponse->isSuccess();
|
||||
$topicResponse->shouldRetry();
|
||||
$topicResponse->error());
|
||||
|
||||
```
|
||||
|
||||
### Group Messages
|
||||
|
||||
#### Sending a Notification to a Group
|
||||
|
||||
```php
|
||||
$notificationKey = ['a_notification_key'];
|
||||
|
||||
|
||||
$notificationBuilder = new PayloadNotificationBuilder('my title');
|
||||
$notificationBuilder->setBody('Hello world')
|
||||
->setSound('default');
|
||||
|
||||
$notification = $notificationBuilder->build();
|
||||
|
||||
|
||||
$groupResponse = FCM::sendToGroup($notificationKey, null, $notification, null);
|
||||
|
||||
$groupResponse->numberSuccess();
|
||||
$groupResponse->numberFailure();
|
||||
$groupResponse->tokensFailed();
|
||||
```
|
||||
|
||||
|
||||
#### Creating a Group
|
||||
|
||||
```php
|
||||
$tokens = ['a_registration_id_at_add_to_group'];
|
||||
$groupName = "a_group";
|
||||
$notificationKey
|
||||
|
||||
// Save notification key in your database you must use it to send messages or for managing this group
|
||||
$notification_key = FCMGroup::createGroup($groupName, $tokens);
|
||||
```
|
||||
|
||||
#### Adding Devices to a Group
|
||||
|
||||
```php
|
||||
$tokens = ['a_registration_id_at_add_to_the_new_group'];
|
||||
$groupName = "a_group";
|
||||
$notificationKey = "notification_key_received_when_group_was_created";
|
||||
|
||||
$key = FCMGroup::addToGroup($groupName, $notificationKey, $tokens);
|
||||
```
|
||||
|
||||
#### Deleting Devices from a Group
|
||||
|
||||
> Note if all devices are removed from the group, the group is automatically removed in "fcm".
|
||||
|
||||
```php
|
||||
$tokens = ['a_registration_id_at_remove_from_the_group'];
|
||||
$groupName = "a_group";
|
||||
$notificationKey = "notification_key_received_when_group_was_created";
|
||||
|
||||
$key = FCMGroup::removeFromGroup($groupName, $notificationKey, $tokens);
|
||||
```
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
Laravel-FCM supports options based on the options of Firebase Cloud Messaging. These options can help you to define the specificity of your notification.
|
||||
|
||||
You can construct an option as follows:
|
||||
|
||||
```php
|
||||
$optionsBuilder = new OptionsBuilder();
|
||||
|
||||
$optionsBuilder->setTimeToLive(42*60)
|
||||
->setCollapseKey('a_collapse_key');
|
||||
|
||||
$options = $optionsBuilder->build();
|
||||
```
|
||||
|
||||
## Notification Messages
|
||||
|
||||
Notification payload is used to send a notification, the behaviour is defined by the App State and the OS of the receptor device.
|
||||
|
||||
**Notification messages are delivered to the notification tray when the app is in the background.** For apps in the foreground, messages are handled by these callbacks:
|
||||
|
||||
- didReceiveRemoteNotification: on iOS
|
||||
- onMessageReceived() on Android. The notification key in the data bundle contains the notification.
|
||||
|
||||
See the [official documentation](https://firebase.google.com/docs/cloud-messaging/concept-options#notifications).
|
||||
|
||||
|
||||
```php
|
||||
$notificationBuilder = new PayloadNotificationBuilder();
|
||||
$notificationBuilder->setTitle('title')
|
||||
->setBody('body')
|
||||
->setSound('sound')
|
||||
->setBadge('badge');
|
||||
|
||||
$notification = $notificationBuilder->build();
|
||||
```
|
||||
|
||||
## Data Messages
|
||||
|
||||
Set the data key with your custom key-value pairs to send a data payload to the client app. Data messages can have a 4KB maximum payload.
|
||||
|
||||
- **iOS**, FCM stores the message and delivers it **only when the app is in the foreground** and has established a FCM connection.
|
||||
- **Android**, a client app receives a data message in onMessageReceived() and can handle the key-value pairs accordingly.
|
||||
|
||||
See the [official documentation](https://firebase.google.com/docs/cloud-messaging/concept-options#data_messages).
|
||||
|
||||
|
||||
```php
|
||||
$dataBuilder = new PayloadDataBuilder();
|
||||
$dataBuilder->addData([
|
||||
'data_1' => 'first_data'
|
||||
]);
|
||||
|
||||
$data = $dataBuilder->build();
|
||||
```
|
||||
|
||||
## Notification & Data Messages
|
||||
|
||||
App behavior when receiving messages that include both notification and data payloads depends on whether the app is in the background or the foreground—essentially, whether or not it is active at the time of receipt ([source](https://firebase.google.com/docs/cloud-messaging/concept-options#messages-with-both-notification-and-data-payloads)).
|
||||
|
||||
- **Background**, apps receive notification payload in the notification tray, and only handle the data payload when the user taps on the notification.
|
||||
- **Foreground**, your app receives a message object with both payloads available.
|
||||
|
||||
|
||||
## Topics
|
||||
|
||||
For topics message, Laravel-FCM offers an easy to use api which abstract firebase conditions. To make the condition given for example in the firebase official documentation it must be done with Laravel-FCM like below:
|
||||
|
||||
**Official documentation condition**
|
||||
|
||||
```
|
||||
'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)
|
||||
```
|
||||
|
||||
```php
|
||||
$topics = new Topics();
|
||||
|
||||
$topics->topic('TopicA')
|
||||
->andTopic(function($condition) {
|
||||
$condition->topic('TopicB')->orTopic('TopicC');
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
For integration testing, you can mock the responses with mockery and Mocks provided by the package.
|
||||
|
||||
There are 3 kinds of "MockResponse" given by the package:
|
||||
|
||||
- MockDownstreamResponse
|
||||
- MockGroupResponse
|
||||
- MockTopicResponse
|
||||
|
||||
You can mock the FCM call as in the following example:
|
||||
|
||||
```php
|
||||
$numberSucess = 2;
|
||||
$mockResponse = new \LaravelFCM\Mocks\MockDownstreamResponse(numberSucess);
|
||||
|
||||
$mockResponse->addTokenToDelete('token_to_delete');
|
||||
$mockResponse->addTokenToModify('token_to_modify', 'token_modified');
|
||||
$mockResponse->setMissingToken(true);
|
||||
|
||||
$sender = Mockery::mock(\LaravelFCM\Sender\FCMSender::class);
|
||||
$sender->shouldReceive('sendTo')->once()->andReturn($mockResponse);
|
||||
|
||||
$this->app->singleton('fcm.sender', function($app) use($sender) {
|
||||
return $sender;
|
||||
});
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
||||
You can find more documentation about the API in the [API reference](./doc/Readme.md).
|
||||
|
||||
|
||||
## Licence
|
||||
|
||||
This library is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
|
||||
|
||||
Some of this documentation is coming from the official documentation. You can find it completely on the [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/) Website.
|
49
vendor/brozot/laravel-fcm/composer.json
vendored
49
vendor/brozot/laravel-fcm/composer.json
vendored
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"name": "brozot/laravel-fcm",
|
||||
"description": "Laravel / Lumen package for Firebase Cloud Messaging ",
|
||||
"keywords": ["laravel", "lumen", "firebase", "notification", "push", "fcm", "firebase cloud messaging"],
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Brosy",
|
||||
"email": "nicolas.brosy@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"illuminate/support": "5.*|^6",
|
||||
"guzzlehttp/guzzle": "~6.0",
|
||||
"monolog/monolog": "^1.12|^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery" : "0.9.*",
|
||||
"phpunit/phpunit" : "4.7.*",
|
||||
"satooshi/php-coveralls": "dev-master",
|
||||
"laravel/laravel": "5.2.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelFCM\\": "src/",
|
||||
"LaravelFCM\\Mocks\\": "tests/mocks"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"classmap": [
|
||||
"tests/"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"LaravelFCM\\FCMServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"FCM": "LaravelFCM\\Facades\\FCM",
|
||||
"FCMGroup": "LaravelFCM\\Facades\\FCMGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3528
vendor/brozot/laravel-fcm/composer.lock
generated
vendored
3528
vendor/brozot/laravel-fcm/composer.lock
generated
vendored
File diff suppressed because it is too large
Load Diff
14
vendor/brozot/laravel-fcm/config/fcm.php
vendored
14
vendor/brozot/laravel-fcm/config/fcm.php
vendored
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'driver' => env('FCM_PROTOCOL', 'http'),
|
||||
'log_enabled' => false,
|
||||
|
||||
'http' => [
|
||||
'server_key' => env('FCM_SERVER_KEY', 'Your FCM server key'),
|
||||
'sender_id' => env('FCM_SENDER_ID', 'Your sender id'),
|
||||
'server_send_url' => 'https://fcm.googleapis.com/fcm/send',
|
||||
'server_group_url' => 'https://android.googleapis.com/gcm/notification',
|
||||
'timeout' => 30.0, // in second
|
||||
],
|
||||
];
|
@@ -1,19 +0,0 @@
|
||||
LaravelFCM\Message\Exceptions\InvalidOptionsException
|
||||
===============
|
||||
|
||||
Class InvalidOptionsException
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: InvalidOptionsException
|
||||
* Namespace: LaravelFCM\Message\Exceptions
|
||||
* Parent class: Exception
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,19 +0,0 @@
|
||||
LaravelFCM\Message\Exceptions\NoTopicProvidedException
|
||||
===============
|
||||
|
||||
Class NoTopicProvidedException
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: NoTopicProvidedException
|
||||
* Namespace: LaravelFCM\Message\Exceptions
|
||||
* Parent class: Exception
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,49 +0,0 @@
|
||||
LaravelFCM\Message\Options
|
||||
===============
|
||||
|
||||
Class Options
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: Options
|
||||
* Namespace: LaravelFCM\Message
|
||||
* This class implements: Illuminate\Contracts\Support\Arrayable
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Message\Options::__construct(\LaravelFCM\Message\OptionsBuilder $builder)
|
||||
|
||||
Options constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $builder **[LaravelFCM\Message\OptionsBuilder](LaravelFCM-Message-OptionsBuilder.md)**
|
||||
|
||||
|
||||
|
||||
### toArray
|
||||
|
||||
array LaravelFCM\Message\Options::toArray()
|
||||
|
||||
Transform Option to array
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,241 +0,0 @@
|
||||
LaravelFCM\Message\OptionsBuilder
|
||||
===============
|
||||
|
||||
Builder for creation of options used by FCM
|
||||
|
||||
Class OptionsBuilder
|
||||
|
||||
|
||||
* Class name: OptionsBuilder
|
||||
* Namespace: LaravelFCM\Message
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### setCollapseKey
|
||||
|
||||
\LaravelFCM\Message\OptionsBuilder LaravelFCM\Message\OptionsBuilder::setCollapseKey(String $collapseKey)
|
||||
|
||||
This parameter identifies a group of messages
|
||||
A maximum of 4 different collapse keys is allowed at any given time.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $collapseKey **String**
|
||||
|
||||
|
||||
|
||||
### setPriority
|
||||
|
||||
\LaravelFCM\Message\OptionsBuilder LaravelFCM\Message\OptionsBuilder::setPriority(String $priority)
|
||||
|
||||
Sets the priority of the message. Valid values are "normal" and "high."
|
||||
By default, messages are sent with normal priority
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $priority **String**
|
||||
|
||||
|
||||
|
||||
### setContentAvailable
|
||||
|
||||
\LaravelFCM\Message\OptionsBuilder LaravelFCM\Message\OptionsBuilder::setContentAvailable(boolean $contentAvailable)
|
||||
|
||||
support only Android and Ios
|
||||
|
||||
An inactive client app is awoken.
|
||||
On iOS, use this field to represent content-available in the APNS payload.
|
||||
On Android, data messages wake the app by default.
|
||||
On Chrome, currently not supported.
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $contentAvailable **boolean**
|
||||
|
||||
|
||||
|
||||
### setDelayWhileIdle
|
||||
|
||||
\LaravelFCM\Message\OptionsBuilder LaravelFCM\Message\OptionsBuilder::setDelayWhileIdle(boolean $delayWhileIdle)
|
||||
|
||||
When this parameter is set to true, it indicates that the message should not be sent until the device becomes active.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $delayWhileIdle **boolean**
|
||||
|
||||
|
||||
|
||||
### setTimeToLive
|
||||
|
||||
\LaravelFCM\Message\OptionsBuilder LaravelFCM\Message\OptionsBuilder::setTimeToLive(integer $timeToLive)
|
||||
|
||||
This parameter specifies how long the message should be kept in FCM storage if the device is offline
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $timeToLive **integer** - <p>(in second) min:0 max:2419200</p>
|
||||
|
||||
|
||||
|
||||
### setRestrictedPackageName
|
||||
|
||||
\LaravelFCM\Message\OptionsBuilder LaravelFCM\Message\OptionsBuilder::setRestrictedPackageName(string $restrictedPackageName)
|
||||
|
||||
This parameter specifies the package name of the application where the registration tokens must match in order to receive the message.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $restrictedPackageName **string**
|
||||
|
||||
|
||||
|
||||
### setDryRun
|
||||
|
||||
\LaravelFCM\Message\OptionsBuilder LaravelFCM\Message\OptionsBuilder::setDryRun(boolean $isDryRun)
|
||||
|
||||
This parameter, when set to true, allows developers to test a request without actually sending a message.
|
||||
|
||||
It should only be used for the development
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $isDryRun **boolean**
|
||||
|
||||
|
||||
|
||||
### getCollapseKey
|
||||
|
||||
null|string LaravelFCM\Message\OptionsBuilder::getCollapseKey()
|
||||
|
||||
Get the collapseKey
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getPriority
|
||||
|
||||
null|string LaravelFCM\Message\OptionsBuilder::getPriority()
|
||||
|
||||
Get the priority
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### isContentAvailable
|
||||
|
||||
boolean LaravelFCM\Message\OptionsBuilder::isContentAvailable()
|
||||
|
||||
is content available
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### isDelayWhileIdle
|
||||
|
||||
boolean LaravelFCM\Message\OptionsBuilder::isDelayWhileIdle()
|
||||
|
||||
is delay white idle
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getTimeToLive
|
||||
|
||||
null|integer LaravelFCM\Message\OptionsBuilder::getTimeToLive()
|
||||
|
||||
get time to live
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getRestrictedPackageName
|
||||
|
||||
null|string LaravelFCM\Message\OptionsBuilder::getRestrictedPackageName()
|
||||
|
||||
get restricted package name
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### isDryRun
|
||||
|
||||
boolean LaravelFCM\Message\OptionsBuilder::isDryRun()
|
||||
|
||||
is dry run
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### build
|
||||
|
||||
\LaravelFCM\Message\Options LaravelFCM\Message\OptionsBuilder::build()
|
||||
|
||||
build an instance of Options
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,69 +0,0 @@
|
||||
LaravelFCM\Message\OptionsPriorities
|
||||
===============
|
||||
|
||||
Class OptionsPriorities
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: OptionsPriorities
|
||||
* Namespace: LaravelFCM\Message
|
||||
|
||||
|
||||
|
||||
Constants
|
||||
----------
|
||||
|
||||
|
||||
### high
|
||||
|
||||
const high = "high"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### normal
|
||||
|
||||
const normal = "normal"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### getPriorities
|
||||
|
||||
array LaravelFCM\Message\OptionsPriorities::getPriorities()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is **static**.
|
||||
|
||||
|
||||
|
||||
|
||||
### isValid
|
||||
|
||||
boolean LaravelFCM\Message\OptionsPriorities::isValid($priority)
|
||||
|
||||
check if this priority is supported by fcm
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is **static**.
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $priority **mixed**
|
||||
|
||||
|
@@ -1,49 +0,0 @@
|
||||
LaravelFCM\Message\PayloadData
|
||||
===============
|
||||
|
||||
Class PayloadData
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: PayloadData
|
||||
* Namespace: LaravelFCM\Message
|
||||
* This class implements: Illuminate\Contracts\Support\Arrayable
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Message\PayloadData::__construct(\LaravelFCM\Message\PayloadDataBuilder $builder)
|
||||
|
||||
PayloadData constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $builder **[LaravelFCM\Message\PayloadDataBuilder](LaravelFCM-Message-PayloadDataBuilder.md)**
|
||||
|
||||
|
||||
|
||||
### toArray
|
||||
|
||||
array LaravelFCM\Message\PayloadData::toArray()
|
||||
|
||||
Transform payloadData to array
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,91 +0,0 @@
|
||||
LaravelFCM\Message\PayloadDataBuilder
|
||||
===============
|
||||
|
||||
Class PayloadDataBuilder
|
||||
|
||||
Official google documentation :
|
||||
|
||||
|
||||
* Class name: PayloadDataBuilder
|
||||
* Namespace: LaravelFCM\Message
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### addData
|
||||
|
||||
\LaravelFCM\Message\PayloadDataBuilder LaravelFCM\Message\PayloadDataBuilder::addData(array $data)
|
||||
|
||||
add data to existing data
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $data **array**
|
||||
|
||||
|
||||
|
||||
### setData
|
||||
|
||||
\LaravelFCM\Message\PayloadDataBuilder LaravelFCM\Message\PayloadDataBuilder::setData(array $data)
|
||||
|
||||
erase data with new data
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $data **array**
|
||||
|
||||
|
||||
|
||||
### removeAllData
|
||||
|
||||
mixed LaravelFCM\Message\PayloadDataBuilder::removeAllData()
|
||||
|
||||
Remove all data
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getData
|
||||
|
||||
array LaravelFCM\Message\PayloadDataBuilder::getData()
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### build
|
||||
|
||||
\LaravelFCM\Message\PayloadData LaravelFCM\Message\PayloadDataBuilder::build()
|
||||
|
||||
generate a PayloadData
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,49 +0,0 @@
|
||||
LaravelFCM\Message\PayloadNotification
|
||||
===============
|
||||
|
||||
Class PayloadNotification
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: PayloadNotification
|
||||
* Namespace: LaravelFCM\Message
|
||||
* This class implements: Illuminate\Contracts\Support\Arrayable
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Message\PayloadNotification::__construct(\LaravelFCM\Message\PayloadNotificationBuilder $builder)
|
||||
|
||||
PayloadNotification constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $builder **[LaravelFCM\Message\PayloadNotificationBuilder](LaravelFCM-Message-PayloadNotificationBuilder.md)**
|
||||
|
||||
|
||||
|
||||
### toArray
|
||||
|
||||
array LaravelFCM\Message\PayloadNotification::toArray()
|
||||
|
||||
convert PayloadNotification to array
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,400 +0,0 @@
|
||||
LaravelFCM\Message\PayloadNotificationBuilder
|
||||
===============
|
||||
|
||||
Class PayloadNotificationBuilder
|
||||
|
||||
Official google documentation :
|
||||
|
||||
|
||||
* Class name: PayloadNotificationBuilder
|
||||
* Namespace: LaravelFCM\Message
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Message\PayloadNotificationBuilder::__construct(String $title)
|
||||
|
||||
Title must be present on android notification and ios (watch) notification
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $title **String**
|
||||
|
||||
|
||||
|
||||
### setTitle
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setTitle(String $title)
|
||||
|
||||
Indicates notification title. This field is not visible on iOS phones and tablets.
|
||||
|
||||
but it is required for android
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $title **String**
|
||||
|
||||
|
||||
|
||||
### setBody
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setBody(String $body)
|
||||
|
||||
Indicates notification body text.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $body **String**
|
||||
|
||||
|
||||
|
||||
### setIcon
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setIcon(String $icon)
|
||||
|
||||
Supported Android
|
||||
Indicates notification icon. example : Sets value to myicon for drawable resource myicon.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $icon **String**
|
||||
|
||||
|
||||
|
||||
### setSound
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setSound(String $sound)
|
||||
|
||||
Indicates a sound to play when the device receives a notification.
|
||||
|
||||
Supports default or the filename of a sound resource bundled in the app.
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $sound **String**
|
||||
|
||||
|
||||
|
||||
### setBadge
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setBadge(String $badge)
|
||||
|
||||
Supported Ios
|
||||
|
||||
Indicates the badge on the client app home icon.
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $badge **String**
|
||||
|
||||
|
||||
|
||||
### setTag
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setTag(String $tag)
|
||||
|
||||
Supported Android
|
||||
|
||||
Indicates whether each notification results in a new entry in the notification drawer on Android.
|
||||
If not set, each request creates a new notification.
|
||||
If set, and a notification with the same tag is already being shown, the new notification replaces the existing one in the notification drawer.
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $tag **String**
|
||||
|
||||
|
||||
|
||||
### setColor
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setColor(String $color)
|
||||
|
||||
Supported Android
|
||||
|
||||
Indicates color of the icon, expressed in #rrggbb format
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $color **String**
|
||||
|
||||
|
||||
|
||||
### setClickAction
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setClickAction(String $action)
|
||||
|
||||
Indicates the action associated with a user click on the notification
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $action **String**
|
||||
|
||||
|
||||
|
||||
### setTitleLocationKey
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setTitleLocationKey(String $titleKey)
|
||||
|
||||
Indicates the key to the title string for localization.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $titleKey **String**
|
||||
|
||||
|
||||
|
||||
### setTitleLocationArgs
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setTitleLocationArgs(mixed $titleArgs)
|
||||
|
||||
Indicates the string value to replace format specifiers in the title string for localization.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $titleArgs **mixed**
|
||||
|
||||
|
||||
|
||||
### setBodyLocationKey
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setBodyLocationKey(String $bodyKey)
|
||||
|
||||
Indicates the key to the body string for localization.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $bodyKey **String**
|
||||
|
||||
|
||||
|
||||
### setBodyLocationArgs
|
||||
|
||||
\LaravelFCM\Message\PayloadNotificationBuilder LaravelFCM\Message\PayloadNotificationBuilder::setBodyLocationArgs(mixed $bodyArgs)
|
||||
|
||||
Indicates the string value to replace format specifiers in the body string for localization.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $bodyArgs **mixed**
|
||||
|
||||
|
||||
|
||||
### getTitle
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getTitle()
|
||||
|
||||
Get title
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getBody
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getBody()
|
||||
|
||||
Get body
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getIcon
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getIcon()
|
||||
|
||||
Get Icon
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getSound
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getSound()
|
||||
|
||||
Get Sound
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getBadge
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getBadge()
|
||||
|
||||
Get Badge
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getTag
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getTag()
|
||||
|
||||
Get Tag
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getColor
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getColor()
|
||||
|
||||
Get Color
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getClickAction
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getClickAction()
|
||||
|
||||
Get ClickAction
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getBodyLocationKey
|
||||
|
||||
null|String LaravelFCM\Message\PayloadNotificationBuilder::getBodyLocationKey()
|
||||
|
||||
Get BodyLocationKey
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getBodyLocationArgs
|
||||
|
||||
null|String|array LaravelFCM\Message\PayloadNotificationBuilder::getBodyLocationArgs()
|
||||
|
||||
Get BodyLocationArgs
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getTitleLocationKey
|
||||
|
||||
string LaravelFCM\Message\PayloadNotificationBuilder::getTitleLocationKey()
|
||||
|
||||
Get TitleLocationKey
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getTitleLocationArgs
|
||||
|
||||
null|String|array LaravelFCM\Message\PayloadNotificationBuilder::getTitleLocationArgs()
|
||||
|
||||
GetTitleLocationArgs
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### build
|
||||
|
||||
\LaravelFCM\Message\PayloadNotification LaravelFCM\Message\PayloadNotificationBuilder::build()
|
||||
|
||||
Build an PayloadNotification
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,134 +0,0 @@
|
||||
LaravelFCM\Message\Topics
|
||||
===============
|
||||
|
||||
Class Topics
|
||||
|
||||
Create topic or a topic condition
|
||||
|
||||
|
||||
* Class name: Topics
|
||||
* Namespace: LaravelFCM\Message
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### topic
|
||||
|
||||
\LaravelFCM\Message\Topics LaravelFCM\Message\Topics::topic(string $first)
|
||||
|
||||
Add a topic, this method should be called before any conditional topic
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $first **string** - <p>topicName</p>
|
||||
|
||||
|
||||
|
||||
### orTopic
|
||||
|
||||
\LaravelFCM\Message\Topics LaravelFCM\Message\Topics::orTopic(string|\Closure $first)
|
||||
|
||||
Add a or condition to the precedent topic set
|
||||
|
||||
Parenthesis is a closure
|
||||
|
||||
Equivalent of this: **'TopicA' in topic' || 'TopicB' in topics**
|
||||
|
||||
```
|
||||
$topic = new Topics();
|
||||
$topic->topic('TopicA')
|
||||
->orTopic('TopicB');
|
||||
```
|
||||
|
||||
Equivalent of this: **'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)**
|
||||
|
||||
```
|
||||
$topic = new Topics();
|
||||
$topic->topic('TopicA')
|
||||
->andTopic(function($condition) {
|
||||
$condition->topic('TopicB')->orTopic('TopicC');
|
||||
});
|
||||
```
|
||||
|
||||
> Note: Only two operators per expression are supported by fcm
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $first **string|Closure** - <p>topicName or closure</p>
|
||||
|
||||
|
||||
|
||||
### andTopic
|
||||
|
||||
\LaravelFCM\Message\Topics LaravelFCM\Message\Topics::andTopic(string|\Closure $first)
|
||||
|
||||
Add a and condition to the precedent topic set
|
||||
|
||||
Parenthesis is a closure
|
||||
|
||||
Equivalent of this: **'TopicA' in topic' && 'TopicB' in topics**
|
||||
|
||||
```
|
||||
$topic = new Topics();
|
||||
$topic->topic('TopicA')
|
||||
->anTopic('TopicB');
|
||||
```
|
||||
|
||||
Equivalent of this: **'TopicA' in topics || ('TopicB' in topics && 'TopicC' in topics)**
|
||||
|
||||
```
|
||||
$topic = new Topics();
|
||||
$topic->topic('TopicA')
|
||||
->orTopic(function($condition) {
|
||||
$condition->topic('TopicB')->AndTopic('TopicC');
|
||||
});
|
||||
```
|
||||
|
||||
> Note: Only two operators per expression are supported by fcm
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $first **string|Closure** - <p>topicName or closure</p>
|
||||
|
||||
|
||||
|
||||
### build
|
||||
|
||||
array|string LaravelFCM\Message\Topics::build()
|
||||
|
||||
Transform to array
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### hasOnlyOneTopic
|
||||
|
||||
boolean LaravelFCM\Message\Topics::hasOnlyOneTopic()
|
||||
|
||||
Check if only one topic was set
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,118 +0,0 @@
|
||||
LaravelFCM\Response\BaseResponse
|
||||
===============
|
||||
|
||||
Class BaseResponse
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: BaseResponse
|
||||
* Namespace: LaravelFCM\Response
|
||||
* This is an **abstract** class
|
||||
|
||||
|
||||
|
||||
Constants
|
||||
----------
|
||||
|
||||
|
||||
### SUCCESS
|
||||
|
||||
const SUCCESS = 'success'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### FAILURE
|
||||
|
||||
const FAILURE = 'failure'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### ERROR
|
||||
|
||||
const ERROR = "error"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### MESSAGE_ID
|
||||
|
||||
const MESSAGE_ID = "message_id"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::__construct(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
BaseResponse constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
||||
|
||||
### isJsonResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::isJsonResponse(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
Check if the response given by fcm is parsable
|
||||
|
||||
|
||||
|
||||
* Visibility: **private**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
||||
|
||||
### parseResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::parseResponse(array $responseInJson)
|
||||
|
||||
parse the response
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $responseInJson **array**
|
||||
|
||||
|
||||
|
||||
### logResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::logResponse()
|
||||
|
||||
Log the response
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
|
||||
|
||||
|
@@ -1,338 +0,0 @@
|
||||
LaravelFCM\Response\DownstreamResponse
|
||||
===============
|
||||
|
||||
Class DownstreamResponse
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: DownstreamResponse
|
||||
* Namespace: LaravelFCM\Response
|
||||
* Parent class: [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
* This class implements: [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
Constants
|
||||
----------
|
||||
|
||||
|
||||
### MULTICAST_ID
|
||||
|
||||
const MULTICAST_ID = 'multicast_id'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### CANONICAL_IDS
|
||||
|
||||
const CANONICAL_IDS = "canonical_ids"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### RESULTS
|
||||
|
||||
const RESULTS = "results"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### MISSING_REGISTRATION
|
||||
|
||||
const MISSING_REGISTRATION = "MissingRegistration"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### MESSAGE_ID
|
||||
|
||||
const MESSAGE_ID = "message_id"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### REGISTRATION_ID
|
||||
|
||||
const REGISTRATION_ID = "registration_id"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### NOT_REGISTERED
|
||||
|
||||
const NOT_REGISTERED = "NotRegistered"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### INVALID_REGISTRATION
|
||||
|
||||
const INVALID_REGISTRATION = "InvalidRegistration"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### UNAVAILABLE
|
||||
|
||||
const UNAVAILABLE = "Unavailable"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### DEVICE_MESSAGE_RATE_EXCEEDED
|
||||
|
||||
const DEVICE_MESSAGE_RATE_EXCEEDED = "DeviceMessageRateExceeded"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### INTERNAL_SERVER_ERROR
|
||||
|
||||
const INTERNAL_SERVER_ERROR = "InternalServerError"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### SUCCESS
|
||||
|
||||
const SUCCESS = 'success'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### FAILURE
|
||||
|
||||
const FAILURE = 'failure'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### ERROR
|
||||
|
||||
const ERROR = "error"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::__construct(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
BaseResponse constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
||||
|
||||
### parseResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::parseResponse(array $responseInJson)
|
||||
|
||||
parse the response
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $responseInJson **array**
|
||||
|
||||
|
||||
|
||||
### merge
|
||||
|
||||
mixed LaravelFCM\Response\DownstreamResponseContract::merge(\LaravelFCM\Response\DownstreamResponse $response)
|
||||
|
||||
Merge two response
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **[LaravelFCM\Response\DownstreamResponse](LaravelFCM-Response-DownstreamResponse.md)**
|
||||
|
||||
|
||||
|
||||
### numberSuccess
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberSuccess()
|
||||
|
||||
Get the number of device reached with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### numberFailure
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberFailure()
|
||||
|
||||
Get the number of device which thrown an error
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### numberModification
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberModification()
|
||||
|
||||
Get the number of device that you need to modify their token
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensToDelete
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToDelete()
|
||||
|
||||
get token to delete
|
||||
|
||||
remove all tokens returned by this method in your database
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensToModify
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToModify()
|
||||
|
||||
get token to modify
|
||||
|
||||
key: oldToken
|
||||
value: new token
|
||||
|
||||
find the old token in your database and replace it with the new one
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensToRetry
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToRetry()
|
||||
|
||||
Get tokens that you should resend using exponential backoof
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensWithError
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensWithError()
|
||||
|
||||
Get tokens that thrown an error
|
||||
|
||||
key : token
|
||||
value : error
|
||||
|
||||
In production, remove these tokens from you database
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### hasMissingToken
|
||||
|
||||
boolean LaravelFCM\Response\DownstreamResponseContract::hasMissingToken()
|
||||
|
||||
check if missing tokens was given to the request
|
||||
If true, remove all the empty token in your database
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### isJsonResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::isJsonResponse(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
Check if the response given by fcm is parsable
|
||||
|
||||
|
||||
|
||||
* Visibility: **private**
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
||||
|
||||
### logResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::logResponse()
|
||||
|
||||
Log the response
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
|
@@ -1,147 +0,0 @@
|
||||
LaravelFCM\Response\DownstreamResponseContract
|
||||
===============
|
||||
|
||||
Interface DownstreamResponseContract
|
||||
|
||||
|
||||
|
||||
|
||||
* Interface name: DownstreamResponseContract
|
||||
* Namespace: LaravelFCM\Response
|
||||
* This is an **interface**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### merge
|
||||
|
||||
mixed LaravelFCM\Response\DownstreamResponseContract::merge(\LaravelFCM\Response\DownstreamResponse $response)
|
||||
|
||||
Merge two response
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **[LaravelFCM\Response\DownstreamResponse](LaravelFCM-Response-DownstreamResponse.md)**
|
||||
|
||||
|
||||
|
||||
### numberSuccess
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberSuccess()
|
||||
|
||||
Get the number of device reached with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### numberFailure
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberFailure()
|
||||
|
||||
Get the number of device which thrown an error
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### numberModification
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberModification()
|
||||
|
||||
Get the number of device that you need to modify their token
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensToDelete
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToDelete()
|
||||
|
||||
get token to delete
|
||||
|
||||
remove all tokens returned by this method in your database
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensToModify
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToModify()
|
||||
|
||||
get token to modify
|
||||
|
||||
key: oldToken
|
||||
value: new token
|
||||
|
||||
find the old token in your database and replace it with the new one
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensToRetry
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToRetry()
|
||||
|
||||
Get tokens that you should resend using exponential backoof
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensWithError
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensWithError()
|
||||
|
||||
Get tokens that thrown an error
|
||||
|
||||
key : token
|
||||
value : error
|
||||
|
||||
In production, remove these tokens from you database
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### hasMissingToken
|
||||
|
||||
boolean LaravelFCM\Response\DownstreamResponseContract::hasMissingToken()
|
||||
|
||||
check if missing tokens was given to the request
|
||||
If true, remove all the empty token in your database
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,37 +0,0 @@
|
||||
LaravelFCM\Response\Exceptions\InvalidRequestException
|
||||
===============
|
||||
|
||||
Class InvalidRequestException
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: InvalidRequestException
|
||||
* Namespace: LaravelFCM\Response\Exceptions
|
||||
* Parent class: Exception
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Response\Exceptions\InvalidRequestException::__construct(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
InvalidRequestException constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
@@ -1,50 +0,0 @@
|
||||
LaravelFCM\Response\Exceptions\ServerResponseException
|
||||
===============
|
||||
|
||||
Class ServerResponseException
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: ServerResponseException
|
||||
* Namespace: LaravelFCM\Response\Exceptions
|
||||
* Parent class: Exception
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
|
||||
### $retryAfter
|
||||
|
||||
public integer $retryAfter
|
||||
|
||||
retry after
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Response\Exceptions\ServerResponseException::__construct(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
ServerResponseException constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
@@ -1,37 +0,0 @@
|
||||
LaravelFCM\Response\Exceptions\UnauthorizedRequestException
|
||||
===============
|
||||
|
||||
Class UnauthorizedRequestException
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: UnauthorizedRequestException
|
||||
* Namespace: LaravelFCM\Response\Exceptions
|
||||
* Parent class: Exception
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Response\Exceptions\UnauthorizedRequestException::__construct(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
UnauthorizedRequestException constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
@@ -1,172 +0,0 @@
|
||||
LaravelFCM\Response\GroupResponse
|
||||
===============
|
||||
|
||||
Class GroupResponse
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: GroupResponse
|
||||
* Namespace: LaravelFCM\Response
|
||||
* Parent class: [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
* This class implements: [LaravelFCM\Response\GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
|
||||
|
||||
Constants
|
||||
----------
|
||||
|
||||
|
||||
### FAILED_REGISTRATION_IDS
|
||||
|
||||
const FAILED_REGISTRATION_IDS = "failed_registration_ids"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### SUCCESS
|
||||
|
||||
const SUCCESS = 'success'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### FAILURE
|
||||
|
||||
const FAILURE = 'failure'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### ERROR
|
||||
|
||||
const ERROR = "error"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### MESSAGE_ID
|
||||
|
||||
const MESSAGE_ID = "message_id"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::__construct(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
BaseResponse constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
||||
|
||||
### parseResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::parseResponse(array $responseInJson)
|
||||
|
||||
parse the response
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $responseInJson **array**
|
||||
|
||||
|
||||
|
||||
### logResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::logResponse()
|
||||
|
||||
Log the response
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### numberSuccess
|
||||
|
||||
integer LaravelFCM\Response\GroupResponseContract::numberSuccess()
|
||||
|
||||
Get the number of device reached with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### numberFailure
|
||||
|
||||
integer LaravelFCM\Response\GroupResponseContract::numberFailure()
|
||||
|
||||
Get the number of device which thrown an error
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensFailed
|
||||
|
||||
array LaravelFCM\Response\GroupResponseContract::tokensFailed()
|
||||
|
||||
Get all token in group that fcm cannot reach
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### isJsonResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::isJsonResponse(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
Check if the response given by fcm is parsable
|
||||
|
||||
|
||||
|
||||
* Visibility: **private**
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
@@ -1,59 +0,0 @@
|
||||
LaravelFCM\Response\GroupResponseContract
|
||||
===============
|
||||
|
||||
Interface GroupResponseContract
|
||||
|
||||
|
||||
|
||||
|
||||
* Interface name: GroupResponseContract
|
||||
* Namespace: LaravelFCM\Response
|
||||
* This is an **interface**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### numberSuccess
|
||||
|
||||
integer LaravelFCM\Response\GroupResponseContract::numberSuccess()
|
||||
|
||||
Get the number of device reached with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### numberFailure
|
||||
|
||||
integer LaravelFCM\Response\GroupResponseContract::numberFailure()
|
||||
|
||||
Get the number of device which thrown an error
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### tokensFailed
|
||||
|
||||
array LaravelFCM\Response\GroupResponseContract::tokensFailed()
|
||||
|
||||
Get all token in group that fcm cannot reach
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,173 +0,0 @@
|
||||
LaravelFCM\Response\TopicResponse
|
||||
===============
|
||||
|
||||
Class TopicResponse
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: TopicResponse
|
||||
* Namespace: LaravelFCM\Response
|
||||
* Parent class: [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
* This class implements: [LaravelFCM\Response\TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
|
||||
|
||||
Constants
|
||||
----------
|
||||
|
||||
|
||||
### LIMIT_RATE_TOPICS_EXCEEDED
|
||||
|
||||
const LIMIT_RATE_TOPICS_EXCEEDED = "TopicsMessageRateExceeded"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### SUCCESS
|
||||
|
||||
const SUCCESS = 'success'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### FAILURE
|
||||
|
||||
const FAILURE = 'failure'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### ERROR
|
||||
|
||||
const ERROR = "error"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### MESSAGE_ID
|
||||
|
||||
const MESSAGE_ID = "message_id"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::__construct(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
BaseResponse constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
||||
|
||||
### parseResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::parseResponse(array $responseInJson)
|
||||
|
||||
parse the response
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $responseInJson **array**
|
||||
|
||||
|
||||
|
||||
### logResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::logResponse()
|
||||
|
||||
Log the response
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### isSuccess
|
||||
|
||||
boolean LaravelFCM\Response\TopicResponseContract::isSuccess()
|
||||
|
||||
true if topic sent with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### error
|
||||
|
||||
string LaravelFCM\Response\TopicResponseContract::error()
|
||||
|
||||
return error message
|
||||
you should test if it's necessary to resent it
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### shouldRetry
|
||||
|
||||
boolean LaravelFCM\Response\TopicResponseContract::shouldRetry()
|
||||
|
||||
return true if it's necessary resent it using exponential backoff
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### isJsonResponse
|
||||
|
||||
mixed LaravelFCM\Response\BaseResponse::isJsonResponse(\GuzzleHttp\Psr7\Response $response)
|
||||
|
||||
Check if the response given by fcm is parsable
|
||||
|
||||
|
||||
|
||||
* Visibility: **private**
|
||||
* This method is defined by [LaravelFCM\Response\BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **GuzzleHttp\Psr7\Response**
|
||||
|
||||
|
@@ -1,60 +0,0 @@
|
||||
LaravelFCM\Response\TopicResponseContract
|
||||
===============
|
||||
|
||||
Interface TopicResponseContract
|
||||
|
||||
|
||||
|
||||
|
||||
* Interface name: TopicResponseContract
|
||||
* Namespace: LaravelFCM\Response
|
||||
* This is an **interface**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### isSuccess
|
||||
|
||||
boolean LaravelFCM\Response\TopicResponseContract::isSuccess()
|
||||
|
||||
true if topic sent with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### error
|
||||
|
||||
string LaravelFCM\Response\TopicResponseContract::error()
|
||||
|
||||
return error message
|
||||
you should test if it's necessary to resent it
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### shouldRetry
|
||||
|
||||
boolean LaravelFCM\Response\TopicResponseContract::shouldRetry()
|
||||
|
||||
return true if it's necessary resent it using exponential backoff
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
@@ -1,83 +0,0 @@
|
||||
LaravelFCM\Sender\BaseSender
|
||||
===============
|
||||
|
||||
Class BaseSender
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: BaseSender
|
||||
* Namespace: LaravelFCM\Sender
|
||||
* This is an **abstract** class
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
|
||||
### $client
|
||||
|
||||
protected \Illuminate\Foundation\Application $client
|
||||
|
||||
Guzzle Client
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
### $config
|
||||
|
||||
protected array $config
|
||||
|
||||
configuration
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
### $url
|
||||
|
||||
protected mixed $url
|
||||
|
||||
url
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Sender\BaseSender::__construct()
|
||||
|
||||
BaseSender constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
|
||||
|
||||
### getUrl
|
||||
|
||||
string LaravelFCM\Sender\BaseSender::getUrl()
|
||||
|
||||
get the url
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
|
||||
|
||||
|
@@ -1,164 +0,0 @@
|
||||
LaravelFCM\Sender\FCMGroup
|
||||
===============
|
||||
|
||||
Class FCMGroup
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: FCMGroup
|
||||
* Namespace: LaravelFCM\Sender
|
||||
* Parent class: [LaravelFCM\Sender\BaseSender](LaravelFCM-Sender-BaseSender.md)
|
||||
|
||||
|
||||
|
||||
Constants
|
||||
----------
|
||||
|
||||
|
||||
### CREATE
|
||||
|
||||
const CREATE = "create"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### ADD
|
||||
|
||||
const ADD = "add"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### REMOVE
|
||||
|
||||
const REMOVE = "remove"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
|
||||
### $client
|
||||
|
||||
protected \Illuminate\Foundation\Application $client
|
||||
|
||||
Guzzle Client
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
### $config
|
||||
|
||||
protected array $config
|
||||
|
||||
configuration
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
### $url
|
||||
|
||||
protected mixed $url
|
||||
|
||||
url
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### createGroup
|
||||
|
||||
null LaravelFCM\Sender\FCMGroup::createGroup($notificationKeyName, array $registrationIds)
|
||||
|
||||
Create a group
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $notificationKeyName **mixed**
|
||||
* $registrationIds **array**
|
||||
|
||||
|
||||
|
||||
### addToGroup
|
||||
|
||||
null LaravelFCM\Sender\FCMGroup::addToGroup($notificationKeyName, $notificationKey, array $registrationIds)
|
||||
|
||||
add registrationId to a existing group
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $notificationKeyName **mixed**
|
||||
* $notificationKey **mixed**
|
||||
* $registrationIds **array** - <p>registrationIds to add</p>
|
||||
|
||||
|
||||
|
||||
### removeFromGroup
|
||||
|
||||
null LaravelFCM\Sender\FCMGroup::removeFromGroup($notificationKeyName, $notificationKey, array $registeredIds)
|
||||
|
||||
remove registrationId to a existing group
|
||||
|
||||
>Note: if you remove all registrationIds the group is automatically deleted
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $notificationKeyName **mixed**
|
||||
* $notificationKey **mixed**
|
||||
* $registeredIds **array** - <p>registrationIds to remove</p>
|
||||
|
||||
|
||||
|
||||
### getUrl
|
||||
|
||||
string LaravelFCM\Sender\BaseSender::getUrl()
|
||||
|
||||
get the url
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
* This method is defined by [LaravelFCM\Sender\BaseSender](LaravelFCM-Sender-BaseSender.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Sender\BaseSender::__construct()
|
||||
|
||||
BaseSender constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Sender\BaseSender](LaravelFCM-Sender-BaseSender.md)
|
||||
|
||||
|
||||
|
@@ -1,153 +0,0 @@
|
||||
LaravelFCM\Sender\FCMSender
|
||||
===============
|
||||
|
||||
Class FCMSender
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: FCMSender
|
||||
* Namespace: LaravelFCM\Sender
|
||||
* Parent class: [LaravelFCM\Sender\BaseSender](LaravelFCM-Sender-BaseSender.md)
|
||||
|
||||
|
||||
|
||||
Constants
|
||||
----------
|
||||
|
||||
|
||||
### MAX_TOKEN_PER_REQUEST
|
||||
|
||||
const MAX_TOKEN_PER_REQUEST = 1000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
|
||||
### $client
|
||||
|
||||
protected \Illuminate\Foundation\Application $client
|
||||
|
||||
Guzzle Client
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
### $config
|
||||
|
||||
protected array $config
|
||||
|
||||
configuration
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
### $url
|
||||
|
||||
protected mixed $url
|
||||
|
||||
url
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### sendTo
|
||||
|
||||
\LaravelFCM\Response\DownstreamResponse|null LaravelFCM\Sender\FCMSender::sendTo(String|array $to, \LaravelFCM\Message\Options|null $options, \LaravelFCM\Message\PayloadNotification|null $notification, \LaravelFCM\Message\PayloadData|null $data)
|
||||
|
||||
send a downstream message to
|
||||
|
||||
- a unique device with is registration Token
|
||||
- or to multiples devices with an array of registrationIds
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $to **String|array**
|
||||
* $options **[LaravelFCM\Message\Options](LaravelFCM-Message-Options.md)|null**
|
||||
* $notification **[LaravelFCM\Message\PayloadNotification](LaravelFCM-Message-PayloadNotification.md)|null**
|
||||
* $data **[LaravelFCM\Message\PayloadData](LaravelFCM-Message-PayloadData.md)|null**
|
||||
|
||||
|
||||
|
||||
### sendToGroup
|
||||
|
||||
\LaravelFCM\Response\GroupResponse LaravelFCM\Sender\FCMSender::sendToGroup($notificationKey, \LaravelFCM\Message\Options|null $options, \LaravelFCM\Message\PayloadNotification|null $notification, \LaravelFCM\Message\PayloadData|null $data)
|
||||
|
||||
Send a message to a group of devices identified with them notification key
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $notificationKey **mixed**
|
||||
* $options **[LaravelFCM\Message\Options](LaravelFCM-Message-Options.md)|null**
|
||||
* $notification **[LaravelFCM\Message\PayloadNotification](LaravelFCM-Message-PayloadNotification.md)|null**
|
||||
* $data **[LaravelFCM\Message\PayloadData](LaravelFCM-Message-PayloadData.md)|null**
|
||||
|
||||
|
||||
|
||||
### sendToTopic
|
||||
|
||||
\LaravelFCM\Response\TopicResponse LaravelFCM\Sender\FCMSender::sendToTopic(\LaravelFCM\Message\Topics $topics, \LaravelFCM\Message\Options|null $options, \LaravelFCM\Message\PayloadNotification|null $notification, \LaravelFCM\Message\PayloadData|null $data)
|
||||
|
||||
Send message devices registered at a or more topics
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $topics **[LaravelFCM\Message\Topics](LaravelFCM-Message-Topics.md)**
|
||||
* $options **[LaravelFCM\Message\Options](LaravelFCM-Message-Options.md)|null**
|
||||
* $notification **[LaravelFCM\Message\PayloadNotification](LaravelFCM-Message-PayloadNotification.md)|null**
|
||||
* $data **[LaravelFCM\Message\PayloadData](LaravelFCM-Message-PayloadData.md)|null**
|
||||
|
||||
|
||||
|
||||
### getUrl
|
||||
|
||||
string LaravelFCM\Sender\BaseSender::getUrl()
|
||||
|
||||
get the url
|
||||
|
||||
|
||||
|
||||
* Visibility: **protected**
|
||||
* This method is **abstract**.
|
||||
* This method is defined by [LaravelFCM\Sender\BaseSender](LaravelFCM-Sender-BaseSender.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Sender\BaseSender::__construct()
|
||||
|
||||
BaseSender constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Sender\BaseSender](LaravelFCM-Sender-BaseSender.md)
|
||||
|
||||
|
||||
|
@@ -1,254 +0,0 @@
|
||||
LaravelFCM\Test\Mocks\MockDownstreamResponse
|
||||
===============
|
||||
|
||||
Class MockDownstreamResponse **Only use it for testing**
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: MockDownstreamResponse
|
||||
* Namespace: LaravelFCM\Test\Mocks
|
||||
* This class implements: [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### __construct
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockDownstreamResponse::__construct($numberSuccess)
|
||||
|
||||
DownstreamResponse constructor.
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $numberSuccess **mixed**
|
||||
|
||||
|
||||
|
||||
### merge
|
||||
|
||||
mixed LaravelFCM\Response\DownstreamResponseContract::merge(\LaravelFCM\Response\DownstreamResponse $response)
|
||||
|
||||
Merge two response
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $response **[LaravelFCM\Response\DownstreamResponse](LaravelFCM-Response-DownstreamResponse.md)**
|
||||
|
||||
|
||||
|
||||
### numberSuccess
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberSuccess()
|
||||
|
||||
Get the number of device reached with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### numberFailure
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberFailure()
|
||||
|
||||
Get the number of device which thrown an error
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### numberModification
|
||||
|
||||
integer LaravelFCM\Response\DownstreamResponseContract::numberModification()
|
||||
|
||||
Get the number of device that you need to modify their token
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### addTokenToDelete
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockDownstreamResponse::addTokenToDelete($token)
|
||||
|
||||
Add a token to delete
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $token **mixed**
|
||||
|
||||
|
||||
|
||||
### tokensToDelete
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToDelete()
|
||||
|
||||
get token to delete
|
||||
|
||||
remove all tokens returned by this method in your database
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### addTokenToModify
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockDownstreamResponse::addTokenToModify($oldToken, $newToken)
|
||||
|
||||
Add a token to modify
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $oldToken **mixed**
|
||||
* $newToken **mixed**
|
||||
|
||||
|
||||
|
||||
### tokensToModify
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToModify()
|
||||
|
||||
get token to modify
|
||||
|
||||
key: oldToken
|
||||
value: new token
|
||||
|
||||
find the old token in your database and replace it with the new one
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### addTokenToRetry
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockDownstreamResponse::addTokenToRetry($token)
|
||||
|
||||
Add a token to retry
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $token **mixed**
|
||||
|
||||
|
||||
|
||||
### tokensToRetry
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensToRetry()
|
||||
|
||||
Get tokens that you should resend using exponential backoof
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### addTokenWithError
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockDownstreamResponse::addTokenWithError($token, $message)
|
||||
|
||||
Add a token to errors
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $token **mixed**
|
||||
* $message **mixed**
|
||||
|
||||
|
||||
|
||||
### tokensWithError
|
||||
|
||||
array LaravelFCM\Response\DownstreamResponseContract::tokensWithError()
|
||||
|
||||
Get tokens that thrown an error
|
||||
|
||||
key : token
|
||||
value : error
|
||||
|
||||
In production, remove these tokens from you database
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### setMissingToken
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockDownstreamResponse::setMissingToken($hasMissingToken)
|
||||
|
||||
change missing token state
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $hasMissingToken **mixed**
|
||||
|
||||
|
||||
|
||||
### hasMissingToken
|
||||
|
||||
boolean LaravelFCM\Response\DownstreamResponseContract::hasMissingToken()
|
||||
|
||||
check if missing tokens was given to the request
|
||||
If true, remove all the empty token in your database
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
|
||||
|
||||
|
@@ -1,110 +0,0 @@
|
||||
LaravelFCM\Test\Mocks\MockGroupResponse
|
||||
===============
|
||||
|
||||
Class MockGroupResponse **Only use it for testing**
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: MockGroupResponse
|
||||
* Namespace: LaravelFCM\Test\Mocks
|
||||
* This class implements: [LaravelFCM\Response\GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### setNumberSuccess
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockGroupResponse::setNumberSuccess($numberSuccess)
|
||||
|
||||
set number of success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $numberSuccess **mixed**
|
||||
|
||||
|
||||
|
||||
### numberSuccess
|
||||
|
||||
integer LaravelFCM\Response\GroupResponseContract::numberSuccess()
|
||||
|
||||
Get the number of device reached with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### setNumberFailure
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockGroupResponse::setNumberFailure($numberFailures)
|
||||
|
||||
set number of failures
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $numberFailures **mixed**
|
||||
|
||||
|
||||
|
||||
### numberFailure
|
||||
|
||||
integer LaravelFCM\Response\GroupResponseContract::numberFailure()
|
||||
|
||||
Get the number of device which thrown an error
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### addTokenFailed
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockGroupResponse::addTokenFailed($tokenFailed)
|
||||
|
||||
add a token to the failed list
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $tokenFailed **mixed**
|
||||
|
||||
|
||||
|
||||
### tokensFailed
|
||||
|
||||
array LaravelFCM\Response\GroupResponseContract::tokensFailed()
|
||||
|
||||
Get all token in group that fcm cannot reach
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
|
||||
|
||||
|
@@ -1,95 +0,0 @@
|
||||
LaravelFCM\Test\Mocks\MockTopicResponse
|
||||
===============
|
||||
|
||||
Class MockTopicResponse **Only use it for testing**
|
||||
|
||||
|
||||
|
||||
|
||||
* Class name: MockTopicResponse
|
||||
* Namespace: LaravelFCM\Test\Mocks
|
||||
* This class implements: [LaravelFCM\Response\TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
### setSuccess
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockTopicResponse::setSuccess($messageId)
|
||||
|
||||
if success set a message id
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $messageId **mixed**
|
||||
|
||||
|
||||
|
||||
### isSuccess
|
||||
|
||||
boolean LaravelFCM\Response\TopicResponseContract::isSuccess()
|
||||
|
||||
true if topic sent with success
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### setError
|
||||
|
||||
mixed LaravelFCM\Test\Mocks\MockTopicResponse::setError($error)
|
||||
|
||||
set error
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
|
||||
|
||||
#### Arguments
|
||||
* $error **mixed**
|
||||
|
||||
|
||||
|
||||
### error
|
||||
|
||||
string LaravelFCM\Response\TopicResponseContract::error()
|
||||
|
||||
return error message
|
||||
you should test if it's necessary to resent it
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
|
||||
|
||||
|
||||
|
||||
### shouldRetry
|
||||
|
||||
boolean LaravelFCM\Response\TopicResponseContract::shouldRetry()
|
||||
|
||||
return true if it's necessary resent it using exponential backoff
|
||||
|
||||
|
||||
|
||||
* Visibility: **public**
|
||||
* This method is defined by [LaravelFCM\Response\TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
|
||||
|
||||
|
38
vendor/brozot/laravel-fcm/doc/Readme.md
vendored
38
vendor/brozot/laravel-fcm/doc/Readme.md
vendored
@@ -1,38 +0,0 @@
|
||||
API Index
|
||||
=========
|
||||
|
||||
* LaravelFCM
|
||||
* LaravelFCM\Message
|
||||
* LaravelFCM\Message\Exceptions
|
||||
* [InvalidOptionsException](LaravelFCM-Message-Exceptions-InvalidOptionsException.md)
|
||||
* [NoTopicProvidedException](LaravelFCM-Message-Exceptions-NoTopicProvidedException.md)
|
||||
* [Options](LaravelFCM-Message-Options.md)
|
||||
* [OptionsBuilder](LaravelFCM-Message-OptionsBuilder.md)
|
||||
* [OptionsPriorities](LaravelFCM-Message-OptionsPriorities.md)
|
||||
* [PayloadData](LaravelFCM-Message-PayloadData.md)
|
||||
* [PayloadDataBuilder](LaravelFCM-Message-PayloadDataBuilder.md)
|
||||
* [PayloadNotification](LaravelFCM-Message-PayloadNotification.md)
|
||||
* [PayloadNotificationBuilder](LaravelFCM-Message-PayloadNotificationBuilder.md)
|
||||
* [Topics](LaravelFCM-Message-Topics.md)
|
||||
* LaravelFCM\Sender
|
||||
* [BaseSender](LaravelFCM-Sender-BaseSender.md)
|
||||
* [FCMGroup](LaravelFCM-Sender-FCMGroup.md)
|
||||
* [FCMSender](LaravelFCM-Sender-FCMSender.md)
|
||||
* LaravelFCM\Response
|
||||
* [BaseResponse](LaravelFCM-Response-BaseResponse.md)
|
||||
* [DownstreamResponse](LaravelFCM-Response-DownstreamResponse.md)
|
||||
* [DownstreamResponseContract](LaravelFCM-Response-DownstreamResponseContract.md)
|
||||
* LaravelFCM\Response\Exceptions
|
||||
* [InvalidRequestException](LaravelFCM-Response-Exceptions-InvalidRequestException.md)
|
||||
* [ServerResponseException](LaravelFCM-Response-Exceptions-ServerResponseException.md)
|
||||
* [UnauthorizedRequestException](LaravelFCM-Response-Exceptions-UnauthorizedRequestException.md)
|
||||
* [GroupResponse](LaravelFCM-Response-GroupResponse.md)
|
||||
* [GroupResponseContract](LaravelFCM-Response-GroupResponseContract.md)
|
||||
* [TopicResponse](LaravelFCM-Response-TopicResponse.md)
|
||||
* [TopicResponseContract](LaravelFCM-Response-TopicResponseContract.md)
|
||||
* LaravelFCM\Test
|
||||
* LaravelFCM\Test\Mocks
|
||||
* [MockDownstreamResponse](LaravelFCM-Test-Mocks-MockDownstreamResponse.md)
|
||||
* [MockGroupResponse](LaravelFCM-Test-Mocks-MockGroupResponse.md)
|
||||
* [MockTopicResponse](LaravelFCM-Test-Mocks-MockTopicResponse.md)
|
||||
|
18
vendor/brozot/laravel-fcm/phpunit.xml
vendored
18
vendor/brozot/laravel-fcm/phpunit.xml
vendored
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false">
|
||||
<testsuites>
|
||||
<testsuite name="Package Test Suite">
|
||||
<directory suffix="Test.php">./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
21
vendor/brozot/laravel-fcm/src/FCMManager.php
vendored
21
vendor/brozot/laravel-fcm/src/FCMManager.php
vendored
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Manager;
|
||||
|
||||
class FCMManager extends Manager
|
||||
{
|
||||
public function getDefaultDriver()
|
||||
{
|
||||
return $this->app[ 'config' ][ 'fcm.driver' ];
|
||||
}
|
||||
|
||||
protected function createHttpDriver()
|
||||
{
|
||||
$config = $this->app[ 'config' ]->get('fcm.http', []);
|
||||
|
||||
return new Client(['timeout' => $config[ 'timeout' ]]);
|
||||
}
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use LaravelFCM\Sender\FCMGroup;
|
||||
use LaravelFCM\Sender\FCMSender;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class FCMServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected $defer = true;
|
||||
|
||||
public function boot()
|
||||
{
|
||||
if (Str::contains($this->app->version(), 'Lumen')) {
|
||||
$this->app->configure('fcm');
|
||||
} else {
|
||||
$this->publishes([
|
||||
__DIR__.'/../config/fcm.php' => config_path('fcm.php'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function register()
|
||||
{
|
||||
if (!Str::contains($this->app->version(), 'Lumen')) {
|
||||
$this->mergeConfigFrom(__DIR__.'/../config/fcm.php', 'fcm');
|
||||
}
|
||||
|
||||
$this->app->singleton('fcm.client', function ($app) {
|
||||
return (new FCMManager($app))->driver();
|
||||
});
|
||||
|
||||
$this->app->bind('fcm.group', function ($app) {
|
||||
$client = $app[ 'fcm.client' ];
|
||||
$url = $app[ 'config' ]->get('fcm.http.server_group_url');
|
||||
|
||||
return new FCMGroup($client, $url);
|
||||
});
|
||||
|
||||
$this->app->bind('fcm.sender', function ($app) {
|
||||
$client = $app[ 'fcm.client' ];
|
||||
$url = $app[ 'config' ]->get('fcm.http.server_send_url');
|
||||
|
||||
return new FCMSender($client, $url);
|
||||
});
|
||||
}
|
||||
|
||||
public function provides()
|
||||
{
|
||||
return ['fcm.client', 'fcm.group', 'fcm.sender'];
|
||||
}
|
||||
}
|
13
vendor/brozot/laravel-fcm/src/Facades/FCM.php
vendored
13
vendor/brozot/laravel-fcm/src/Facades/FCM.php
vendored
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class FCM extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'fcm.sender';
|
||||
}
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class FCMGroup extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'fcm.group';
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class InvalidOptionsException.
|
||||
*/
|
||||
class InvalidOptionsException extends Exception
|
||||
{
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class NoTopicProvidedException.
|
||||
*/
|
||||
class NoTopicProvidedException extends Exception
|
||||
{
|
||||
}
|
110
vendor/brozot/laravel-fcm/src/Message/Options.php
vendored
110
vendor/brozot/laravel-fcm/src/Message/Options.php
vendored
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
/**
|
||||
* Class Options.
|
||||
*/
|
||||
class Options implements Arrayable
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $collapseKey;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $priority;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $contentAvailable;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isMutableContent = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $delayWhileIdle;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $timeToLive;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $restrictedPackageName;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isDryRun = false;
|
||||
|
||||
/**
|
||||
* Options constructor.
|
||||
*
|
||||
* @param OptionsBuilder $builder
|
||||
*/
|
||||
public function __construct(OptionsBuilder $builder)
|
||||
{
|
||||
$this->collapseKey = $builder->getCollapseKey();
|
||||
$this->priority = $builder->getPriority();
|
||||
$this->contentAvailable = $builder->isContentAvailable();
|
||||
$this->isMutableContent = $builder->isMutableContent();
|
||||
$this->delayWhileIdle = $builder->isDelayWhileIdle();
|
||||
$this->timeToLive = $builder->getTimeToLive();
|
||||
$this->restrictedPackageName = $builder->getRestrictedPackageName();
|
||||
$this->isDryRun = $builder->isDryRun();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform Option to array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$contentAvailable = $this->contentAvailable ? true : null;
|
||||
$mutableContent = $this->isMutableContent ? true : null;
|
||||
$delayWhileIdle = $this->delayWhileIdle ? true : null;
|
||||
$dryRun = $this->isDryRun ? true : null;
|
||||
|
||||
$options = [
|
||||
'collapse_key' => $this->collapseKey,
|
||||
'priority' => $this->priority,
|
||||
'content_available' => $contentAvailable,
|
||||
'mutable_content' => $mutableContent,
|
||||
'delay_while_idle' => $delayWhileIdle,
|
||||
'time_to_live' => $this->timeToLive,
|
||||
'restricted_package_name' => $this->restrictedPackageName,
|
||||
'dry_run' => $dryRun,
|
||||
];
|
||||
|
||||
return array_filter($options);
|
||||
}
|
||||
}
|
@@ -1,336 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message;
|
||||
|
||||
use LaravelFCM\Message\Exceptions\InvalidOptionsException;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Builder for creation of options used by FCM.
|
||||
*
|
||||
* Class OptionsBuilder
|
||||
*
|
||||
* @link http://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json
|
||||
*/
|
||||
class OptionsBuilder
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $collapseKey;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $priority;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $contentAvailable = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @var bool
|
||||
*/
|
||||
protected $mutableContent;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $delayWhileIdle = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $timeToLive;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $restrictedPackageName;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $dryRun = false;
|
||||
|
||||
/**
|
||||
* This parameter identifies a group of messages
|
||||
* A maximum of 4 different collapse keys is allowed at any given time.
|
||||
*
|
||||
* @param string $collapseKey
|
||||
*
|
||||
* @return \LaravelFCM\Message\OptionsBuilder
|
||||
*/
|
||||
public function setCollapseKey($collapseKey)
|
||||
{
|
||||
$this->collapseKey = $collapseKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the priority of the message. Valid values are "normal" and "high."
|
||||
* By default, messages are sent with normal priority.
|
||||
*
|
||||
* @param string $priority
|
||||
*
|
||||
* @return \LaravelFCM\Message\OptionsBuilder
|
||||
*
|
||||
* @throws InvalidOptionsException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function setPriority($priority)
|
||||
{
|
||||
if (!OptionsPriorities::isValid($priority)) {
|
||||
throw new InvalidOptionsException('priority is not valid, please refer to the documentation or use the constants of the class "OptionsPriorities"');
|
||||
}
|
||||
$this->priority = $priority;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* support only Android and Ios.
|
||||
*
|
||||
* An inactive client app is awoken.
|
||||
* On iOS, use this field to represent content-available in the APNS payload.
|
||||
* On Android, data messages wake the app by default.
|
||||
* On Chrome, currently not supported.
|
||||
*
|
||||
* @param bool $contentAvailable
|
||||
*
|
||||
* @return \LaravelFCM\Message\OptionsBuilder
|
||||
*/
|
||||
public function setContentAvailable($contentAvailable)
|
||||
{
|
||||
$this->contentAvailable = $contentAvailable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* support iOS 10+
|
||||
*
|
||||
* When a notification is sent and this is set to true,
|
||||
* the content of the notification can be modified before it is displayed.
|
||||
*
|
||||
* @param String $isMutableContent
|
||||
* @return OptionsBuilder
|
||||
*/
|
||||
public function setMutableContent($isMutableContent)
|
||||
{
|
||||
$this->mutableContent = $isMutableContent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When this parameter is set to true, it indicates that the message should not be sent until the device becomes active.
|
||||
*
|
||||
* @param bool $delayWhileIdle
|
||||
*
|
||||
* @return \LaravelFCM\Message\OptionsBuilder
|
||||
*/
|
||||
public function setDelayWhileIdle($delayWhileIdle)
|
||||
{
|
||||
$this->delayWhileIdle = $delayWhileIdle;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This parameter specifies how long the message should be kept in FCM storage if the device is offline.
|
||||
*
|
||||
* @param int $timeToLive (in second) min:0 max:2419200
|
||||
*
|
||||
* @return \LaravelFCM\Message\OptionsBuilder
|
||||
*
|
||||
* @throws InvalidOptionsException
|
||||
*/
|
||||
public function setTimeToLive($timeToLive)
|
||||
{
|
||||
if ($timeToLive < 0 || $timeToLive > 2419200) {
|
||||
throw new InvalidOptionsException("time to live must be between 0 and 2419200, current value is: {$timeToLive}");
|
||||
}
|
||||
$this->timeToLive = $timeToLive;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This parameter specifies the package name of the application where the registration tokens must match in order to receive the message.
|
||||
*
|
||||
* @param string $restrictedPackageName
|
||||
*
|
||||
* @return \LaravelFCM\Message\OptionsBuilder
|
||||
*/
|
||||
public function setRestrictedPackageName($restrictedPackageName)
|
||||
{
|
||||
$this->restrictedPackageName = $restrictedPackageName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This parameter, when set to true, allows developers to test a request without actually sending a message.
|
||||
* It should only be used for the development.
|
||||
*
|
||||
* @param bool $isDryRun
|
||||
*
|
||||
* @return \LaravelFCM\Message\OptionsBuilder
|
||||
*/
|
||||
public function setDryRun($isDryRun)
|
||||
{
|
||||
$this->dryRun = $isDryRun;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collapseKey.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getCollapseKey()
|
||||
{
|
||||
return $this->collapseKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the priority.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* is content available.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isContentAvailable()
|
||||
{
|
||||
return $this->contentAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* is mutable content
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMutableContent()
|
||||
{
|
||||
return $this->mutableContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* is delay white idle.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDelayWhileIdle()
|
||||
{
|
||||
return $this->delayWhileIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* get time to live.
|
||||
*
|
||||
* @return null|int
|
||||
*/
|
||||
public function getTimeToLive()
|
||||
{
|
||||
return $this->timeToLive;
|
||||
}
|
||||
|
||||
/**
|
||||
* get restricted package name.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getRestrictedPackageName()
|
||||
{
|
||||
return $this->restrictedPackageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* is dry run.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDryRun()
|
||||
{
|
||||
return $this->dryRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* build an instance of Options.
|
||||
*
|
||||
* @return Options
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return new Options($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class OptionsPriorities.
|
||||
*/
|
||||
final class OptionsPriorities
|
||||
{
|
||||
/**
|
||||
* @const high priority : iOS, these correspond to APNs priorities 10.
|
||||
*/
|
||||
const high = 'high';
|
||||
|
||||
/**
|
||||
* @const normal priority : iOS, these correspond to APNs priorities 5
|
||||
*/
|
||||
const normal = 'normal';
|
||||
|
||||
/**
|
||||
* @return array priorities available in fcm
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function getPriorities()
|
||||
{
|
||||
$class = new ReflectionClass(__CLASS__);
|
||||
|
||||
return $class->getConstants();
|
||||
}
|
||||
|
||||
/**
|
||||
* check if this priority is supported by fcm.
|
||||
*
|
||||
* @param $priority
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function isValid($priority)
|
||||
{
|
||||
return in_array($priority, static::getPriorities());
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
/**
|
||||
* Class PayloadData.
|
||||
*/
|
||||
class PayloadData implements Arrayable
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* PayloadData constructor.
|
||||
*
|
||||
* @param PayloadDataBuilder $builder
|
||||
*/
|
||||
public function __construct(PayloadDataBuilder $builder)
|
||||
{
|
||||
$this->data = $builder->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform payloadData to array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
@@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message;
|
||||
|
||||
/**
|
||||
* Class PayloadDataBuilder.
|
||||
*
|
||||
* Official google documentation :
|
||||
*
|
||||
* @link http://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json
|
||||
*/
|
||||
class PayloadDataBuilder
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* add data to existing data.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return PayloadDataBuilder
|
||||
*/
|
||||
public function addData(array $data)
|
||||
{
|
||||
$this->data = $this->data ?: [];
|
||||
|
||||
$this->data = array_merge($data, $this->data);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* erase data with new data.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return PayloadDataBuilder
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all data.
|
||||
*/
|
||||
public function removeAllData()
|
||||
{
|
||||
$this->data = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* return data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate a PayloadData.
|
||||
*
|
||||
* @return PayloadData new PayloadData instance
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return new PayloadData($this);
|
||||
}
|
||||
}
|
@@ -1,155 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
/**
|
||||
* Class PayloadNotification.
|
||||
*/
|
||||
class PayloadNotification implements Arrayable
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $body;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null/string
|
||||
*/
|
||||
protected $channelId;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $icon;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $sound;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $badge;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $tag;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $color;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $clickAction;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $bodyLocationKey;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $bodyLocationArgs;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $titleLocationKey;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $titleLocationArgs;
|
||||
|
||||
/**
|
||||
* PayloadNotification constructor.
|
||||
*
|
||||
* @param PayloadNotificationBuilder $builder
|
||||
*/
|
||||
public function __construct(PayloadNotificationBuilder $builder)
|
||||
{
|
||||
$this->title = $builder->getTitle();
|
||||
$this->body = $builder->getBody();
|
||||
$this->channelId = $builder->getChannelId();
|
||||
$this->icon = $builder->getIcon();
|
||||
$this->sound = $builder->getSound();
|
||||
$this->badge = $builder->getBadge();
|
||||
$this->tag = $builder->getTag();
|
||||
$this->color = $builder->getColor();
|
||||
$this->clickAction = $builder->getClickAction();
|
||||
$this->bodyLocationKey = $builder->getBodyLocationKey();
|
||||
$this->bodyLocationArgs = $builder->getBodyLocationArgs();
|
||||
$this->titleLocationKey = $builder->getTitleLocationKey();
|
||||
$this->titleLocationArgs = $builder->getTitleLocationArgs();
|
||||
}
|
||||
|
||||
/**
|
||||
* convert PayloadNotification to array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$notification = [
|
||||
'title' => $this->title,
|
||||
'body' => $this->body,
|
||||
'android_channel_id' => $this->channelId,
|
||||
'icon' => $this->icon,
|
||||
'sound' => $this->sound,
|
||||
'badge' => $this->badge,
|
||||
'tag' => $this->tag,
|
||||
'color' => $this->color,
|
||||
'click_action' => $this->clickAction,
|
||||
'body_loc_key' => $this->bodyLocationKey,
|
||||
'body_loc_args' => $this->bodyLocationArgs,
|
||||
'title_loc_key' => $this->titleLocationKey,
|
||||
'title_loc_args' => $this->titleLocationArgs,
|
||||
];
|
||||
|
||||
// remove null values
|
||||
$notification = array_filter($notification, function($value) {
|
||||
return $value !== null;
|
||||
});
|
||||
|
||||
return $notification;
|
||||
}
|
||||
}
|
@@ -1,447 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message;
|
||||
|
||||
/**
|
||||
* Class PayloadNotificationBuilder.
|
||||
*
|
||||
* Official google documentation :
|
||||
*
|
||||
* @link http://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json
|
||||
*/
|
||||
class PayloadNotificationBuilder
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $body;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $icon;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $sound;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $channelId;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $badge;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $tag;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $color;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $clickAction;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $bodyLocationKey;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $bodyLocationArgs;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $titleLocationKey;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $titleLocationArgs;
|
||||
|
||||
/**
|
||||
* Title must be present on android notification and ios (watch) notification.
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function __construct($title = null)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates notification title. This field is not visible on iOS phones and tablets.
|
||||
* but it is required for android.
|
||||
*
|
||||
* @param string $title
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates notification body text.
|
||||
*
|
||||
* @param string $body
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setBody($body)
|
||||
{
|
||||
$this->body = $body;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a channel ID for android API >= 26.
|
||||
*
|
||||
* @param string $channelId
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setChannelId($channelId)
|
||||
{
|
||||
$this->channelId = $channelId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported Android
|
||||
* Indicates notification icon. example : Sets value to myicon for drawable resource myicon.
|
||||
*
|
||||
* @param string $icon
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setIcon($icon)
|
||||
{
|
||||
$this->icon = $icon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates a sound to play when the device receives a notification.
|
||||
* Supports default or the filename of a sound resource bundled in the app.
|
||||
*
|
||||
* @param string $sound
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setSound($sound)
|
||||
{
|
||||
$this->sound = $sound;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported Ios.
|
||||
*
|
||||
* Indicates the badge on the client app home icon.
|
||||
*
|
||||
* @param string $badge
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setBadge($badge)
|
||||
{
|
||||
$this->badge = $badge;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported Android.
|
||||
*
|
||||
* Indicates whether each notification results in a new entry in the notification drawer on Android.
|
||||
* If not set, each request creates a new notification.
|
||||
* If set, and a notification with the same tag is already being shown, the new notification replaces the existing one in the notification drawer.
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setTag($tag)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported Android.
|
||||
*
|
||||
* Indicates color of the icon, expressed in #rrggbb format
|
||||
*
|
||||
* @param string $color
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setColor($color)
|
||||
{
|
||||
$this->color = $color;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the action associated with a user click on the notification.
|
||||
*
|
||||
* @param string $action
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setClickAction($action)
|
||||
{
|
||||
$this->clickAction = $action;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the key to the title string for localization.
|
||||
*
|
||||
* @param string $titleKey
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setTitleLocationKey($titleKey)
|
||||
{
|
||||
$this->titleLocationKey = $titleKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the string value to replace format specifiers in the title string for localization.
|
||||
*
|
||||
* @param mixed $titleArgs
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setTitleLocationArgs($titleArgs)
|
||||
{
|
||||
$this->titleLocationArgs = $titleArgs;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the key to the body string for localization.
|
||||
*
|
||||
* @param string $bodyKey
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setBodyLocationKey($bodyKey)
|
||||
{
|
||||
$this->bodyLocationKey = $bodyKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the string value to replace format specifiers in the body string for localization.
|
||||
*
|
||||
* @param mixed $bodyArgs
|
||||
*
|
||||
* @return PayloadNotificationBuilder current instance of the builder
|
||||
*/
|
||||
public function setBodyLocationArgs($bodyArgs)
|
||||
{
|
||||
$this->bodyLocationArgs = $bodyArgs;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get body.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get channel id for android api >= 26
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getChannelId()
|
||||
{
|
||||
return $this->channelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Icon.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getIcon()
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Sound.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getSound()
|
||||
{
|
||||
return $this->sound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Badge.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getBadge()
|
||||
{
|
||||
return $this->badge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Tag.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTag()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Color.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getColor()
|
||||
{
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ClickAction.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getClickAction()
|
||||
{
|
||||
return $this->clickAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get BodyLocationKey.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getBodyLocationKey()
|
||||
{
|
||||
return $this->bodyLocationKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get BodyLocationArgs.
|
||||
*
|
||||
* @return null|string|array
|
||||
*/
|
||||
public function getBodyLocationArgs()
|
||||
{
|
||||
return $this->bodyLocationArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TitleLocationKey.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitleLocationKey()
|
||||
{
|
||||
return $this->titleLocationKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetTitleLocationArgs.
|
||||
*
|
||||
* @return null|string|array
|
||||
*/
|
||||
public function getTitleLocationArgs()
|
||||
{
|
||||
return $this->titleLocationArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an PayloadNotification.
|
||||
*
|
||||
* @return PayloadNotification
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return new PayloadNotification($this);
|
||||
}
|
||||
}
|
226
vendor/brozot/laravel-fcm/src/Message/Topics.php
vendored
226
vendor/brozot/laravel-fcm/src/Message/Topics.php
vendored
@@ -1,226 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Message;
|
||||
|
||||
use Closure;
|
||||
use LaravelFCM\Message\Exceptions\NoTopicProvidedException;
|
||||
|
||||
/**
|
||||
* Class Topics.
|
||||
*
|
||||
* Create topic or a topic condition
|
||||
*/
|
||||
class Topics
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array of element in the condition
|
||||
*/
|
||||
public $conditions = [];
|
||||
|
||||
/**
|
||||
* Add a topic, this method should be called before any conditional topic.
|
||||
*
|
||||
* @param string $first topicName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function topic($first)
|
||||
{
|
||||
$this->conditions[] = compact('first');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a or condition to the precedent topic set.
|
||||
*
|
||||
* Parenthesis is a closure
|
||||
*
|
||||
* Equivalent of this: **'TopicA' in topic' || 'TopicB' in topics**
|
||||
*
|
||||
* ```
|
||||
* $topic = new Topics();
|
||||
* $topic->topic('TopicA')
|
||||
* ->orTopic('TopicB');
|
||||
* ```
|
||||
*
|
||||
* Equivalent of this: **'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)**
|
||||
*
|
||||
* ```
|
||||
* $topic = new Topics();
|
||||
* $topic->topic('TopicA')
|
||||
* ->andTopic(function($condition) {
|
||||
* $condition->topic('TopicB')->orTopic('TopicC');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* > Note: Only two operators per expression are supported by fcm
|
||||
*
|
||||
* @param string|Closure $first topicName or closure
|
||||
*
|
||||
* @return Topics
|
||||
*/
|
||||
public function orTopic($first)
|
||||
{
|
||||
return $this->on($first, ' || ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a and condition to the precedent topic set.
|
||||
*
|
||||
* Parenthesis is a closure
|
||||
*
|
||||
* Equivalent of this: **'TopicA' in topic' && 'TopicB' in topics**
|
||||
*
|
||||
* ```
|
||||
* $topic = new Topics();
|
||||
* $topic->topic('TopicA')
|
||||
* ->anTopic('TopicB');
|
||||
* ```
|
||||
*
|
||||
* Equivalent of this: **'TopicA' in topics || ('TopicB' in topics && 'TopicC' in topics)**
|
||||
*
|
||||
* ```
|
||||
* $topic = new Topics();
|
||||
* $topic->topic('TopicA')
|
||||
* ->orTopic(function($condition) {
|
||||
* $condition->topic('TopicB')->AndTopic('TopicC');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* > Note: Only two operators per expression are supported by fcm
|
||||
*
|
||||
* @param string|Closure $first topicName or closure
|
||||
*
|
||||
* @return Topics
|
||||
*/
|
||||
public function andTopic($first)
|
||||
{
|
||||
return $this->on($first, ' && ');
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $first
|
||||
* @param $condition
|
||||
*
|
||||
* @return $this|Topics
|
||||
*/
|
||||
private function on($first, $condition)
|
||||
{
|
||||
if ($first instanceof Closure) {
|
||||
return $this->nest($first, $condition);
|
||||
}
|
||||
|
||||
$this->conditions[] = compact('condition', 'first');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param Closure $callback
|
||||
* @param $condition
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function nest(Closure $callback, $condition)
|
||||
{
|
||||
$topic = new static();
|
||||
|
||||
$callback($topic);
|
||||
if (count($topic->conditions)) {
|
||||
$open_parenthesis = '(';
|
||||
$topic = $topic->conditions;
|
||||
$close_parenthesis = ')';
|
||||
|
||||
$this->conditions[] = compact('condition', 'open_parenthesis', 'topic', 'close_parenthesis');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform to array.
|
||||
*
|
||||
* @return array|string
|
||||
*
|
||||
* @throws NoTopicProvided
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$this->checkIfOneTopicExist();
|
||||
|
||||
if ($this->hasOnlyOneTopic()) {
|
||||
foreach ($this->conditions[0] as $topic) {
|
||||
return '/topics/'.$topic;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'condition' => $this->topicsForFcm($this->conditions),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $conditions
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function topicsForFcm($conditions)
|
||||
{
|
||||
$condition = '';
|
||||
foreach ($conditions as $partial) {
|
||||
if (array_key_exists('condition', $partial)) {
|
||||
$condition .= $partial['condition'];
|
||||
}
|
||||
|
||||
if (array_key_exists('first', $partial)) {
|
||||
$topic = $partial['first'];
|
||||
$condition .= "'$topic' in topics";
|
||||
}
|
||||
|
||||
if (array_key_exists('open_parenthesis', $partial)) {
|
||||
$condition .= $partial['open_parenthesis'];
|
||||
}
|
||||
|
||||
if (array_key_exists('topic', $partial)) {
|
||||
$condition .= $this->topicsForFcm($partial['topic']);
|
||||
}
|
||||
|
||||
if (array_key_exists('close_parenthesis', $partial)) {
|
||||
$condition .= $partial['close_parenthesis'];
|
||||
}
|
||||
}
|
||||
|
||||
return $condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if only one topic was set.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOnlyOneTopic()
|
||||
{
|
||||
return count($this->conditions) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @throws NoTopicProvidedException
|
||||
*/
|
||||
private function checkIfOneTopicExist()
|
||||
{
|
||||
if (!count($this->conditions)) {
|
||||
throw new NoTopicProvidedException('At least one topic must be provided');
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Request;
|
||||
|
||||
/**
|
||||
* Class BaseRequest.
|
||||
*/
|
||||
abstract class BaseRequest
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var \GuzzleHttp\ClientInterface
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* BaseRequest constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = app('config')->get('fcm.http', []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the header for the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildRequestHeader()
|
||||
{
|
||||
return [
|
||||
'Authorization' => 'key='.$this->config['server_key'],
|
||||
'Content-Type' => 'application/json',
|
||||
'project_id' => $this->config['sender_id'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the body of the request.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function buildBody();
|
||||
|
||||
/**
|
||||
* Return the request in array form.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return [
|
||||
'headers' => $this->buildRequestHeader(),
|
||||
'json' => $this->buildBody(),
|
||||
];
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Request;
|
||||
|
||||
/**
|
||||
* Class GroupRequest.
|
||||
*/
|
||||
class GroupRequest extends BaseRequest
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $operation;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $notificationKeyName;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $notificationKey;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $registrationIds;
|
||||
|
||||
/**
|
||||
* GroupRequest constructor.
|
||||
*
|
||||
* @param $operation
|
||||
* @param $notificationKeyName
|
||||
* @param $notificationKey
|
||||
* @param $registrationIds
|
||||
*/
|
||||
public function __construct($operation, $notificationKeyName, $notificationKey, $registrationIds)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->operation = $operation;
|
||||
$this->notificationKeyName = $notificationKeyName;
|
||||
$this->notificationKey = $notificationKey;
|
||||
$this->registrationIds = $registrationIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the header for the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildBody()
|
||||
{
|
||||
return [
|
||||
'operation' => $this->operation,
|
||||
'notification_key_name' => $this->notificationKeyName,
|
||||
'notification_key' => $this->notificationKey,
|
||||
'registration_ids' => $this->registrationIds,
|
||||
];
|
||||
}
|
||||
}
|
151
vendor/brozot/laravel-fcm/src/Request/Request.php
vendored
151
vendor/brozot/laravel-fcm/src/Request/Request.php
vendored
@@ -1,151 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Request;
|
||||
|
||||
use LaravelFCM\Message\Topics;
|
||||
use LaravelFCM\Message\Options;
|
||||
use LaravelFCM\Message\PayloadData;
|
||||
use LaravelFCM\Message\PayloadNotification;
|
||||
|
||||
/**
|
||||
* Class Request.
|
||||
*/
|
||||
class Request extends BaseRequest
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var Options
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var PayloadNotification
|
||||
*/
|
||||
protected $notification;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var PayloadData
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var Topics|null
|
||||
*/
|
||||
protected $topic;
|
||||
|
||||
/**
|
||||
* Request constructor.
|
||||
*
|
||||
* @param $to
|
||||
* @param Options $options
|
||||
* @param PayloadNotification $notification
|
||||
* @param PayloadData $data
|
||||
* @param Topics|null $topic
|
||||
*/
|
||||
public function __construct($to, Options $options = null, PayloadNotification $notification = null, PayloadData $data = null, Topics $topic = null)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->to = $to;
|
||||
$this->options = $options;
|
||||
$this->notification = $notification;
|
||||
$this->data = $data;
|
||||
$this->topic = $topic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the body for the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildBody()
|
||||
{
|
||||
$message = [
|
||||
'to' => $this->getTo(),
|
||||
'registration_ids' => $this->getRegistrationIds(),
|
||||
'notification' => $this->getNotification(),
|
||||
'data' => $this->getData(),
|
||||
];
|
||||
|
||||
$message = array_merge($message, $this->getOptions());
|
||||
|
||||
// remove null entries
|
||||
return array_filter($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* get to key transformed.
|
||||
*
|
||||
* @return array|null|string
|
||||
*/
|
||||
protected function getTo()
|
||||
{
|
||||
$to = is_array($this->to) ? null : $this->to;
|
||||
|
||||
if ($this->topic && $this->topic->hasOnlyOneTopic()) {
|
||||
$to = $this->topic->build();
|
||||
}
|
||||
|
||||
return $to;
|
||||
}
|
||||
|
||||
/**
|
||||
* get registrationIds transformed.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getRegistrationIds()
|
||||
{
|
||||
return is_array($this->to) ? $this->to : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get Options transformed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = $this->options ? $this->options->toArray() : [];
|
||||
|
||||
if ($this->topic && !$this->topic->hasOnlyOneTopic()) {
|
||||
$options = array_merge($options, $this->topic->build());
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* get notification transformed.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getNotification()
|
||||
{
|
||||
return $this->notification ? $this->notification->toArray() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get data transformed.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
return $this->data ? $this->data->toArray() : null;
|
||||
}
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use LaravelFCM\Response\Exceptions\ServerResponseException;
|
||||
use LaravelFCM\Response\Exceptions\InvalidRequestException;
|
||||
use LaravelFCM\Response\Exceptions\UnauthorizedRequestException;
|
||||
|
||||
/**
|
||||
* Class BaseResponse.
|
||||
*/
|
||||
abstract class BaseResponse
|
||||
{
|
||||
const SUCCESS = 'success';
|
||||
const FAILURE = 'failure';
|
||||
const ERROR = 'error';
|
||||
const MESSAGE_ID = 'message_id';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $logEnabled = false;
|
||||
|
||||
/**
|
||||
* BaseResponse constructor.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
*/
|
||||
public function __construct(ResponseInterface $response)
|
||||
{
|
||||
$this->isJsonResponse($response);
|
||||
$this->logEnabled = app('config')->get('fcm.log_enabled', false);
|
||||
$responseInJson = json_decode($response->getBody(), true);
|
||||
$this->parseResponse($responseInJson);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the response given by fcm is parsable.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
*
|
||||
* @throws InvalidRequestException
|
||||
* @throws ServerResponseException
|
||||
* @throws UnauthorizedRequestException
|
||||
*/
|
||||
private function isJsonResponse(ResponseInterface $response)
|
||||
{
|
||||
if ($response->getStatusCode() == 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($response->getStatusCode() == 400) {
|
||||
throw new InvalidRequestException($response);
|
||||
}
|
||||
|
||||
if ($response->getStatusCode() == 401) {
|
||||
throw new UnauthorizedRequestException($response);
|
||||
}
|
||||
|
||||
throw new ServerResponseException($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse the response.
|
||||
*
|
||||
* @param array $responseInJson
|
||||
*/
|
||||
abstract protected function parseResponse($responseInJson);
|
||||
|
||||
/**
|
||||
* Log the response.
|
||||
*/
|
||||
abstract protected function logResponse();
|
||||
}
|
@@ -1,413 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class DownstreamResponse.
|
||||
*/
|
||||
class DownstreamResponse extends BaseResponse implements DownstreamResponseContract
|
||||
{
|
||||
const MULTICAST_ID = 'multicast_id';
|
||||
const CANONICAL_IDS = 'canonical_ids';
|
||||
const RESULTS = 'results';
|
||||
|
||||
const MISSING_REGISTRATION = 'MissingRegistration';
|
||||
const MESSAGE_ID = 'message_id';
|
||||
const REGISTRATION_ID = 'registration_id';
|
||||
const NOT_REGISTERED = 'NotRegistered';
|
||||
const INVALID_REGISTRATION = 'InvalidRegistration';
|
||||
const UNAVAILABLE = 'Unavailable';
|
||||
const DEVICE_MESSAGE_RATE_EXCEEDED = 'DeviceMessageRateExceeded';
|
||||
const INTERNAL_SERVER_ERROR = 'InternalServerError';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numberTokensSuccess = 0;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numberTokensFailure = 0;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numberTokenModify = 0;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected $messageId;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokensToDelete = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokensToModify = [];
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokensToRetry = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokensWithError = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $hasMissingToken = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $tokens;
|
||||
|
||||
/**
|
||||
* DownstreamResponse constructor.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
* @param $tokens
|
||||
*/
|
||||
public function __construct(ResponseInterface $response, $tokens)
|
||||
{
|
||||
$this->tokens = is_string($tokens) ? [$tokens] : $tokens;
|
||||
|
||||
parent::__construct($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the response.
|
||||
*
|
||||
* @param $responseInJson
|
||||
*/
|
||||
protected function parseResponse($responseInJson)
|
||||
{
|
||||
$this->parse($responseInJson);
|
||||
|
||||
if ($this->needResultParsing($responseInJson)) {
|
||||
$this->parseResult($responseInJson);
|
||||
}
|
||||
|
||||
if ($this->logEnabled) {
|
||||
$this->logResponse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $responseInJson
|
||||
*/
|
||||
private function parse($responseInJson)
|
||||
{
|
||||
if (array_key_exists(self::MULTICAST_ID, $responseInJson)) {
|
||||
$this->messageId;
|
||||
}
|
||||
|
||||
if (array_key_exists(self::SUCCESS, $responseInJson)) {
|
||||
$this->numberTokensSuccess = $responseInJson[self::SUCCESS];
|
||||
}
|
||||
|
||||
if (array_key_exists(self::FAILURE, $responseInJson)) {
|
||||
$this->numberTokensFailure = $responseInJson[self::FAILURE];
|
||||
}
|
||||
|
||||
if (array_key_exists(self::CANONICAL_IDS, $responseInJson)) {
|
||||
$this->numberTokenModify = $responseInJson[self::CANONICAL_IDS];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $responseInJson
|
||||
*/
|
||||
private function parseResult($responseInJson)
|
||||
{
|
||||
foreach ($responseInJson[self::RESULTS] as $index => $result) {
|
||||
if (!$this->isSent($result)) {
|
||||
if (!$this->needToBeModify($index, $result)) {
|
||||
if (!$this->needToBeDeleted($index, $result) && !$this->needToResend($index, $result) && !$this->checkMissingToken($result)) {
|
||||
$this->needToAddError($index, $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $responseInJson
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function needResultParsing($responseInJson)
|
||||
{
|
||||
return array_key_exists(self::RESULTS, $responseInJson) && ($this->numberTokensFailure > 0 || $this->numberTokenModify > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $results
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isSent($results)
|
||||
{
|
||||
return array_key_exists(self::MESSAGE_ID, $results) && !array_key_exists(self::REGISTRATION_ID, $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $index
|
||||
* @param $result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function needToBeModify($index, $result)
|
||||
{
|
||||
if (array_key_exists(self::MESSAGE_ID, $result) && array_key_exists(self::REGISTRATION_ID, $result)) {
|
||||
if ($this->tokens[$index]) {
|
||||
$this->tokensToModify[$this->tokens[$index]] = $result[self::REGISTRATION_ID];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $index
|
||||
* @param $result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function needToBeDeleted($index, $result)
|
||||
{
|
||||
if (array_key_exists(self::ERROR, $result) &&
|
||||
(in_array(self::NOT_REGISTERED, $result) || in_array(self::INVALID_REGISTRATION, $result))) {
|
||||
if ($this->tokens[$index]) {
|
||||
$this->tokensToDelete[] = $this->tokens[$index];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $index
|
||||
* @param $result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function needToResend($index, $result)
|
||||
{
|
||||
if (array_key_exists(self::ERROR, $result) && (in_array(self::UNAVAILABLE, $result) || in_array(self::DEVICE_MESSAGE_RATE_EXCEEDED, $result) || in_array(self::INTERNAL_SERVER_ERROR, $result))) {
|
||||
if ($this->tokens[$index]) {
|
||||
$this->tokensToRetry[] = $this->tokens[$index];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $result
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkMissingToken($result)
|
||||
{
|
||||
$hasMissingToken = (array_key_exists(self::ERROR, $result) && in_array(self::MISSING_REGISTRATION, $result));
|
||||
|
||||
$this->hasMissingToken = (bool) ($this->hasMissingToken | $hasMissingToken);
|
||||
|
||||
return $hasMissingToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $index
|
||||
* @param $result
|
||||
*/
|
||||
private function needToAddError($index, $result)
|
||||
{
|
||||
if (array_key_exists(self::ERROR, $result)) {
|
||||
if ($this->tokens[$index]) {
|
||||
$this->tokensWithError[$this->tokens[$index]] = $result[self::ERROR];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected function logResponse()
|
||||
{
|
||||
$logger = new Logger('Laravel-FCM');
|
||||
$logger->pushHandler(new StreamHandler(storage_path('logs/laravel-fcm.log')));
|
||||
|
||||
$logMessage = 'notification send to '.count($this->tokens).' devices'.PHP_EOL;
|
||||
$logMessage .= 'success: '.$this->numberTokensSuccess.PHP_EOL;
|
||||
$logMessage .= 'failures: '.$this->numberTokensFailure.PHP_EOL;
|
||||
$logMessage .= 'number of modified token : '.$this->numberTokenModify.PHP_EOL;
|
||||
|
||||
$logger->info($logMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two response.
|
||||
*
|
||||
* @param DownstreamResponse $response
|
||||
*/
|
||||
public function merge(DownstreamResponse $response)
|
||||
{
|
||||
$this->numberTokensSuccess += $response->numberSuccess();
|
||||
$this->numberTokensFailure += $response->numberFailure();
|
||||
$this->numberTokenModify += $response->numberModification();
|
||||
|
||||
$this->tokensToDelete = array_merge($this->tokensToDelete, $response->tokensToDelete());
|
||||
$this->tokensToModify = array_merge($this->tokensToModify, $response->tokensToModify());
|
||||
$this->tokensToRetry = array_merge($this->tokensToRetry, $response->tokensToRetry());
|
||||
$this->tokensWithError = array_merge($this->tokensWithError, $response->tokensWithError());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of device reached with success.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberSuccess()
|
||||
{
|
||||
return $this->numberTokensSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of device which thrown an error.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberFailure()
|
||||
{
|
||||
return $this->numberTokensFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of device that you need to modify their token.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberModification()
|
||||
{
|
||||
return $this->numberTokenModify;
|
||||
}
|
||||
|
||||
/**
|
||||
* get token to delete.
|
||||
*
|
||||
* remove all tokens returned by this method in your database
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensToDelete()
|
||||
{
|
||||
return $this->tokensToDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* get token to modify.
|
||||
*
|
||||
* key: oldToken
|
||||
* value: new token
|
||||
*
|
||||
* find the old token in your database and replace it with the new one
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensToModify()
|
||||
{
|
||||
return $this->tokensToModify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tokens that you should resend using exponential backoff.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensToRetry()
|
||||
{
|
||||
return $this->tokensToRetry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tokens that thrown an error.
|
||||
*
|
||||
* key : token
|
||||
* value : error
|
||||
*
|
||||
* In production, remove these tokens from you database
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensWithError()
|
||||
{
|
||||
return $this->tokensWithError;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if missing tokens was given to the request
|
||||
* If true, remove all the empty token in your database.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMissingToken()
|
||||
{
|
||||
return $this->hasMissingToken;
|
||||
}
|
||||
}
|
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response;
|
||||
|
||||
/**
|
||||
* Interface DownstreamResponseContract.
|
||||
*/
|
||||
interface DownstreamResponseContract
|
||||
{
|
||||
/**
|
||||
* Merge two response.
|
||||
*
|
||||
* @param DownstreamResponse $response
|
||||
*/
|
||||
public function merge(DownstreamResponse $response);
|
||||
|
||||
/**
|
||||
* Get the number of device reached with success.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberSuccess();
|
||||
|
||||
/**
|
||||
* Get the number of device which thrown an error.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberFailure();
|
||||
|
||||
/**
|
||||
* Get the number of device that you need to modify their token.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberModification();
|
||||
|
||||
/**
|
||||
* get token to delete.
|
||||
*
|
||||
* remove all tokens returned by this method in your database
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensToDelete();
|
||||
|
||||
/**
|
||||
* get token to modify.
|
||||
*
|
||||
* key: oldToken
|
||||
* value: new token
|
||||
*
|
||||
* find the old token in your database and replace it with the new one
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensToModify();
|
||||
|
||||
/**
|
||||
* Get tokens that you should resend using exponential backoof.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensToRetry();
|
||||
|
||||
/**
|
||||
* Get tokens that thrown an error.
|
||||
*
|
||||
* key : token
|
||||
* value : error
|
||||
*
|
||||
* In production, remove these tokens from you database
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensWithError();
|
||||
|
||||
/**
|
||||
* check if missing tokens was given to the request
|
||||
* If true, remove all the empty token in your database.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMissingToken();
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class InvalidRequestException.
|
||||
*/
|
||||
class InvalidRequestException extends Exception
|
||||
{
|
||||
/**
|
||||
* InvalidRequestException constructor.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
*/
|
||||
public function __construct(ResponseInterface $response)
|
||||
{
|
||||
$code = $response->getStatusCode();
|
||||
$responseBody = $response->getBody()->getContents();
|
||||
|
||||
parent::__construct($responseBody, $code);
|
||||
}
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class ServerResponseException.
|
||||
*/
|
||||
class ServerResponseException extends Exception
|
||||
{
|
||||
/**
|
||||
* retry after.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $retryAfter;
|
||||
|
||||
/**
|
||||
* ServerResponseException constructor.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
*/
|
||||
public function __construct(ResponseInterface $response)
|
||||
{
|
||||
$code = $response->getStatusCode();
|
||||
$responseHeader = $response->getHeaders();
|
||||
$responseBody = $response->getBody()->getContents();
|
||||
|
||||
if (array_keys($responseHeader, 'Retry-After')) {
|
||||
$this->retryAfter = $responseHeader['Retry-After'];
|
||||
}
|
||||
|
||||
parent::__construct($responseBody, $code);
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class UnauthorizedRequestException.
|
||||
*/
|
||||
class UnauthorizedRequestException extends Exception
|
||||
{
|
||||
/**
|
||||
* UnauthorizedRequestException constructor.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
*/
|
||||
public function __construct(ResponseInterface $response)
|
||||
{
|
||||
$code = $response->getStatusCode();
|
||||
|
||||
parent::__construct('FCM_SENDER_ID or FCM_SERVER_KEY are invalid', $code);
|
||||
}
|
||||
}
|
@@ -1,148 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class GroupResponse.
|
||||
*/
|
||||
class GroupResponse extends BaseResponse implements GroupResponseContract
|
||||
{
|
||||
const FAILED_REGISTRATION_IDS = 'failed_registration_ids';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numberTokensSuccess = 0;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numberTokensFailure = 0;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tokensFailed = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
/**
|
||||
* GroupResponse constructor.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
* @param $to
|
||||
*/
|
||||
public function __construct(ResponseInterface $response, $to)
|
||||
{
|
||||
$this->to = $to;
|
||||
parent::__construct($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse the response.
|
||||
*
|
||||
* @param $responseInJson
|
||||
*/
|
||||
protected function parseResponse($responseInJson)
|
||||
{
|
||||
if ($this->parse($responseInJson)) {
|
||||
$this->parseFailed($responseInJson);
|
||||
}
|
||||
|
||||
if ($this->logEnabled) {
|
||||
$this->logResponse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the response.
|
||||
*/
|
||||
protected function logResponse()
|
||||
{
|
||||
$logger = new Logger('Laravel-FCM');
|
||||
$logger->pushHandler(new StreamHandler(storage_path('logs/laravel-fcm.log')));
|
||||
|
||||
$logMessage = "notification send to group: $this->to";
|
||||
$logMessage .= "with $this->numberTokensSuccess success and $this->numberTokensFailure";
|
||||
|
||||
$logger->info($logMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $responseInJson
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function parse($responseInJson)
|
||||
{
|
||||
if (array_key_exists(self::SUCCESS, $responseInJson)) {
|
||||
$this->numberTokensSuccess = $responseInJson[self::SUCCESS];
|
||||
}
|
||||
if (array_key_exists(self::FAILURE, $responseInJson)) {
|
||||
$this->numberTokensFailure = $responseInJson[self::FAILURE];
|
||||
}
|
||||
|
||||
return $this->numberTokensFailure > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $responseInJson
|
||||
*/
|
||||
private function parseFailed($responseInJson)
|
||||
{
|
||||
if (array_key_exists(self::FAILED_REGISTRATION_IDS, $responseInJson)) {
|
||||
foreach ($responseInJson[self::FAILED_REGISTRATION_IDS] as $registrationId) {
|
||||
$this->tokensFailed[] = $registrationId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of device reached with success.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberSuccess()
|
||||
{
|
||||
return $this->numberTokensSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of device which thrown an error.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberFailure()
|
||||
{
|
||||
return $this->numberTokensFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all token in group that fcm cannot reach.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensFailed()
|
||||
{
|
||||
return $this->tokensFailed;
|
||||
}
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response;
|
||||
|
||||
/**
|
||||
* Interface GroupResponseContract.
|
||||
*/
|
||||
interface GroupResponseContract
|
||||
{
|
||||
/**
|
||||
* Get the number of device reached with success.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberSuccess();
|
||||
|
||||
/**
|
||||
* Get the number of device which thrown an error.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function numberFailure();
|
||||
|
||||
/**
|
||||
* Get all token in group that fcm cannot reach.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tokensFailed();
|
||||
}
|
@@ -1,151 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response;
|
||||
|
||||
use Monolog\Logger;
|
||||
use LaravelFCM\Message\Topics;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class TopicResponse.
|
||||
*/
|
||||
class TopicResponse extends BaseResponse implements TopicResponseContract
|
||||
{
|
||||
const LIMIT_RATE_TOPICS_EXCEEDED = 'TopicsMessageRateExceeded';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $topic;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $messageId;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $error;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $needRetry = false;
|
||||
|
||||
/**
|
||||
* TopicResponse constructor.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
* @param Topics $topic
|
||||
*/
|
||||
public function __construct(ResponseInterface $response, Topics $topic)
|
||||
{
|
||||
$this->topic = $topic;
|
||||
parent::__construct($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse the response.
|
||||
*
|
||||
* @param $responseInJson
|
||||
*/
|
||||
protected function parseResponse($responseInJson)
|
||||
{
|
||||
if (!$this->parseSuccess($responseInJson)) {
|
||||
$this->parseError($responseInJson);
|
||||
}
|
||||
|
||||
if ($this->logEnabled) {
|
||||
$this->logResponse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $responseInJson
|
||||
*/
|
||||
private function parseSuccess($responseInJson)
|
||||
{
|
||||
if (array_key_exists(self::MESSAGE_ID, $responseInJson)) {
|
||||
$this->messageId = $responseInJson[ self::MESSAGE_ID ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $responseInJson
|
||||
*/
|
||||
private function parseError($responseInJson)
|
||||
{
|
||||
if (array_key_exists(self::ERROR, $responseInJson)) {
|
||||
if (in_array(self::LIMIT_RATE_TOPICS_EXCEEDED, $responseInJson)) {
|
||||
$this->needRetry = true;
|
||||
}
|
||||
|
||||
$this->error = $responseInJson[ self::ERROR ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the response.
|
||||
*/
|
||||
protected function logResponse()
|
||||
{
|
||||
$logger = new Logger('Laravel-FCM');
|
||||
$logger->pushHandler(new StreamHandler(storage_path('logs/laravel-fcm.log')));
|
||||
|
||||
$topic = $this->topic->build();
|
||||
|
||||
$logMessage = "notification send to topic: ".json_encode($topic);
|
||||
if ($this->messageId) {
|
||||
$logMessage .= "with success (message-id : $this->messageId)";
|
||||
} else {
|
||||
$logMessage .= "with error (error : $this->error)";
|
||||
}
|
||||
|
||||
$logger->info($logMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* true if topic sent with success.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccess()
|
||||
{
|
||||
return (bool) $this->messageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* return error message
|
||||
* you should test if it's necessary to resent it.
|
||||
*
|
||||
* @return string error
|
||||
*/
|
||||
public function error()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if it's necessary resent it using exponential backoff.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldRetry()
|
||||
{
|
||||
return $this->needRetry;
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Response;
|
||||
|
||||
/**
|
||||
* Interface TopicResponseContract.
|
||||
*/
|
||||
interface TopicResponseContract
|
||||
{
|
||||
/**
|
||||
* true if topic sent with success.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccess();
|
||||
|
||||
/**
|
||||
* return error message
|
||||
* you should test if it's necessary to resent it.
|
||||
*
|
||||
* @return string error
|
||||
*/
|
||||
public function error();
|
||||
|
||||
/**
|
||||
* return true if it's necessary resent it using exponential backoff.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldRetry();
|
||||
}
|
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Sender;
|
||||
|
||||
use LaravelFCM\Request\GroupRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class FCMGroup.
|
||||
*/
|
||||
class FCMGroup extends HTTPSender
|
||||
{
|
||||
const CREATE = 'create';
|
||||
const ADD = 'add';
|
||||
const REMOVE = 'remove';
|
||||
|
||||
/**
|
||||
* Create a group.
|
||||
*
|
||||
* @param $notificationKeyName
|
||||
* @param array $registrationIds
|
||||
*
|
||||
* @return null|string notification_key
|
||||
*/
|
||||
public function createGroup($notificationKeyName, array $registrationIds)
|
||||
{
|
||||
$request = new GroupRequest(self::CREATE, $notificationKeyName, null, $registrationIds);
|
||||
|
||||
$response = $this->client->request('post', $this->url, $request->build());
|
||||
|
||||
return $this->getNotificationToken($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* add registrationId to a existing group.
|
||||
*
|
||||
* @param $notificationKeyName
|
||||
* @param $notificationKey
|
||||
* @param array $registrationIds registrationIds to add
|
||||
* @return null|string notification_key
|
||||
*/
|
||||
public function addToGroup($notificationKeyName, $notificationKey, array $registrationIds)
|
||||
{
|
||||
$request = new GroupRequest(self::ADD, $notificationKeyName, $notificationKey, $registrationIds);
|
||||
$response = $this->client->request('post', $this->url, $request->build());
|
||||
|
||||
return $this->getNotificationToken($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove registrationId to a existing group.
|
||||
*
|
||||
* >Note: if you remove all registrationIds the group is automatically deleted
|
||||
*
|
||||
* @param $notificationKeyName
|
||||
* @param $notificationKey
|
||||
* @param array $registeredIds registrationIds to remove
|
||||
* @return null|string notification_key
|
||||
*/
|
||||
public function removeFromGroup($notificationKeyName, $notificationKey, array $registeredIds)
|
||||
{
|
||||
$request = new GroupRequest(self::REMOVE, $notificationKeyName, $notificationKey, $registeredIds);
|
||||
$response = $this->client->request('post', $this->url, $request->build());
|
||||
|
||||
return $this->getNotificationToken($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
* @return null|string notification_key
|
||||
*/
|
||||
private function getNotificationToken(ResponseInterface $response)
|
||||
{
|
||||
if (! $this->isValidResponse($response)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$json = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
return $json['notification_key'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidResponse(ResponseInterface $response)
|
||||
{
|
||||
return $response->getStatusCode() === 200;
|
||||
}
|
||||
}
|
118
vendor/brozot/laravel-fcm/src/Sender/FCMSender.php
vendored
118
vendor/brozot/laravel-fcm/src/Sender/FCMSender.php
vendored
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Sender;
|
||||
|
||||
use LaravelFCM\Message\Topics;
|
||||
use LaravelFCM\Request\Request;
|
||||
use LaravelFCM\Message\Options;
|
||||
use LaravelFCM\Message\PayloadData;
|
||||
use LaravelFCM\Response\GroupResponse;
|
||||
use LaravelFCM\Response\TopicResponse;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use LaravelFCM\Response\DownstreamResponse;
|
||||
use LaravelFCM\Message\PayloadNotification;
|
||||
|
||||
/**
|
||||
* Class FCMSender.
|
||||
*/
|
||||
class FCMSender extends HTTPSender
|
||||
{
|
||||
const MAX_TOKEN_PER_REQUEST = 1000;
|
||||
|
||||
/**
|
||||
* send a downstream message to.
|
||||
*
|
||||
* - a unique device with is registration Token
|
||||
* - or to multiples devices with an array of registrationIds
|
||||
*
|
||||
* @param string|array $to
|
||||
* @param Options|null $options
|
||||
* @param PayloadNotification|null $notification
|
||||
* @param PayloadData|null $data
|
||||
*
|
||||
* @return DownstreamResponse|null
|
||||
*/
|
||||
public function sendTo($to, Options $options = null, PayloadNotification $notification = null, PayloadData $data = null)
|
||||
{
|
||||
$response = null;
|
||||
|
||||
if (is_array($to) && !empty($to)) {
|
||||
$partialTokens = array_chunk($to, self::MAX_TOKEN_PER_REQUEST, false);
|
||||
foreach ($partialTokens as $tokens) {
|
||||
$request = new Request($tokens, $options, $notification, $data);
|
||||
|
||||
$responseGuzzle = $this->post($request);
|
||||
|
||||
$responsePartial = new DownstreamResponse($responseGuzzle, $tokens);
|
||||
if (!$response) {
|
||||
$response = $responsePartial;
|
||||
} else {
|
||||
$response->merge($responsePartial);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$request = new Request($to, $options, $notification, $data);
|
||||
$responseGuzzle = $this->post($request);
|
||||
|
||||
$response = new DownstreamResponse($responseGuzzle, $to);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a group of devices identified with them notification key.
|
||||
*
|
||||
* @param $notificationKey
|
||||
* @param Options|null $options
|
||||
* @param PayloadNotification|null $notification
|
||||
* @param PayloadData|null $data
|
||||
*
|
||||
* @return GroupResponse
|
||||
*/
|
||||
public function sendToGroup($notificationKey, Options $options = null, PayloadNotification $notification = null, PayloadData $data = null)
|
||||
{
|
||||
$request = new Request($notificationKey, $options, $notification, $data);
|
||||
|
||||
$responseGuzzle = $this->post($request);
|
||||
|
||||
return new GroupResponse($responseGuzzle, $notificationKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message devices registered at a or more topics.
|
||||
*
|
||||
* @param Topics $topics
|
||||
* @param Options|null $options
|
||||
* @param PayloadNotification|null $notification
|
||||
* @param PayloadData|null $data
|
||||
*
|
||||
* @return TopicResponse
|
||||
*/
|
||||
public function sendToTopic(Topics $topics, Options $options = null, PayloadNotification $notification = null, PayloadData $data = null)
|
||||
{
|
||||
$request = new Request(null, $options, $notification, $data, $topics);
|
||||
|
||||
$responseGuzzle = $this->post($request);
|
||||
|
||||
return new TopicResponse($responseGuzzle, $topics);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param \LaravelFCM\Request\Request $request
|
||||
*
|
||||
* @return null|\Psr\Http\Message\ResponseInterface
|
||||
*/
|
||||
protected function post($request)
|
||||
{
|
||||
try {
|
||||
$responseGuzzle = $this->client->request('post', $this->url, $request->build());
|
||||
} catch (ClientException $e) {
|
||||
$responseGuzzle = $e->getResponse();
|
||||
}
|
||||
|
||||
return $responseGuzzle;
|
||||
}
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace LaravelFCM\Sender;
|
||||
|
||||
use GuzzleHttp\ClientInterface;
|
||||
|
||||
/**
|
||||
* Class BaseSender.
|
||||
*/
|
||||
abstract class HTTPSender
|
||||
{
|
||||
/**
|
||||
* The client used to send messages.
|
||||
*
|
||||
* @var \GuzzleHttp\ClientInterface
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* The URL entry point.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* Initializes a new sender object.
|
||||
*
|
||||
* @param \GuzzleHttp\ClientInterface $client
|
||||
* @param string $url
|
||||
*/
|
||||
public function __construct(ClientInterface $client, $url)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->url = $url;
|
||||
}
|
||||
}
|
@@ -1,460 +0,0 @@
|
||||
<?php
|
||||
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use LaravelFCM\Response\DownstreamResponse;
|
||||
|
||||
class DownstreamResponseTest extends FCMTestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_a_success()
|
||||
{
|
||||
$token = 'new_token';
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 108,
|
||||
"success": 1,
|
||||
"failure": 0,
|
||||
"canonical_ids": 0,
|
||||
"results": [
|
||||
{ "message_id": "1:08" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $token);
|
||||
|
||||
$this->assertEquals(1, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(0, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(0, $downstreamResponse->numberModification());
|
||||
|
||||
$this->assertCount(0, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(0, $downstreamResponse->tokensToModify());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_multiple_successes()
|
||||
{
|
||||
$tokens = [
|
||||
'first_token',
|
||||
'second_token',
|
||||
'third_token',
|
||||
];
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 108,
|
||||
"success": 3,
|
||||
"failure": 0,
|
||||
"canonical_ids": 0,
|
||||
"results": [
|
||||
{ "message_id": "1:01" },
|
||||
{ "message_id": "1:02" },
|
||||
{ "message_id": "1:03" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $tokens);
|
||||
|
||||
$this->assertEquals(3, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(0, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(0, $downstreamResponse->numberModification());
|
||||
|
||||
$this->assertCount(0, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(0, $downstreamResponse->tokensToModify());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_a_failure()
|
||||
{
|
||||
$token = 'new_token';
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 108,
|
||||
"success": 0,
|
||||
"failure": 1,
|
||||
"canonical_ids": 0,
|
||||
"results": [
|
||||
{ "error": "NotRegistered" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $token);
|
||||
|
||||
$this->assertEquals(0, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(1, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(0, $downstreamResponse->numberModification());
|
||||
$this->assertFalse($downstreamResponse->hasMissingToken());
|
||||
|
||||
$this->assertCount(1, $downstreamResponse->tokensToDelete());
|
||||
$this->assertEquals($token, $downstreamResponse->tokensToDelete()[ 0 ]);
|
||||
$this->assertCount(0, $downstreamResponse->tokensToModify());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_multiple_failures()
|
||||
{
|
||||
$tokens = [
|
||||
'first_token',
|
||||
'second_token',
|
||||
'third_token',
|
||||
'fourth_token',
|
||||
];
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 108,
|
||||
"success": 0,
|
||||
"failure": 3,
|
||||
"canonical_ids": 0,
|
||||
"results": [
|
||||
{ "error": "NotRegistered" },
|
||||
{ "error": "InvalidRegistration" },
|
||||
{ "error": "NotRegistered" },
|
||||
{ "error": "MissingRegistration"}
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $tokens);
|
||||
|
||||
$this->assertEquals(0, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(3, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(0, $downstreamResponse->numberModification());
|
||||
$this->assertTrue($downstreamResponse->hasMissingToken());
|
||||
|
||||
$this->assertCount(3, $downstreamResponse->tokensToDelete());
|
||||
$this->assertEquals($tokens[ 0 ], $downstreamResponse->tokensToDelete()[ 0 ]);
|
||||
$this->assertEquals($tokens[ 1 ], $downstreamResponse->tokensToDelete()[ 1 ]);
|
||||
$this->assertEquals($tokens[ 2 ], $downstreamResponse->tokensToDelete()[ 2 ]);
|
||||
$this->assertCount(0, $downstreamResponse->tokensToModify());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_a_token_to_change()
|
||||
{
|
||||
$token = 'new_token';
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 108,
|
||||
"success": 0,
|
||||
"failure": 0,
|
||||
"canonical_ids": 1,
|
||||
"results": [
|
||||
{ "message_id": "1:2342", "registration_id": "32" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $token);
|
||||
|
||||
$this->assertEquals(0, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(0, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(1, $downstreamResponse->numberModification());
|
||||
|
||||
$this->assertCount(0, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(1, $downstreamResponse->tokensToModify());
|
||||
|
||||
$this->assertTrue(array_key_exists($token, $downstreamResponse->tokensToModify()));
|
||||
$this->assertEquals('32', $downstreamResponse->tokensToModify()[ $token ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_multiple_tokens_to_change()
|
||||
{
|
||||
$tokens = [
|
||||
'first_token',
|
||||
'second_token',
|
||||
'third_token',
|
||||
];
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 108,
|
||||
"success": 0,
|
||||
"failure": 0,
|
||||
"canonical_ids": 3,
|
||||
"results": [
|
||||
{ "message_id": "1:2342", "registration_id": "32" },
|
||||
{ "message_id": "1:2342", "registration_id": "33" },
|
||||
{ "message_id": "1:2342", "registration_id": "34" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $tokens);
|
||||
|
||||
$this->assertEquals(0, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(0, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(3, $downstreamResponse->numberModification());
|
||||
|
||||
$this->assertCount(0, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(3, $downstreamResponse->tokensToModify());
|
||||
|
||||
$this->assertTrue(array_key_exists($tokens[ 0 ], $downstreamResponse->tokensToModify()));
|
||||
$this->assertEquals('32', $downstreamResponse->tokensToModify()[ $tokens[ 0 ] ]);
|
||||
|
||||
$this->assertTrue(array_key_exists($tokens[ 1 ], $downstreamResponse->tokensToModify()));
|
||||
$this->assertEquals('33', $downstreamResponse->tokensToModify()[ $tokens[ 1 ] ]);
|
||||
|
||||
$this->assertTrue(array_key_exists($tokens[ 2 ], $downstreamResponse->tokensToModify()));
|
||||
$this->assertEquals('34', $downstreamResponse->tokensToModify()[ $tokens[ 2 ] ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_a_token_unavailable()
|
||||
{
|
||||
$token = 'first_token';
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 0,
|
||||
"failure": 1,
|
||||
"canonical_ids": 0,
|
||||
"results": [
|
||||
{ "error": "Unavailable" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $token);
|
||||
|
||||
$this->assertEquals(0, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(1, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(0, $downstreamResponse->numberModification());
|
||||
|
||||
// Unavailable is not an error caused by the token validity. it don't need to be deleted$
|
||||
$this->assertCount(0, $downstreamResponse->tokensToModify());
|
||||
$this->assertCount(0, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(1, $downstreamResponse->tokensToRetry());
|
||||
|
||||
$this->assertEquals($token, $downstreamResponse->tokensToRetry()[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_a_token_server_error()
|
||||
{
|
||||
$token = 'first_token';
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 0,
|
||||
"failure": 1,
|
||||
"canonical_ids": 0,
|
||||
"results": [
|
||||
{ "error": "InternalServerError" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $token);
|
||||
|
||||
$this->assertEquals(0, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(1, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(0, $downstreamResponse->numberModification());
|
||||
|
||||
// Unavailable is not an error caused by the token validity. it don't need to be deleted$
|
||||
$this->assertCount(0, $downstreamResponse->tokensToModify());
|
||||
$this->assertCount(0, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(1, $downstreamResponse->tokensToRetry());
|
||||
|
||||
$this->assertEquals($token, $downstreamResponse->tokensToRetry()[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_a_token_exceeded()
|
||||
{
|
||||
$token = 'first_token';
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 0,
|
||||
"failure": 1,
|
||||
"canonical_ids": 0,
|
||||
"results": [
|
||||
{ "error": "DeviceMessageRateExceeded" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $token);
|
||||
|
||||
$this->assertEquals(0, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(1, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(0, $downstreamResponse->numberModification());
|
||||
|
||||
// Unavailable is not an error caused by the token validity. it don't need to be deleted$
|
||||
$this->assertCount(0, $downstreamResponse->tokensToModify());
|
||||
$this->assertCount(0, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(1, $downstreamResponse->tokensToRetry());
|
||||
|
||||
$this->assertEquals($token, $downstreamResponse->tokensToRetry()[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_a_mixed_token_to_retry()
|
||||
{
|
||||
$tokens = [
|
||||
'first_token',
|
||||
'second_token',
|
||||
'third_token',
|
||||
'fourth_token',
|
||||
'fifth_token',
|
||||
'sixth_token',
|
||||
];
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 0,
|
||||
"failure": 6,
|
||||
"canonical_ids": 0,
|
||||
"results": [
|
||||
{ "error": "DeviceMessageRateExceeded" },
|
||||
{ "error": "InternalServerError" },
|
||||
{ "error": "Unavailable" },
|
||||
{ "error": "DeviceMessageRateExceeded" },
|
||||
{ "error": "InternalServerError" },
|
||||
{ "error": "Unavailable" }
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $tokens);
|
||||
|
||||
$this->assertEquals(0, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(6, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(0, $downstreamResponse->numberModification());
|
||||
|
||||
// Unavailable is not an error caused by the token validity. it don't need to be deleted$
|
||||
$this->assertCount(0, $downstreamResponse->tokensToModify());
|
||||
$this->assertCount(0, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(6, $downstreamResponse->tokensToRetry());
|
||||
|
||||
$this->assertEquals($tokens[ 0 ], $downstreamResponse->tokensToRetry()[ 0 ]);
|
||||
$this->assertEquals($tokens[ 1 ], $downstreamResponse->tokensToRetry()[ 1 ]);
|
||||
$this->assertEquals($tokens[ 2 ], $downstreamResponse->tokensToRetry()[ 2 ]);
|
||||
$this->assertEquals($tokens[ 3 ], $downstreamResponse->tokensToRetry()[ 3 ]);
|
||||
$this->assertEquals($tokens[ 4 ], $downstreamResponse->tokensToRetry()[ 4 ]);
|
||||
$this->assertEquals($tokens[ 5 ], $downstreamResponse->tokensToRetry()[ 5 ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_mixed_response()
|
||||
{
|
||||
$tokens = [
|
||||
'first_token',
|
||||
'second_token',
|
||||
'third_token',
|
||||
'fourth_token',
|
||||
'fifth_token',
|
||||
'sixth_token',
|
||||
];
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 3,
|
||||
"failure": 3,
|
||||
"canonical_ids": 1,
|
||||
"results": [
|
||||
{ "message_id": "1:0408" },
|
||||
{ "error": "Unavailable" },
|
||||
{ "error": "InvalidRegistration" },
|
||||
{ "message_id": "1:1516" },
|
||||
{ "message_id": "1:2342", "registration_id": "32" },
|
||||
{ "error": "NotRegistered"}
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $tokens);
|
||||
|
||||
$this->assertEquals(3, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(3, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(1, $downstreamResponse->numberModification());
|
||||
|
||||
// Unavailable is not an error caused by the token validity. it don't need to be deleted
|
||||
$this->assertCount(2, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(1, $downstreamResponse->tokensToModify());
|
||||
|
||||
$this->assertEquals($tokens[ 2 ], $downstreamResponse->tokensToDelete()[ 0 ]);
|
||||
$this->assertEquals($tokens[ 5 ], $downstreamResponse->tokensToDelete()[ 1 ]);
|
||||
|
||||
$this->assertTrue(array_key_exists($tokens[ 4 ], $downstreamResponse->tokensToModify()));
|
||||
$this->assertEquals('32', $downstreamResponse->tokensToModify()[ $tokens[ 4 ] ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_multiples_response()
|
||||
{
|
||||
$tokens = [
|
||||
'first_token',
|
||||
'second_token',
|
||||
'third_token',
|
||||
'fourth_token',
|
||||
'fifth_token',
|
||||
'sixth_token',
|
||||
'seventh_token',
|
||||
];
|
||||
|
||||
$tokens1 = [
|
||||
'first_1_token',
|
||||
'second_1_token',
|
||||
'third_1_token',
|
||||
'fourth_1_token',
|
||||
'fifth_1_token',
|
||||
'sixth_1_token',
|
||||
'seventh_1_token',
|
||||
];
|
||||
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 3,
|
||||
"failure": 3,
|
||||
"canonical_ids": 1,
|
||||
"results": [
|
||||
{ "message_id": "1:0408" },
|
||||
{ "error": "Unavailable" },
|
||||
{ "error": "InvalidRegistration" },
|
||||
{ "message_id": "1:1516" },
|
||||
{ "message_id": "1:2342", "registration_id": "32" },
|
||||
{ "error": "NotRegistered"},
|
||||
{ "error": "MessageTooBig"}
|
||||
]
|
||||
}');
|
||||
|
||||
$downstreamResponse = new DownstreamResponse($response, $tokens);
|
||||
$downstreamResponse1 = new DownstreamResponse($response, $tokens1);
|
||||
|
||||
$downstreamResponse->merge($downstreamResponse1);
|
||||
|
||||
$this->assertEquals(6, $downstreamResponse->numberSuccess());
|
||||
$this->assertEquals(6, $downstreamResponse->numberFailure());
|
||||
$this->assertEquals(2, $downstreamResponse->numberModification());
|
||||
|
||||
// Unavailable is not an error caused by the token validity. it don't need to be deleted
|
||||
$this->assertCount(4, $downstreamResponse->tokensToDelete());
|
||||
$this->assertCount(2, $downstreamResponse->tokensToModify());
|
||||
$this->assertCount(2, $downstreamResponse->tokensWithError());
|
||||
|
||||
$this->assertEquals($tokens[ 2 ], $downstreamResponse->tokensToDelete()[ 0 ]);
|
||||
$this->assertEquals($tokens1[ 2 ], $downstreamResponse->tokensToDelete()[ 2 ]);
|
||||
$this->assertEquals($tokens[ 5 ], $downstreamResponse->tokensToDelete()[ 1 ]);
|
||||
$this->assertEquals($tokens1[ 5 ], $downstreamResponse->tokensToDelete()[ 3 ]);
|
||||
|
||||
$this->assertCount(2, $downstreamResponse->tokensToRetry());
|
||||
|
||||
$this->assertEquals('MessageTooBig', $downstreamResponse->tokensWithError()[$tokens[6]]);
|
||||
$this->assertEquals('MessageTooBig', $downstreamResponse->tokensWithError()[$tokens1[6]]);
|
||||
}
|
||||
}
|
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use LaravelFCM\Sender\FCMSender;
|
||||
|
||||
class ResponseTest extends FCMTestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_send_a_notification_to_a_device()
|
||||
{
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 3,
|
||||
"failure": 3,
|
||||
"canonical_ids": 1,
|
||||
"results": [
|
||||
{ "message_id": "1:0408" }
|
||||
]
|
||||
}');
|
||||
|
||||
$client = Mockery::mock(Client::class);
|
||||
$client->shouldReceive('request')->once()->andReturn($response);
|
||||
|
||||
$tokens = 'uniqueToken';
|
||||
|
||||
$fcm = new FCMSender($client, 'http://test.test');
|
||||
$fcm->sendTo($tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_send_a_notification_to_more_than_1000_devices()
|
||||
{
|
||||
$response = new Response(200, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 3,
|
||||
"failure": 3,
|
||||
"canonical_ids": 1,
|
||||
"results": [
|
||||
{ "message_id": "1:0408" },
|
||||
{ "error": "Unavailable" },
|
||||
{ "error": "InvalidRegistration" },
|
||||
{ "message_id": "1:1516" },
|
||||
{ "message_id": "1:2342", "registration_id": "32" },
|
||||
{ "error": "NotRegistered"}
|
||||
]
|
||||
}');
|
||||
|
||||
$client = Mockery::mock(Client::class);
|
||||
$client->shouldReceive('request')->times(10)->andReturn($response);
|
||||
|
||||
$tokens = [];
|
||||
for ($i = 0; $i < 10000; ++$i) {
|
||||
$tokens[$i] = 'token_'.$i;
|
||||
}
|
||||
|
||||
$fcm = new FCMSender($client, 'http://test.test');
|
||||
$fcm->sendTo($tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function an_empty_array_of_tokens_thrown_an_exception()
|
||||
{
|
||||
$response = new Response(400, [], '{
|
||||
"multicast_id": 216,
|
||||
"success": 3,
|
||||
"failure": 3,
|
||||
"canonical_ids": 1,
|
||||
"results": [
|
||||
{ "message_id": "1:0408" },
|
||||
{ "error": "Unavailable" },
|
||||
{ "error": "InvalidRegistration" },
|
||||
{ "message_id": "1:1516" },
|
||||
{ "message_id": "1:2342", "registration_id": "32" },
|
||||
{ "error": "NotRegistered"}
|
||||
]
|
||||
}');
|
||||
|
||||
$client = Mockery::mock(Client::class);
|
||||
$client->shouldReceive('request')->once()->andReturn($response);
|
||||
|
||||
$fcm = new FCMSender($client, 'http://test.test');
|
||||
$this->setExpectedException(\LaravelFCM\Response\Exceptions\InvalidRequestException::class);
|
||||
$fcm->sendTo([]);
|
||||
}
|
||||
}
|
22
vendor/brozot/laravel-fcm/tests/FCMTestCase.php
vendored
22
vendor/brozot/laravel-fcm/tests/FCMTestCase.php
vendored
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Foundation\Testing\TestCase;
|
||||
|
||||
abstract class FCMTestCase extends TestCase
|
||||
{
|
||||
public function createApplication()
|
||||
{
|
||||
$app = require __DIR__.'/../vendor/laravel/laravel/bootstrap/app.php';
|
||||
|
||||
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
|
||||
$app->register(LaravelFCM\FCMServiceProvider::class);
|
||||
|
||||
$app['config']['fcm.driver'] = 'http';
|
||||
$app['config']['fcm.http.timeout'] = 20;
|
||||
$app['config']['fcm.http.server_send_url'] = 'http://test.test';
|
||||
$app['config']['fcm.http.server_key'] = 'key=myKey';
|
||||
$app['config']['fcm.http.sender_id'] = 'SENDER_ID';
|
||||
|
||||
return $app;
|
||||
}
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
use LaravelFCM\Response\GroupResponse;
|
||||
|
||||
class GroupResponseTest extends FCMTestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_successes()
|
||||
{
|
||||
$notificationKey = 'notificationKey';
|
||||
|
||||
$response = new \GuzzleHttp\Psr7\Response(200, [], '{
|
||||
"success": 2,
|
||||
"failure": 0
|
||||
}');
|
||||
|
||||
$responseGroup = new GroupResponse($response, $notificationKey);
|
||||
|
||||
$this->assertEquals(2, $responseGroup->numberSuccess());
|
||||
$this->assertEquals(0, $responseGroup->numberFailure());
|
||||
$this->assertCount(0, $responseGroup->tokensFailed());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_failures()
|
||||
{
|
||||
$notificationKey = 'notificationKey';
|
||||
|
||||
$response = new \GuzzleHttp\Psr7\Response(200, [], '{
|
||||
"success": 0,
|
||||
"failure": 2,
|
||||
"failed_registration_ids":[
|
||||
"regId1",
|
||||
"regId2"
|
||||
]}');
|
||||
|
||||
$responseGroup = new GroupResponse($response, $notificationKey);
|
||||
|
||||
$this->assertEquals(0, $responseGroup->numberSuccess());
|
||||
$this->assertEquals(2, $responseGroup->numberFailure());
|
||||
$this->assertCount(2, $responseGroup->tokensFailed());
|
||||
|
||||
$this->assertEquals('regId1', $responseGroup->tokensFailed()[ 0]);
|
||||
$this->assertEquals('regId2', $responseGroup->tokensFailed()[ 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_construct_a_response_with_partials_failures()
|
||||
{
|
||||
$notificationKey = 'notificationKey';
|
||||
|
||||
$response = new \GuzzleHttp\Psr7\Response(200, [], '{
|
||||
"success": 1,
|
||||
"failure": 2,
|
||||
"failed_registration_ids":[
|
||||
"regId1",
|
||||
"regId2"
|
||||
]}');
|
||||
|
||||
$responseGroup = new GroupResponse($response, $notificationKey);
|
||||
|
||||
$this->assertEquals(1, $responseGroup->numberSuccess());
|
||||
$this->assertEquals(2, $responseGroup->numberFailure());
|
||||
$this->assertCount(2, $responseGroup->tokensFailed());
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user