diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c2643eb8..053cde013 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,13 +11,18 @@ jobs: - name: Install dependencies uses: php-actions/composer@v6 with: - php_version: 7.4 + php_version: 8.3 command: update - php_extensions: ldap gd mbstring - - name: PHPUnit Tests for php7.4 + php_extensions: ldap gd mbstring xdebug + - name: PHPUnit Tests for php8.3 uses: php-actions/phpunit@v3 + env: + XDEBUG_MODE: coverage with: configuration: tests/phpunit.xml - version: 5.7.25 - php_version: 7.4 + version: latest + php_version: 8.3 + php_extensions: ldap gd mbstring xdebug + test_suffix: Test.php args: --coverage-text + diff --git a/composer.json b/composer.json index b9550fe8e..0f903ed55 100644 --- a/composer.json +++ b/composer.json @@ -18,5 +18,10 @@ "rm -rf htdocs/vendor/font-awesome ", "cp -R vendor/fortawesome/font-awesome htdocs/vendor/font-awesome" ] + }, + "require-dev": { + "phpunit/phpunit": "*", + "php-mock/php-mock-phpunit": "*", + "mockery/mockery": "*" } } diff --git a/composer.lock b/composer.lock index df8d88245..2cd1e5726 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "26cb255e1add9db76de55482d812d914", + "content-hash": "1bcdefdbd026935ec2c010791b562a57", "packages": [ { "name": "bjeavons/zxcvbn-php", @@ -62,158 +62,365 @@ "time": "2021-12-21T18:37:02+00:00" }, { - "name": "ltb-project/ldap", - "version": "v0.1.0", + "name": "components/jquery", + "version": "v3.7.1", "source": { "type": "git", - "url": "https://github.com/ltb-project/ltb-ldap.git", - "reference": "5acd3c86998acbc302937196e8495e81cdcfb4a1" + "url": "https://github.com/components/jquery.git", + "reference": "8edc7785239bb8c2ad2b83302b856a1d61de60e7" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/components/jquery/zipball/8edc7785239bb8c2ad2b83302b856a1d61de60e7", + "reference": "8edc7785239bb8c2ad2b83302b856a1d61de60e7", + "shasum": "" + }, + "type": "component", + "extra": { + "component": { + "scripts": [ + "jquery.js" + ], + "files": [ + "jquery.min.js", + "jquery.min.map", + "jquery.slim.js", + "jquery.slim.min.js", + "jquery.slim.min.map" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "JS Foundation and other contributors" + } + ], + "description": "jQuery JavaScript Library", + "homepage": "http://jquery.com", + "support": { + "forum": "http://forum.jquery.com", + "irc": "irc://irc.freenode.org/jquery", + "issues": "https://github.com/jquery/jquery/issues", + "source": "https://github.com/jquery/jquery", + "wiki": "http://docs.jquery.com/" + }, + "time": "2023-09-22T01:43:46+00:00" + }, + { + "name": "defuse/php-encryption", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/defuse/php-encryption.git", + "reference": "f53396c2d34225064647a05ca76c1da9d99e5828" }, "dist": { "type": "zip", - "url": "https://github.com/repos/ltb-project/ltb-ldap/zipball/5acd3c86998acbc302937196e8495e81cdcfb4a1", - "reference": "5acd3c86998acbc302937196e8495e81cdcfb4a1", + "url": "https://github.com/repos/defuse/php-encryption/zipball/f53396c2d34225064647a05ca76c1da9d99e5828", + "reference": "f53396c2d34225064647a05ca76c1da9d99e5828", "shasum": "" }, "require": { - "ext-ldap": ">=7.4", - "php": ">=7.4", - "phpmailer/phpmailer": "^6.5.0" + "ext-openssl": "*", + "paragonie/random_compat": ">= 2", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^5|^6|^7|^8|^9|^10", + "yoast/phpunit-polyfills": "^2.0.0" }, + "bin": [ + "bin/generate-defuse-key" + ], "type": "library", "autoload": { "psr-4": { - "Ltb\\": "src/Ltb" + "Defuse\\Crypto\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-3.0-or-later" + "MIT" + ], + "authors": [ + { + "name": "Taylor Hornby", + "email": "taylor@defuse.ca", + "homepage": "https://defuse.ca/" + }, + { + "name": "Scott Arciszewski", + "email": "info@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "Secure PHP Encryption Library", + "keywords": [ + "aes", + "authenticated encryption", + "cipher", + "crypto", + "cryptography", + "encrypt", + "encryption", + "openssl", + "security", + "symmetric key cryptography" ], - "description": "PHP framework for LTB project applications", "support": { - "issues": "https://github.com/ltb-project/ltb-ldap/issues", - "source": "https://github.com/ltb-project/ltb-ldap/tree/v0.1.0" + "issues": "https://github.com/defuse/php-encryption/issues", + "source": "https://github.com/defuse/php-encryption/tree/v2.4.0" }, - "time": "2023-04-24T13:24:07+00:00" + "time": "2023-06-19T06:10:36+00:00" }, { - "name": "phpmailer/phpmailer", - "version": "v6.9.1", + "name": "fortawesome/font-awesome", + "version": "6.5.1", "source": { "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18" + "url": "https://github.com/FortAwesome/Font-Awesome.git", + "reference": "deeea78c52bfe00b6e251ffddccf5570d5fdb05e" }, "dist": { "type": "zip", - "url": "https://github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18", - "reference": "039de174cd9c17a8389754d3b877a2ed22743e18", + "url": "https://github.com/repos/FortAwesome/Font-Awesome/zipball/deeea78c52bfe00b6e251ffddccf5570d5fdb05e", + "reference": "deeea78c52bfe00b6e251ffddccf5570d5fdb05e", + "shasum": "" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "CC-BY-4.0", + "OFL-1.1", + "MIT" + ], + "authors": [ + { + "name": "The Font Awesome Team", + "homepage": "https://github.com/orgs/FortAwesome/people" + } + ], + "description": "The iconic font, CSS, and SVG framework", + "homepage": "https://fontawesome.com", + "keywords": [ + "FontAwesome", + "awesome", + "bootstrap", + "font", + "icon", + "svg" + ], + "support": { + "docs": "http://fontawesome.com/docs", + "email": "hello@fontawesome.com", + "issues": "https://github.com/FortAwesome/Font-Awesome/issues", + "source": "https://github.com/FortAwesome/Font-Awesome" + }, + "time": "2023-11-30T22:38:48+00:00" + }, + { + "name": "gregwar/captcha", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/Gregwar/Captcha.git", + "reference": "229d3cdfe33d6f1349e0aec94a26e9205a6db08e" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/Gregwar/Captcha/zipball/229d3cdfe33d6f1349e0aec94a26e9205a6db08e", + "reference": "229d3cdfe33d6f1349e0aec94a26e9205a6db08e", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" + "ext-gd": "*", + "ext-mbstring": "*", + "php": ">=5.3.0", + "symfony/finder": "*" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/annotations": "^1.2.6 || ^1.13.3", - "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.7.2", - "yoast/phpunit-polyfills": "^1.0.4" + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gregwar\\": "src/Gregwar" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Passault", + "email": "g.passault@gmail.com", + "homepage": "http://www.gregwar.com/" + }, + { + "name": "Jeremy Livingston", + "email": "jeremy.j.livingston@gmail.com" + } + ], + "description": "Captcha generator", + "homepage": "https://github.com/Gregwar/Captcha", + "keywords": [ + "bot", + "captcha", + "spam" + ], + "support": { + "issues": "https://github.com/Gregwar/Captcha/issues", + "source": "https://github.com/Gregwar/Captcha/tree/v1.2.1" + }, + "time": "2023-09-26T13:45:37+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.8", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981", + "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.9", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" }, "suggest": { - "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "ext-openssl": "Needed for secure SMTP sending and DKIM signing", - "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", - "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" + "psr/log": "Required for using the Log middleware" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, "autoload": { + "files": [ + "src/functions_include.php" + ], "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" + "GuzzleHttp\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-2.1-only" + "MIT" ], "authors": [ { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" }, { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" }, { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" }, { - "name": "Brent R. Matzelle" + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1" + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/6.5.8" }, "funding": [ { - "url": "https://github.com/Synchro", + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" } ], - "time": "2023-11-25T22:23:28+00:00" + "time": "2022-06-20T22:16:07+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "name": "guzzlehttp/promises", + "version": "1.5.3", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "url": "https://github.com/guzzle/promises.git", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" }, "dist": { "type": "zip", - "url": "https://github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" + "php": ">=5.5" }, - "suggest": { - "ext-mbstring": "For best performance" + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { "files": [ - "bootstrap.php" + "src/functions_include.php" ], "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" + "GuzzleHttp\\Promise\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -222,100 +429,2976 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", + "description": "Guzzle promises library", "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" + "promise" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.3" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" + "url": "https://github.com/GrahamCampbell", + "type": "github" }, { - "url": "https://github.com/fabpot", + "url": "https://github.com/Nyholm", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2023-05-21T12:31:43+00:00" }, { - "name": "twbs/bootstrap", - "version": "v5.3.2", + "name": "guzzlehttp/psr7", + "version": "1.9.1", "source": { "type": "git", - "url": "https://github.com/twbs/bootstrap.git", - "reference": "344e912d04b5b6a04482113eff20ab416ff01048" + "url": "https://github.com/guzzle/psr7.git", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b" }, "dist": { "type": "zip", - "url": "https://github.com/repos/twbs/bootstrap/zipball/344e912d04b5b6a04482113eff20ab416ff01048", - "reference": "344e912d04b5b6a04482113eff20ab416ff01048", + "url": "https://github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b", "shasum": "" }, - "replace": { - "twitter/bootstrap": "self.version" + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Mark Otto", - "email": "markdotto@gmail.com" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" }, { - "name": "Jacob Thornton", - "email": "jacobthornton@gmail.com" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], - "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", - "homepage": "https://getbootstrap.com/", + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ - "JS", - "css", - "framework", - "front-end", - "mobile-first", - "responsive", - "sass", - "web" + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" ], "support": { - "issues": "https://github.com/twbs/bootstrap/issues", - "source": "https://github.com/twbs/bootstrap/tree/v5.3.2" + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.9.1" }, - "time": "2023-09-14T14:19:27+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-04-17T16:00:37+00:00" + }, + { + "name": "ltb-project/ldap", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/ltb-project/ltb-ldap.git", + "reference": "26819752c88487dd982a5eaf0acb74784f3058ac" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/ltb-project/ltb-ldap/zipball/26819752c88487dd982a5eaf0acb74784f3058ac", + "reference": "26819752c88487dd982a5eaf0acb74784f3058ac", + "shasum": "" + }, + "require": { + "ext-ldap": ">=7.4", + "php": ">=7.4", + "phpmailer/phpmailer": "^6.5.0" + }, + "require-dev": { + "mockery/mockery": "*", + "phpunit/phpunit": "*" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "Ltb\\": "src/Ltb" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "description": "PHP framework for LTB project applications", + "support": { + "issues": "https://github.com/ltb-project/ltb-ldap/issues", + "source": "https://github.com/ltb-project/ltb-ldap/tree/main" + }, + "time": "2024-04-19T13:44:51+00:00" + }, + { + "name": "mxrxdxn/pwned-passwords", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/mxrxdxn/pwned-passwords.git", + "reference": "4aff79ce064f4f6d3890c1d37fe723d2ad2ca18d" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/mxrxdxn/pwned-passwords/zipball/4aff79ce064f4f6d3890c1d37fe723d2ad2ca18d", + "reference": "4aff79ce064f4f6d3890c1d37fe723d2ad2ca18d", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.3 | ^7.0", + "php": "^7.3 | ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "symfony/var-dumper": "^5.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "PwnedPasswords\\": "src/PwnedPasswords/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ron Marsden", + "email": "hello@ronmarsden.com" + }, + { + "name": "Saif Eddin Gmati", + "email": "azjezz2@gmail.com" + } + ], + "description": "A library to query Troy Hunt's Pwned Passwords service to see whether or not a password has been included in a public breach.", + "keywords": [ + "password", + "passwords", + "security" + ], + "support": { + "issues": "https://github.com/mxrxdxn/pwned-passwords/issues", + "source": "https://github.com/mxrxdxn/pwned-passwords/tree/v2.1.0" + }, + "time": "2021-08-24T18:26:57+00:00" + }, + { + "name": "ovh/ovh", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/ovh/php-ovh.git", + "reference": "25a97501a150dff8a7848c372b5826395aab4df2" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/ovh/php-ovh/zipball/25a97501a150dff8a7848c372b5826395aab4df2", + "reference": "25a97501a150dff8a7848c372b5826395aab4df2", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0" + }, + "require-dev": { + "phpdocumentor/phpdocumentor": "2.*", + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "1.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ovh\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Wrapper for OVH APIs", + "support": { + "issues": "https://github.com/ovh/php-ovh/issues", + "source": "https://github.com/ovh/php-ovh/tree/master" + }, + "time": "2016-02-10T13:16:38+00:00" + }, + { + "name": "ovh/php-ovh-sms", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/ovh/php-ovh-sms.git", + "reference": "52d279e112a7da8f897745acab32a887321e03f1" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/ovh/php-ovh-sms/zipball/52d279e112a7da8f897745acab32a887321e03f1", + "reference": "52d279e112a7da8f897745acab32a887321e03f1", + "shasum": "" + }, + "require": { + "ovh/ovh": "~2.0.1" + }, + "require-dev": { + "phpdocumentor/phpdocumentor": "2.*", + "phpunit/phpunit": "7.*", + "squizlabs/php_codesniffer": "3.*" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-0": { + "Ovh\\Sms\\": "src/" + }, + "psr-4": { + "Ovh\\Sms\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "SDK for OVH SMS APIs", + "support": { + "issues": "https://github.com/ovh/php-ovh-sms/issues", + "source": "https://github.com/ovh/php-ovh-sms/tree/master" + }, + "time": "2019-01-22T11:17:39+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.9.1", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "039de174cd9c17a8389754d3b877a2ed22743e18" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18", + "reference": "039de174cd9c17a8389754d3b877a2ed22743e18", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "doctrine/annotations": "^1.2.6 || ^1.13.3", + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.7.2", + "yoast/phpunit-polyfills": "^1.0.4" + }, + "suggest": { + "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "ext-openssl": "Needed for secure SMTP sending and DKIM signing", + "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", + "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2023-11-25T22:23:28+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-10-31T17:59:56+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "twbs/bootstrap", + "version": "v5.3.3", + "source": { + "type": "git", + "url": "https://github.com/twbs/bootstrap.git", + "reference": "6e1f75f420f68e1d52733b8e407fc7c3766c9dba" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/twbs/bootstrap/zipball/6e1f75f420f68e1d52733b8e407fc7c3766c9dba", + "reference": "6e1f75f420f68e1d52733b8e407fc7c3766c9dba", + "shasum": "" + }, + "replace": { + "twitter/bootstrap": "self.version" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Otto", + "email": "markdotto@gmail.com" + }, + { + "name": "Jacob Thornton", + "email": "jacobthornton@gmail.com" + } + ], + "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", + "homepage": "https://getbootstrap.com/", + "keywords": [ + "JS", + "css", + "framework", + "front-end", + "mobile-first", + "responsive", + "sass", + "web" + ], + "support": { + "issues": "https://github.com/twbs/bootstrap/issues", + "source": "https://github.com/twbs/bootstrap/tree/v5.3.3" + }, + "time": "2024-02-20T15:14:29+00:00" + } + ], + "packages-dev": [ + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.11", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "81a161d0b135df89951abd52296adf97deb0723d" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/mockery/mockery/zipball/81a161d0b135df89951abd52296adf97deb0723d", + "reference": "81a161d0b135df89951abd52296adf97deb0723d", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" + }, + "time": "2024-03-21T18:34:15+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.0.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" + }, + "time": "2024-03-05T20:51:40+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "php-mock/php-mock", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/php-mock/php-mock.git", + "reference": "fff1a621ebe54100fa3bd852e7be57773a0c0127" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/php-mock/php-mock/zipball/fff1a621ebe54100fa3bd852e7be57773a0c0127", + "reference": "fff1a621ebe54100fa3bd852e7be57773a0c0127", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0 || ^8.0", + "phpunit/php-text-template": "^1 || ^2 || ^3 || ^4" + }, + "replace": { + "malkusch/php-mock": "*" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.0 || ^9.0 || ^10.0 || ^11.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "suggest": { + "php-mock/php-mock-phpunit": "Allows integration into PHPUnit testcase with the trait PHPMock." + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ], + "psr-4": { + "phpmock\\": [ + "classes/", + "tests/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "WTFPL" + ], + "authors": [ + { + "name": "Markus Malkusch", + "email": "markus@malkusch.de", + "homepage": "http://markus.malkusch.de", + "role": "Developer" + } + ], + "description": "PHP-Mock can mock built-in PHP functions (e.g. time()). PHP-Mock relies on PHP's namespace fallback policy. No further extension is needed.", + "homepage": "https://github.com/php-mock/php-mock", + "keywords": [ + "BDD", + "TDD", + "function", + "mock", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/php-mock/php-mock/issues", + "source": "https://github.com/php-mock/php-mock/tree/2.5.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2024-02-10T21:07:01+00:00" + }, + { + "name": "php-mock/php-mock-integration", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-mock/php-mock-integration.git", + "reference": "ec6a00a8129d50ed0f07907c91e3274ca4ade877" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/php-mock/php-mock-integration/zipball/ec6a00a8129d50ed0f07907c91e3274ca4ade877", + "reference": "ec6a00a8129d50ed0f07907c91e3274ca4ade877", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "php-mock/php-mock": "^2.5", + "phpunit/php-text-template": "^1 || ^2 || ^3 || ^4" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.27 || ^6 || ^7 || ^8 || ^9 || ^10 || ^11" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpmock\\integration\\": "classes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "WTFPL" + ], + "authors": [ + { + "name": "Markus Malkusch", + "email": "markus@malkusch.de", + "homepage": "http://markus.malkusch.de", + "role": "Developer" + } + ], + "description": "Integration package for PHP-Mock", + "homepage": "https://github.com/php-mock/php-mock-integration", + "keywords": [ + "BDD", + "TDD", + "function", + "mock", + "stub", + "test", + "test double" + ], + "support": { + "issues": "https://github.com/php-mock/php-mock-integration/issues", + "source": "https://github.com/php-mock/php-mock-integration/tree/2.3.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2024-02-10T21:37:25+00:00" + }, + { + "name": "php-mock/php-mock-phpunit", + "version": "2.10.0", + "source": { + "type": "git", + "url": "https://github.com/php-mock/php-mock-phpunit.git", + "reference": "e1f7e795990b00937376e345883ea68ca3bda7e0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/php-mock/php-mock-phpunit/zipball/e1f7e795990b00937376e345883ea68ca3bda7e0", + "reference": "e1f7e795990b00937376e345883ea68ca3bda7e0", + "shasum": "" + }, + "require": { + "php": ">=7", + "php-mock/php-mock-integration": "^2.3", + "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11" + }, + "require-dev": { + "mockery/mockery": "^1.3.6" + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ], + "psr-4": { + "phpmock\\phpunit\\": "classes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "WTFPL" + ], + "authors": [ + { + "name": "Markus Malkusch", + "email": "markus@malkusch.de", + "homepage": "http://markus.malkusch.de", + "role": "Developer" + } + ], + "description": "Mock built-in PHP functions (e.g. time()) with PHPUnit. This package relies on PHP's namespace fallback policy. No further extension is needed.", + "homepage": "https://github.com/php-mock/php-mock-phpunit", + "keywords": [ + "BDD", + "TDD", + "function", + "mock", + "phpunit", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/php-mock/php-mock-phpunit/issues", + "source": "https://github.com/php-mock/php-mock-phpunit/tree/2.10.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2024-02-11T07:24:16+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e35a2cbcabac0e6865fd373742ea432a3c34f92", + "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.0", + "phpunit/php-text-template": "^4.0", + "sebastian/code-unit-reverse-lookup": "^4.0", + "sebastian/complexity": "^4.0", + "sebastian/environment": "^7.0", + "sebastian/lines-of-code": "^3.0", + "sebastian/version": "^5.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-12T15:35:40+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "99e95c94ad9500daca992354fa09d7b99abe2210" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/php-file-iterator/zipball/99e95c94ad9500daca992354fa09d7b99abe2210", + "reference": "99e95c94ad9500daca992354fa09d7b99abe2210", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:05:04+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/php-invoker/zipball/5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:05:50+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/php-text-template/zipball/d38f6cbff1cdb6f40b03c9811421561668cc133e", + "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:06:56+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/php-timer/zipball/8a59d9e25720482ee7fcdf296595e08795b84dc5", + "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:08:01+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "51e342a0bc987e0ea8418105d0711f08ae116de3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/phpunit/zipball/51e342a0bc987e0ea8418105d0711f08ae116de3", + "reference": "51e342a0bc987e0ea8418105d0711f08ae116de3", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0", + "phpunit/php-file-iterator": "^5.0", + "phpunit/php-invoker": "^5.0", + "phpunit/php-text-template": "^4.0", + "phpunit/php-timer": "^7.0", + "sebastian/cli-parser": "^3.0", + "sebastian/code-unit": "^3.0", + "sebastian/comparator": "^6.0", + "sebastian/diff": "^6.0", + "sebastian/environment": "^7.0", + "sebastian/exporter": "^6.0", + "sebastian/global-state": "^7.0", + "sebastian/object-enumerator": "^6.0", + "sebastian/type": "^5.0", + "sebastian/version": "^5.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.1-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.1.2" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-04-14T07:13:56+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/cli-parser/zipball/00a74d5568694711f0222e54fb281e1d15fdf04a", + "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:26:58+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "6634549cb8d702282a04a774e36a7477d2bd9015" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/code-unit/zipball/6634549cb8d702282a04a774e36a7477d2bd9015", + "reference": "6634549cb8d702282a04a774e36a7477d2bd9015", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:50:41+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:52:17+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/comparator/zipball/bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:53:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "88a434ad86150e11a606ac4866b09130712671f0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/complexity/zipball/88a434ad86150e11a606ac4866b09130712671f0", + "reference": "88a434ad86150e11a606ac4866b09130712671f0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:55:19+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ab83243ecc233de5655b76f577711de9f842e712" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/diff/zipball/ab83243ecc233de5655b76f577711de9f842e712", + "reference": "ab83243ecc233de5655b76f577711de9f842e712", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:30:33+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/environment/zipball/4eb3a442574d0e9d141aab209cd4aaf25701b09a", + "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:56:34+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "f291e5a317c321c0381fa9ecc796fa2d21b186da" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/exporter/zipball/f291e5a317c321c0381fa9ecc796fa2d21b186da", + "reference": "f291e5a317c321c0381fa9ecc796fa2d21b186da", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:28:20+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/global-state/zipball/c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", + "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:32:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/lines-of-code/zipball/376c5b3f6b43c78fdc049740bca76a7c846706c0", + "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:00:36+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/object-enumerator/zipball/f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", + "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:01:29+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/object-reflector/zipball/bb2a6255d30853425fd38f032eb64ced9f7f132d", + "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:02:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "b75224967b5a466925c6d54e68edd0edf8dd4ed4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/recursion-context/zipball/b75224967b5a466925c6d54e68edd0edf8dd4ed4", + "reference": "b75224967b5a466925c6d54e68edd0edf8dd4ed4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:08:48+00:00" + }, + { + "name": "sebastian/type", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/type/zipball/b8502785eb3523ca0dd4afe9ca62235590020f3f", + "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:09:34+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/sebastianbergmann/version/zipball/13999475d2cb1ab33cb73403ba356a814fdbb001", + "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:10:47+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" } ], - "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "ltb-project/ldap": 20, + "ovh/php-ovh-sms": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/docs/config_sms.rst b/docs/config_sms.rst index ea8a8e628..f85441df9 100644 --- a/docs/config_sms.rst +++ b/docs/config_sms.rst @@ -75,7 +75,7 @@ trough mail configuration (see :ref:`config_mail`). You can adjust some settings here, depending on provider guidelines: To set SMS mail to address. -Within smssmailto {sms_attribute} will be replaced by sms number. +Within smsmailto {sms_attribute} will be replaced by sms number. .. code-block:: php @@ -94,28 +94,51 @@ If you choose API, you need to define which library will be called: .. code-block:: php - $sms_api_lib = "lib/smsapi.inc.php"; + $sms_api_lib = "lib/smsapi-.inc.php"; -In this library, you must define the ``send_sms_by_api`` function: +In this library, you must define a class with the ``send_sms_by_api`` function: .. code-block:: php - function send_sms_by_api($mobile, $message) { + param1 = $param1; + $this->param2 = $param2; + } + + function send_sms_by_api($mobile, $message) + { + + # PHP code + # ... + + # Or call to external script + # $command = escapeshellcmd(/path/to/script).' '.escapeshellarg($mobile).' '.escapeshellarg($message); + # exec($command); + + return 1; + } + +.. tip:: You have to define the properties ($param1, $param2,...) plus the + constructor with the appropriate parameters you want to use in + send_sms_by_api function. In send_sms_by_api function, you can + use these properties with: ``$this->param1``. + Then you can declare these parameters in the config.inc.local.php file. + For example: + ``$param1 = "value1";`` Read the provider guidelines to know how to access its API. .. tip:: An example is given in lib/smsapi-example.inc.php. Copy this - file to lib/smsapi.inc.php and start coding! + file to lib/smsapi-.inc.php and start coding! See also :ref:`sms_api`. diff --git a/docs/sms_api.rst b/docs/sms_api.rst index cac2f74ab..f5b474300 100644 --- a/docs/sms_api.rst +++ b/docs/sms_api.rst @@ -13,21 +13,45 @@ Provider website: https://www.linkmobility.com/ .. code-block:: php - function send_sms_by_api($mobile, $message) { - $post = [ - 'USER' => 'api_username', - 'PW' => 'api_password', - 'SND' => 'SenderName', - 'RCV' => $mobile, - 'TXT' => $message, - ]; - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, 'https://simple.pswin.com'); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post)); - $response = curl_exec($ch); - - return 1; + '; + * $signal_cli = ''; + */ + + class smsLink + { + + public $api_username; + public $api_password; + public $SenderName; + + public function __construct($api_username, $api_password, $SenderName) + { + $this->api_username = $api_username; + $this->api_password = $api_password; + $this->SenderName = $SenderName; + } + + function send_sms_by_api($mobile, $message) { + $post = [ + 'USER' => $this->api_username, + 'PW' => $this->api_password, + 'SND' => $this->SenderName, + 'RCV' => $mobile, + 'TXT' => $message, + ]; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, 'https://simple.pswin.com'); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post)); + $response = curl_exec($ch); + + return 1; + } } Twilio diff --git a/htdocs/sendsms.php b/htdocs/sendsms.php index fadc26d31..1bb58e77b 100644 --- a/htdocs/sendsms.php +++ b/htdocs/sendsms.php @@ -19,6 +19,8 @@ # #============================================================================== +include_once(dirname(__FILE__) . "/../lib/smsapi.inc.php"); + # This page is called to send random generated password to user by SMS #============================================================================== @@ -31,7 +33,6 @@ $phone = ""; $smsdisplay = ""; $ldap = ""; -$userdn = ""; $smstoken = ""; $token = ""; $sessiontoken = ""; @@ -93,7 +94,11 @@ $attempts = $_SESSION['attempts']; if (!$login or !$sessiontoken) { - list($result, $token) = obscure_info_sendsms("tokenattempts","tokennotvalid"); + list($result, $token) = obscure_info_sendsms("tokenattempts", + "tokennotvalid", + $token, + $obscure_notfound_sendsms, + $keyphrase); error_log("Unable to open session $smstokenid"); } elseif ($sessiontoken != $smstoken) { # To have only x tries and not x+1 tries @@ -124,7 +129,12 @@ } elseif (isset($_REQUEST["encrypted_sms_login"])) { $decrypted_sms_login = explode(':', decrypt($_REQUEST["encrypted_sms_login"], $keyphrase)); $login = $decrypted_sms_login[1]; - [$result, $phone] = get_mobile_and_displayname($login); + [$result, $phone] = get_mobile_and_displayname( + $ldapInstance, $ldap_base, $ldap_filter, + $ldap_fullname_attribute, $sms_attributes, + $sms_sanitize_number, $sms_truncate_number, + $obscure_notfound_sendsms, $token, + $keyphrase, $login); if (!$result) { $result = "sendsms"; } } elseif (isset($_REQUEST["login"]) and $_REQUEST["login"] and $sms_use_ldap) { $login = strval($_REQUEST["login"]); @@ -145,7 +155,12 @@ # Check sms #============================================================================== if ( $result === "" ) { - [$result, $sms, $displayname] = get_mobile_and_displayname($login); + [$result, $sms, $displayname] = get_mobile_and_displayname( + $ldapInstance, $ldap_base, $ldap_filter, + $ldap_fullname_attribute, $sms_attributes, + $sms_sanitize_number, $sms_truncate_number, + $obscure_notfound_sendsms, $token, + $keyphrase, $login); if ($sms){ if (!$sms_use_ldap) { $match = false; @@ -155,7 +170,11 @@ $result = "sendsms"; } if (!$match){ - list($result, $token) = obscure_info_sendsms("smssent_ifexists","smsnomatch"); + list($result, $token) = obscure_info_sendsms("smssent_ifexists", + "smsnomatch", + $token, + $obscure_notfound_sendsms, + $keyphrase); error_log("SMS number $phone does not match for user $login"); } }else{ @@ -220,10 +239,11 @@ $result = "smsnotsent"; error_log('No API library found, set $sms_api_lib in configuration.'); } else { - include_once("../".$sms_api_lib); $sms_message = str_replace('{smsresetmessage}', $messages['smsresetmessage'], $sms_message); $sms_message = str_replace('{smstoken}', $smstoken, $sms_message); - if (send_sms_by_api($sms, $sms_message)) { + $definedVariables = get_defined_vars(); // get all variables, including configuration + $smsInstance = createSMSInstance($sms_api_lib, $definedVariables); + if ($smsInstance->send_sms_by_api($sms, $sms_message)) { $token = encrypt(session_id(), $keyphrase); $result = "smssent"; if ( !empty($reset_request_log) ) { @@ -281,14 +301,12 @@ #============================================================================== # Functions #============================================================================== -function obscure_info_sendsms($obscure_message, $real_message){ - global $token; - global $obscure_notfound_sendsms; - +function obscure_info_sendsms($obscure_message, $real_message, $token, $obscure_notfound_sendsms, $keyphrase) +{ if ($obscure_notfound_sendsms){ $result = $obscure_message; if ($token === ""){ - $token = create_fake_token(); + $token = create_fake_token($keyphrase); } } else { $result = $real_message; @@ -296,8 +314,7 @@ function obscure_info_sendsms($obscure_message, $real_message){ return [$result, $token]; } -function create_fake_token(){ - global $keyphrase; +function create_fake_token($keyphrase){ $salt = bin2hex(random_bytes(26)); $token = encrypt($salt, $keyphrase); return $token; @@ -313,23 +330,16 @@ function truncate_number($phone_number){ return $phone_number; } -function get_mobile_and_displayname($login) { +function get_mobile_and_displayname($ldapInstance, $ldap_base, $ldap_filter, + $ldap_fullname_attribute, $sms_attributes, + $sms_sanitize_number, $sms_truncate_number, + $obscure_notfound_sendsms, $token, + $keyphrase, $login) { $sms = ""; $result = ""; $displayname = ""; - global $userdn; - global $ldap_url; - global $ldap_starttls; - global $ldap_binddn; - global $ldap_bindpw; - global $ldap_base; - global $ldap_filter; - global $ldap_fullname_attribute; - global $sms_attributes; - global $sms_sanitize_number; - global $sms_truncate_number; - global $obscure_notfound_sendsms; + $userdn = ""; $search_attributes = $sms_attributes; $search_attributes[] = $ldap_fullname_attribute; @@ -357,7 +367,11 @@ function get_mobile_and_displayname($login) { $displayname = ldap_get_values($ldap, $entry, $ldap_fullname_attribute); } if (!$userdn) { - list($result, $token) = obscure_info_sendsms("smssent_ifexists","badcredentials"); + list($result, $token) = obscure_info_sendsms("smssent_ifexists", + "badcredentials", + $token, + $obscure_notfound_sendsms, + $keyphrase); error_log("LDAP - User $login not found"); } else { # Get first sms number for configured ldap attributes in sms_attributes. @@ -372,7 +386,11 @@ function get_mobile_and_displayname($login) { $sms = truncate_number($sms); } }else{ - list($result, $token) = obscure_info_sendsms("smssent_ifexists","smsnonumber"); + list($result, $token) = obscure_info_sendsms("smssent_ifexists", + "smsnonumber", + $token, + $obscure_notfound_sendsms, + $keyphrase); error_log("No SMS number found for user $login"); } } diff --git a/lib/smsapi-example.inc.php b/lib/smsapi-example.inc.php index 48cf671d2..6e9c69bd1 100644 --- a/lib/smsapi-example.inc.php +++ b/lib/smsapi-example.inc.php @@ -1,4 +1,4 @@ -example_param1 = $example_param1; + $this->example_param2 = $example_param2; + } - return 1; + /* @function boolean send_sms_by_api(string $mobile, string $message) + * Send SMS trough an API + * @param mobile mobile number + * @param message text to send + * @return 1 if message sent, 0 if not + */ + function send_sms_by_api($mobile, $message) { + + # PHP code + # ... + + # Or call to external script + # $command = escapeshellcmd(/path/to/script).' '.escapeshellarg($mobile).' '.escapeshellarg($message); + # exec($command); + + return 1; + } } diff --git a/lib/smsapi-signal-cli.inc.php b/lib/smsapi-signal-cli.inc.php index e3b31a92d..88ca253db 100644 --- a/lib/smsapi-signal-cli.inc.php +++ b/lib/smsapi-signal-cli.inc.php @@ -1,4 +1,4 @@ -'; */ -/* @function boolean send_sms_by_api(string $mobile, string $message) - * Send SMS trough an API - * @param mobile mobile number - * @param message text to send - * @return 1 if message sent, 0 if not - */ -function send_sms_by_api($mobile, $message) { - global $signal_user, $signal_config, $signal_cli; - if (!$signal_user || !$signal_config || !$signal_cli) { - error_log('Trying to access signal without credentials. Set signal_user, signal_config and signal_cli in your config.inc.local.php'); - return 0; +class smsSignal +{ + + public $signal_user; + public $signal_config; + public $signal_cli; + + public function __construct($signal_user, $signal_config, $signal_cli) + { + $this->signal_user = $signal_user; + $this->signal_config = $signal_config; + $this->signal_cli = $signal_cli; } - $command = escapeshellcmd($signal_cli).' -u '.escapeshellarg($signal_user).' --config '.escapeshellarg($signal_config).' send -m '.escapeshellarg($message).' '.escapeshellarg($mobile); + /* @function boolean send_sms_by_api(string $mobile, string $message) + * Send SMS trough an API + * @param mobile mobile number + * @param message text to send + * @return 1 if message sent, 0 if not + */ + function send_sms_by_api($mobile, $message) { + if (!$this->signal_user || !$this->signal_config || !$this->signal_cli) { + error_log('Trying to access signal without credentials. Set signal_user, signal_config and signal_cli in your config.inc.local.php'); + return 0; + } - $v = ''; - $o = ''; - exec($command." 2>&1", $o, $v); + $command = escapeshellcmd($this->signal_cli).' -u '.escapeshellarg($this->signal_user).' --config '.escapeshellarg($this->signal_config).' send -m '.escapeshellarg($message).' '.escapeshellarg($mobile); - if ($v !== 0) { - error_log('Error sending message: '); - $o_size = count($o); - for ($x = 0; $x < $o_size; $x++) { - error_log(' ' . $o[$x]); - } + $v = ''; + $o = ''; + exec($command." 2>&1", $o, $v); - return 0; + if ($v !== 0) { + error_log('Error sending message: '); + $o_size = count($o); + for ($x = 0; $x < $o_size; $x++) { + error_log(' ' . $o[$x]); + } + return 0; + + } + return 1; } - return 1; -} +} diff --git a/lib/smsapi-twilio.inc.php b/lib/smsapi-twilio.inc.php index 7136188a3..a8dea4480 100644 --- a/lib/smsapi-twilio.inc.php +++ b/lib/smsapi-twilio.inc.php @@ -1,4 +1,4 @@ -twilio_sid = $twilio_sid; + $this->twilio_auth_token = $twilio_auth_token; + $this->twilio_outgoing_number = $twilio_outgoing_number; + $this->twilio_lookup_first = $twilio_lookup_first; } - if ($twilio_lookup_first) { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, 'https://lookups.twilio.com/v1/PhoneNumbers/' . rawurlencode($mobile)); - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); - curl_setopt($ch, CURLOPT_USERPWD, $twilio_sid . ":" . $twilio_auth_token); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - $response = curl_exec($ch); - $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); - curl_close($ch); - if ($http_code != "200") { - error_log("Error code $http_code from twilio: $response"); - return 0; - } - $json = json_decode($response, true); - if (@$json['code'] || @$json['message']) { - error_log("Error from twilio: $response"); - return 0; - } - $mobile = $json['phone_number']; - } + /* @function boolean send_sms_by_api(string $mobile, string $message) + * Send SMS trough an API + * @param mobile mobile number + * @param message text to send + * @return 1 if message sent, 0 if not + */ + function send_sms_by_api($mobile, $message) { + if (!$this->twilio_sid || !$this->twilio_auth_token) { + error_log('Trying to access twilio without credentials. Set twilio_sid and twilio_auth_token in your config.inc.local.php with values from https://www.twilio.com/console'); + return 0; + } - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, 'https://api.twilio.com/2010-04-01/Accounts/' . rawurlencode($twilio_sid) . '/Messages.json'); - curl_setopt($ch, CURLOPT_POST, 1); - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); - curl_setopt($ch, CURLOPT_USERPWD, $twilio_sid . ":" . $twilio_auth_token); - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array( - 'Body' => $message, - 'From' => $twilio_outgoing_number, - 'To' => $mobile - ))); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - $response = curl_exec($ch); - $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); - curl_close($ch); - if ($http_code != "200" && $http_code != "201") { - error_log("Error code $http_code from twilio: $response"); - return 0; - } - $json = json_decode($response, true); - if (@$json['code'] || @$json['message']) { - error_log("Error from twilio: $response"); - return 0; - } + if (!$this->twilio_outgoing_number) { + error_log('No outgoing twilio number, set twilio_outgoing_number in config.inc.local.php with values from https://www.twilio.com/console/phone-numbers/search'); + return 0; + } - return 1; -} + if ($this->twilio_lookup_first) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, 'https://lookups.twilio.com/v1/PhoneNumbers/' . rawurlencode($mobile)); + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($ch, CURLOPT_USERPWD, $this->twilio_sid . ":" . $this->twilio_auth_token); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($ch); + $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); + curl_close($ch); + if ($http_code != "200") { + error_log("Error code $http_code from twilio: $response"); + return 0; + } + $json = json_decode($response, true); + if (@$json['code'] || @$json['message']) { + error_log("Error from twilio: $response"); + return 0; + } + + $mobile = $json['phone_number']; + } + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, 'https://api.twilio.com/2010-04-01/Accounts/' . rawurlencode($this->twilio_sid) . '/Messages.json'); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($ch, CURLOPT_USERPWD, $this->twilio_sid . ":" . $this->twilio_auth_token); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array( + 'Body' => $message, + 'From' => $this->twilio_outgoing_number, + 'To' => $mobile + ))); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($ch); + $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); + curl_close($ch); + if ($http_code != "200" && $http_code != "201") { + error_log("Error code $http_code from twilio: $response"); + return 0; + } + $json = json_decode($response, true); + if (@$json['code'] || @$json['message']) { + error_log("Error from twilio: $response"); + return 0; + } + return 1; + } +} diff --git a/lib/smsapi.inc.php b/lib/smsapi.inc.php new file mode 100644 index 000000000..865ac8d02 --- /dev/null +++ b/lib/smsapi.inc.php @@ -0,0 +1,43 @@ +newInstanceArgs($params); +} + +function createSMSInstance($sms_api_lib, $config) +{ + # Get all loaded classes + $classes = get_declared_classes(); + + # load the sms module + include_once(dirname(__FILE__) . "/../" . $sms_api_lib); + + # Get class name defined in $sms_api_lib file + $diff = array_diff(get_declared_classes(), $classes); + $class = reset($diff); + + if(!isset($class) || $class == "") + { + error_log("Error: no class found in $sms_api_lib"); + exit(1); + } + + # Inspect class properties of sms modules + $class_vars = get_class_vars($class); + + # Gather properties to pass to the class: all config params to pass to sms module + $params = []; + foreach (array_keys($class_vars) as $param) + { + if(!isset($config[$param])) + { + error_log("Error: Missing param $param in $sms_api_lib"); + exit(1); + } + array_push($params, $config[$param]); + } + return create_instance($class, $params); +} + +?> diff --git a/lib/smsovh/composer.json b/lib/smsovh/composer.json index 4854a417e..7b35f186e 100644 --- a/lib/smsovh/composer.json +++ b/lib/smsovh/composer.json @@ -1,5 +1,5 @@ { "require": { - "ovh/php-ovh-sms": "dev-master" + "ovh/php-ovh-sms": "dev-master" } } diff --git a/lib/smsovh/smsapi-ovh.inc.php b/lib/smsovh/smsapi-ovh.inc.php index 155f2669e..3e5a1e388 100644 --- a/lib/smsovh/smsapi-ovh.inc.php +++ b/lib/smsovh/smsapi-ovh.inc.php @@ -1,4 +1,4 @@ -getAccounts(); - // Set the account you will use - // print_r($accounts); - $Sms->setAccount($accounts[0]); - - // Get declared senders - $sender=NULL; - if (defined($ovh_smssender)) { - $sender = $ovh_smssender; - } - if ($sender === NULL) { - $senders = $Sms->getSenders(); - $sender = $senders[0]; +class smsOVH +{ + + public $ovh_appkey; + public $ovh_appsecret; + public $ovh_consumerkey; + public $ovh_smssender; + + public function __construct($ovh_appkey, $ovh_appsecret, $ovh_consumerkey, $ovh_smssender) + { + $this->ovh_appkey = $ovh_appkey; + $this->ovh_appsecret = $ovh_appsecret; + $this->ovh_consumerkey = $ovh_consumerkey; + $this->ovh_smssender = $ovh_smssender; } - - // OVH needs international '+' format - $mobile = preg_replace('/[^0-9\+]/','',$mobile); - if ( !preg_match('/^\+/',$mobile) ) { - if ( preg_match('/^00/',$mobile) ) { - $mobile=preg_replace('^00','+'); - } - if ( preg_match('/^0/',$mobile) ) { - $mobile=preg_replace('/^0/','+33',$mobile); + + + /* @function boolean send_sms_by_api(string $mobile, string $message, array $config) + * Send SMS trough an API + * @param mobile mobile number + * @param message text to send + * @return 1 if message sent, 0 if not + */ + public function send_sms_by_api($mobile, $message) { + + // https://api.ovh.com/createToken/index.cgi?GET=/sms&GET=/sms/*&PUT=/sms/*&DELETE=/sms/*&POST=/sms/* + + $endpoint = 'ovh-eu'; + $applicationKey=$this->ovh_appkey; + $applicationSecret=$this->ovh_appsecret; + $consumer_key=$this->ovh_consumerkey; + error_log("OVH: $applicationKey $applicationSecret $consumer_key $this->ovh_smssender"); + // print_r($config); + $Sms = new \Ovh\Sms\SmsApi( $applicationKey, + $applicationSecret, + $endpoint, + $consumer_key ); + + $accounts = $Sms->getAccounts(); + // Set the account you will use + // print_r($accounts); + $Sms->setAccount($accounts[0]); + + // Get declared senders + $sender=NULL; + if (isset($this->ovh_smssender)) { + $sender = $this->ovh_smssender; + } + if ($sender === NULL) { + $senders = $Sms->getSenders(); + $sender = $senders[0]; } - } - // Create a new message - $Message = $Sms->createMessage(); - $Message->setSender($sender); - $Message->addReceiver($mobile); - $Message->setIsMarketing(false); - return $Message->send($message); - # PHP code - # ... + // OVH needs international '+' format + $mobile = preg_replace('/[^0-9\+]/','',$mobile); + if ( !preg_match('/^\+/',$mobile) ) { + if ( preg_match('/^00/',$mobile) ) { + $mobile=preg_replace('^00','+'); + } + if ( preg_match('/^0/',$mobile) ) { + $mobile=preg_replace('/^0/','+33',$mobile); + } + } + // Create a new message + $Message = $Sms->createMessage(); + $Message->setSender($sender); + $Message->addReceiver($mobile); + $Message->setIsMarketing(false); + return $Message->send($message); + + # PHP code + # ... - # Or call to external script - # $command = escapeshellcmd(/path/to/script).' '.escapeshellarg($mobile).' '.escapeshellarg($message); - # exec($command); + # Or call to external script + # $command = escapeshellcmd(/path/to/script).' '.escapeshellarg($mobile).' '.escapeshellarg($message); + # exec($command); + + return 1; + } - return 1; } diff --git a/lib/smsovh/vendor/autoload.php b/lib/smsovh/vendor/autoload.php new file mode 100644 index 000000000..42db4da28 --- /dev/null +++ b/lib/smsovh/vendor/autoload.php @@ -0,0 +1,25 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/lib/smsovh/vendor/composer/InstalledVersions.php b/lib/smsovh/vendor/composer/InstalledVersions.php new file mode 100644 index 000000000..51e734a77 --- /dev/null +++ b/lib/smsovh/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/lib/smsovh/vendor/composer/LICENSE b/lib/smsovh/vendor/composer/LICENSE new file mode 100644 index 000000000..f27399a04 --- /dev/null +++ b/lib/smsovh/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/lib/smsovh/vendor/composer/autoload_classmap.php b/lib/smsovh/vendor/composer/autoload_classmap.php new file mode 100644 index 000000000..0fb0a2c19 --- /dev/null +++ b/lib/smsovh/vendor/composer/autoload_classmap.php @@ -0,0 +1,10 @@ + $vendorDir . '/composer/InstalledVersions.php', +); diff --git a/lib/smsovh/vendor/composer/autoload_namespaces.php b/lib/smsovh/vendor/composer/autoload_namespaces.php new file mode 100644 index 000000000..15a2ff3ad --- /dev/null +++ b/lib/smsovh/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ +register(true); + + return $loader; + } +} diff --git a/lib/smsovh/vendor/composer/autoload_static.php b/lib/smsovh/vendor/composer/autoload_static.php new file mode 100644 index 000000000..eabbee317 --- /dev/null +++ b/lib/smsovh/vendor/composer/autoload_static.php @@ -0,0 +1,20 @@ + __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->classMap = ComposerStaticInit5aa2467a5b80bf8e7848a6bfd2f457e8::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/lib/smsovh/vendor/composer/installed.json b/lib/smsovh/vendor/composer/installed.json new file mode 100644 index 000000000..87fda747e --- /dev/null +++ b/lib/smsovh/vendor/composer/installed.json @@ -0,0 +1,5 @@ +{ + "packages": [], + "dev": true, + "dev-package-names": [] +} diff --git a/lib/smsovh/vendor/composer/installed.php b/lib/smsovh/vendor/composer/installed.php new file mode 100644 index 000000000..019c6a291 --- /dev/null +++ b/lib/smsovh/vendor/composer/installed.php @@ -0,0 +1,23 @@ + array( + 'name' => '__root__', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '5094c87a8cfe37db757e0e29a94fee45d83ea815', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => true, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '5094c87a8cfe37db757e0e29a94fee45d83ea815', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/packaging/README b/packaging/README index aa573b8ce..c2c9c2635 100644 --- a/packaging/README +++ b/packaging/README @@ -10,11 +10,14 @@ Update version in following files: * packaging/rpm/SPECS/self-service-password.spec * packaging/debian/changelog -# 1 - Update dependencies +# 1 - Update dependencies and run tests #============================================================================== From the self-service-password root directory, run: -$ composer update +$ composer update --no-dev + +Run tests: +$ XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-text --configuration tests/phpunit.xml # 2 - Archive tar.gz diff --git a/tests/phpunit.xml b/tests/phpunit.xml index f18476f54..45674cc30 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -6,4 +6,10 @@ + + + ../lib + ../htdocs + + diff --git a/tests/smsOVHTest.php b/tests/smsOVHTest.php new file mode 100644 index 000000000..3989468de --- /dev/null +++ b/tests/smsOVHTest.php @@ -0,0 +1,59 @@ +shouldreceive('setSender') + ->with($ovh_smssender); + + $mockSmsMessage->shouldreceive('addReceiver') + ->with("+33123456789"); + + $mockSmsMessage->shouldreceive('setIsMarketing') + ->with(false); + + $mockSmsMessage->shouldreceive('send') + ->andReturn(0); + + $mockSmsApi = Mockery::mock('overload:\Ovh\Sms\SmsApi'); + + $mockSmsApi->shouldreceive('getAccounts') + ->andReturn(["account1", "account2", "account3"]); + + $mockSmsApi->shouldreceive('setAccount') + ->with("account1"); + + $mockSmsApi->shouldreceive('createMessage') + ->andReturn(new \Ovh\Sms\Message($mockSmsApi)); + + + $smsInstance = new smsapi\smsOVH($ovh_appkey, + $ovh_appsecret, + $ovh_consumerkey, + $ovh_smssender); + + $this->assertEquals("$ovh_appkey", $smsInstance->ovh_appkey, "Bad appkey"); + $this->assertEquals("$ovh_appsecret", $smsInstance->ovh_appsecret, "Bad appsecret"); + $this->assertEquals("$ovh_consumerkey", $smsInstance->ovh_consumerkey, "Bad consumerkey"); + $this->assertEquals("$ovh_smssender", $smsInstance->ovh_smssender, "Bad smssender"); + + $res = $smsInstance->send_sms_by_api($mobile, $message); + + $this->assertEquals(0, $res, "Wrong return code by ovh send_sms_by_api function"); + } +} diff --git a/tests/smsSignalTest.php b/tests/smsSignalTest.php new file mode 100644 index 000000000..da865ae35 --- /dev/null +++ b/tests/smsSignalTest.php @@ -0,0 +1,42 @@ +getFunctionMock("smsapi", "exec"); + $mock->expects($this->once())->willReturnCallback( + function ($command, &$output, &$return_var) { + $this->assertEquals("cli -u 'user' --config 'config' send -m 'my message' '+33123456789' 2>&1", $command); + $output = "success"; + $return_var = 0; + } + ); + + $smsInstance = new smsapi\smsSignal($signal_user, + $signal_config, + $signal_cli); + + $this->assertEquals("$signal_user", $smsInstance->signal_user, "Bad signal user"); + $this->assertEquals("$signal_config", $smsInstance->signal_config, "Bad signal config"); + $this->assertEquals("$signal_cli", $smsInstance->signal_cli, "Bad signal cli"); + + $res = $smsInstance->send_sms_by_api($mobile, $message); + + $this->assertEquals(1, $res, "Wrong return code by send_sms_by_api function"); + } + +} diff --git a/tests/smsTwilioTest.php b/tests/smsTwilioTest.php new file mode 100644 index 000000000..81b8231f1 --- /dev/null +++ b/tests/smsTwilioTest.php @@ -0,0 +1,173 @@ +getFunctionMock("smsapi", "curl_init"); + $mock_init->expects($this->any())->willReturnCallback( + function ($ch) { + $ch = array(); + return $ch; + } + ); + + $mock_setopt = $this->getFunctionMock("smsapi", "curl_setopt"); + $mock_setopt->expects($this->any())->willReturnCallback( + function ($ch, $option, $value) { + + $twilio_sid = "sid"; + $twilio_auth_token = "authtoken"; + $twilio_outgoing_number = "+18881234567"; + $twilio_lookup_first = false; + $mobile = "+33123456789"; + $message = "my message"; + + switch ($option) { + case CURLOPT_URL: + $this->assertEquals("https://api.twilio.com/2010-04-01/Accounts/" . rawurlencode($twilio_sid) . '/Messages.json' , $value, "Bad Twilio CURLOPT_URL"); + break; + case CURLOPT_USERPWD: + $this->assertEquals($twilio_sid . ":" . $twilio_auth_token , $value, "Bad Twilio CURLOPT_USERPWD"); + break; + case CURLOPT_POSTFIELDS: + $this->assertEquals('Body=my+message&From=%2B18881234567&To=%2B33123456789' , $value, "Bad Twilio CURLOPT_POSTFIELDS"); + break; + } + $ch[$option] = $value; + } + ); + + + $mock_exec = $this->getFunctionMock("smsapi", "curl_exec"); + $mock_exec->expects($this->once())->willReturnCallback( + function ($ch) { + return '{"code": "0", "message": ""}'; # code corresponding to a success + } + ); + + $mock_getinfo = $this->getFunctionMock("smsapi", "curl_getinfo"); + $mock_getinfo->expects($this->once())->willReturnCallback( + function ($ch, $option) { + $this->assertEquals(CURLINFO_HTTP_CODE, $option, "Bad option in Twilio curl_getinfo"); + return "200"; + } + ); + + $mock_close = $this->getFunctionMock("smsapi", "curl_close"); + $mock_close->expects($this->once())->willReturnCallback( + function ($ch) { + } + ); + + $smsInstance = new smsapi\smsTwilio($twilio_sid, + $twilio_auth_token, + $twilio_outgoing_number, + $twilio_lookup_first); + + $this->assertEquals("$twilio_sid", $smsInstance->twilio_sid, "Bad sid"); + $this->assertEquals("$twilio_auth_token", $smsInstance->twilio_auth_token, "Bad auth_token"); + $this->assertEquals("$twilio_outgoing_number", $smsInstance->twilio_outgoing_number, "Bad outgoing_number"); + $this->assertEquals($twilio_lookup_first, $smsInstance->twilio_lookup_first, "Bad lookup_first"); + + $res = $smsInstance->send_sms_by_api($mobile, $message); + + $this->assertEquals(1, $res, "Wrong return code by twilio send_sms_by_api function"); + } + + + + public function test_send_sms_by_api_twilio_lookup_first(): void + { + $twilio_sid = "sid"; + $twilio_auth_token = "authtoken"; + $twilio_outgoing_number = "+18881234567"; + $twilio_lookup_first = true; + + $mobile = "+33123456789"; + $message = "my message"; + + + $mock_init = $this->getFunctionMock("smsapi", "curl_init"); + $mock_init->expects($this->any())->willReturnCallback( + function ($ch) { + $ch = array(); + return $ch; + } + ); + + $mock_setopt = $this->getFunctionMock("smsapi", "curl_setopt"); + $mock_setopt->expects($this->any())->willReturnCallback( + function ($ch, $option, $value) { + + $twilio_sid = "sid"; + $twilio_auth_token = "authtoken"; + $twilio_outgoing_number = "+18881234567"; + $twilio_lookup_first = true; + $mobile = "+33123456789"; + $message = "my message"; + + switch ($option) { + case CURLOPT_URL: + $this->assertEquals('https://lookups.twilio.com/v1/PhoneNumbers/' . rawurlencode($mobile) , $value, "Bad Twilio lookup_first CURLOPT_URL"); + break; + case CURLOPT_USERPWD: + $this->assertEquals($twilio_sid . ":" . $twilio_auth_token , $value, "Bad Twilio CURLOPT_USERPWD"); + break; + } + $ch[$option] = $value; + } + ); + + + $mock_exec = $this->getFunctionMock("smsapi", "curl_exec"); + $mock_exec->expects($this->once())->willReturnCallback( + function ($ch) { + return '{"code": "1"}'; # code corresponding to an error + } + ); + + $mock_getinfo = $this->getFunctionMock("smsapi", "curl_getinfo"); + $mock_getinfo->expects($this->once())->willReturnCallback( + function ($ch, $option) { + $this->assertEquals(CURLINFO_HTTP_CODE, $option, "Bad option in Twilio curl_getinfo"); + return "200"; + } + ); + + $mock_close = $this->getFunctionMock("smsapi", "curl_close"); + $mock_close->expects($this->once())->willReturnCallback( + function ($ch) { + } + ); + + $smsInstance = new smsapi\smsTwilio($twilio_sid, + $twilio_auth_token, + $twilio_outgoing_number, + $twilio_lookup_first); + + $this->assertEquals("$twilio_sid", $smsInstance->twilio_sid, "Bad sid"); + $this->assertEquals("$twilio_auth_token", $smsInstance->twilio_auth_token, "Bad auth_token"); + $this->assertEquals("$twilio_outgoing_number", $smsInstance->twilio_outgoing_number, "Bad outgoing_number"); + $this->assertEquals($twilio_lookup_first, $smsInstance->twilio_lookup_first, "Bad lookup_first"); + + $res = $smsInstance->send_sms_by_api($mobile, $message); + + $this->assertEquals(0, $res, "Wrong return code by twilio send_sms_by_api function during first lookup"); + } +}